diff --git a/addons/account_asset/account_asset.py b/addons/account_asset/account_asset.py index 69d5313be78..f8155ae4e0c 100644 --- a/addons/account_asset/account_asset.py +++ b/addons/account_asset/account_asset.py @@ -363,7 +363,7 @@ class AccountAssetAsset(models.Model): if default is None: default = {} default['name'] = self.name + _(' (copy)') - return super(AccountAssetAsset, self).copy_data(default)[0] + return super(AccountAssetAsset, self).copy_data(default) @api.multi def _compute_entries(self, date, group_entries=False): diff --git a/addons/base_import/models.py b/addons/base_import/models.py index 4c4a9fd6c15..36cd41fa7f0 100644 --- a/addons/base_import/models.py +++ b/addons/base_import/models.py @@ -501,7 +501,7 @@ class ir_import(orm.TransientModel): def _convert_import_data(self, record, fields, options, context=None): """ Extracts the input browse_record and fields list (with ``False``-y placeholders for fields to *not* import) into a - format Model.import_data can use: a fields list without holes + format Model.load can use: a fields list without holes and the precisely matching data matrix :param browse_record record: diff --git a/addons/base_import/tests/test_cases.py b/addons/base_import/tests/test_cases.py index 19815e396d5..d9b6e16b2f4 100644 --- a/addons/base_import/tests/test_cases.py +++ b/addons/base_import/tests/test_cases.py @@ -358,7 +358,7 @@ class test_preview(TransactionCase): class test_convert_import_data(TransactionCase): """ Tests conversion of base_import.import input into data which - can be fed to Model.import_data + can be fed to Model.load """ def test_all(self): Import = self.registry('base_import.import') diff --git a/addons/mail/models/res_users.py b/addons/mail/models/res_users.py index ee3ee5f6b1c..1b03d992dc4 100644 --- a/addons/mail/models/res_users.py +++ b/addons/mail/models/res_users.py @@ -65,11 +65,12 @@ class Users(models.Model): self.env['mail.channel'].search([('group_ids', 'in', user_group_ids)])._subscribe_users() return write_res - def copy_data(self, *args, **kwargs): - data = super(Users, self).copy_data(*args, **kwargs) + @api.multi + def copy_data(self, default=None): + data = super(Users, self).copy_data(default)[0] if data and data.get('alias_name'): data['alias_name'] = data['login'] - return data + return [data] def _create_welcome_message(self): self.ensure_one() diff --git a/openerp/addons/base/res/res_config.py b/openerp/addons/base/res/res_config.py index c09d6f2d279..8d54f96cc22 100644 --- a/openerp/addons/base/res/res_config.py +++ b/openerp/addons/base/res/res_config.py @@ -316,12 +316,12 @@ class ResConfigInstaller(models.TransientModel, ResConfigModuleInstallationMixin return dict(defaults, **dict.fromkeys(self.already_installed(), True)) @api.model - def fields_get(self, fields=None, write_access=True, attributes=None): + def fields_get(self, fields=None, attributes=None): """ If an addon is already installed, set it to readonly as res.config.installer doesn't handle uninstallations of already installed addons """ - fields = super(ResConfigInstaller, self).fields_get(fields, write_access=write_access, attributes=attributes) + fields = super(ResConfigInstaller, self).fields_get(fields, attributes=attributes) for name in self.already_installed(): if name not in fields: diff --git a/openerp/addons/base/res/res_users.py b/openerp/addons/base/res/res_users.py index 890432786cf..216bc64ade3 100644 --- a/openerp/addons/base/res/res_users.py +++ b/openerp/addons/base/res/res_users.py @@ -876,8 +876,8 @@ class UsersView(models.Model): values[f] = selected and selected[-1] or False @api.model - def fields_get(self, allfields=None, write_access=True, attributes=None): - res = super(UsersView, self).fields_get(allfields=allfields, write_access=write_access, attributes=attributes) + def fields_get(self, allfields=None, attributes=None): + res = super(UsersView, self).fields_get(allfields, attributes=attributes) # add reified groups fields if not self.env.user._is_admin(): return res diff --git a/openerp/addons/base/tests/test_base.py b/openerp/addons/base/tests/test_base.py index 45910803b95..bf4195d770d 100644 --- a/openerp/addons/base/tests/test_base.py +++ b/openerp/addons/base/tests/test_base.py @@ -400,6 +400,10 @@ class TestPartnerRecursion(TransactionCase): self.p2 = res_partner.create({'name': 'Elmtree Child 1', 'parent_id': self.p1.id}) self.p3 = res_partner.create({'name': 'Elmtree Grand-Child 1.1', 'parent_id': self.p2.id}) + def test_100_res_partner_recursion(self): + self.assertTrue(self.p3._check_recursion()) + self.assertTrue((self.p1 + self.p2 + self.p3)._check_recursion()) + # split 101, 102, 103 tests to force SQL rollback between them def test_101_res_partner_recursion(self): @@ -511,3 +515,15 @@ class TestGroups(TransactionCase): groups = all_groups.search([('full_name', 'in', ['Administration / Access Rights','Contact Creation'])]) self.assertTrue(groups, "did not match search for 'Administration / Access Rights' and 'Contact Creation'") + + def test_res_group_recursion(self): + # four groups with no cycle, check them all together + a = self.env['res.groups'].create({'name': 'A'}) + b = self.env['res.groups'].create({'name': 'B'}) + c = self.env['res.groups'].create({'name': 'G', 'implied_ids': [(6, 0, (a + b).ids)]}) + d = self.env['res.groups'].create({'name': 'D', 'implied_ids': [(6, 0, c.ids)]}) + self.assertTrue((a + b + c + d)._check_m2m_recursion('implied_ids')) + + # create a cycle and check + a.implied_ids = d + self.assertFalse(a._check_m2m_recursion('implied_ids')) diff --git a/openerp/addons/test_impex/tests/__init__.py b/openerp/addons/test_impex/tests/__init__.py index 031da993781..93dd6ccb8bb 100644 --- a/openerp/addons/test_impex/tests/__init__.py +++ b/openerp/addons/test_impex/tests/__init__.py @@ -1,4 +1,4 @@ # -*- coding: utf-8 -*- -from . import test_export, test_import, test_load +from . import test_export, test_load diff --git a/openerp/addons/test_impex/tests/test_import.py b/openerp/addons/test_impex/tests/test_import.py deleted file mode 100644 index 8693b9b389e..00000000000 --- a/openerp/addons/test_impex/tests/test_import.py +++ /dev/null @@ -1,877 +0,0 @@ -# -*- coding: utf-8 -*- -import openerp.modules.registry -import openerp - -from openerp.tests import common -from openerp.tools.misc import mute_logger - -def ok(n): - """ Successful import of ``n`` records - - :param int n: number of records which should have been imported - """ - return n, 0, 0, 0 - -def error(row, message, record=None, **kwargs): - """ Failed import of the record ``record`` at line ``row``, with the error - message ``message`` - - :param str message: - :param dict record: - """ - return ( - -1, dict(record or {}, **kwargs), - "Line %d : %s" % (row, message), - '') - -def values(seq, field='value'): - return [item[field] for item in seq] - -class ImporterCase(common.TransactionCase): - model_name = False - - def __init__(self, *args, **kwargs): - super(ImporterCase, self).__init__(*args, **kwargs) - self.model = None - - def setUp(self): - super(ImporterCase, self).setUp() - self.model = self.registry(self.model_name) - - def import_(self, fields, rows, context=None): - return self.model.import_data( - self.cr, openerp.SUPERUSER_ID, fields, rows, context=context) - def read(self, fields=('value',), domain=(), context=None): - return self.model.read( - self.cr, openerp.SUPERUSER_ID, - self.model.search(self.cr, openerp.SUPERUSER_ID, domain, context=context), - fields=fields, context=context) - def browse(self, domain=(), context=None): - return self.model.browse( - self.cr, openerp.SUPERUSER_ID, - self.model.search(self.cr, openerp.SUPERUSER_ID, domain, context=context), - context=context) - - def xid(self, record): - ModelData = self.registry('ir.model.data') - - ids = ModelData.search( - self.cr, openerp.SUPERUSER_ID, - [('model', '=', record._name), ('res_id', '=', record.id)]) - if ids: - d = ModelData.read( - self.cr, openerp.SUPERUSER_ID, ids, ['name', 'module'])[0] - if d['module']: - return '%s.%s' % (d['module'], d['name']) - return d['name'] - - name = record.name_get()[0][1] - # fix dotted name_get results, otherwise xid lookups blow up - name = name.replace('.', '-') - ModelData.create(self.cr, openerp.SUPERUSER_ID, { - 'name': name, - 'model': record._name, - 'res_id': record.id, - 'module': '__test__' - }) - return '__test__.' + name - -class test_ids_stuff(ImporterCase): - model_name = 'export.integer' - - def test_create_with_id(self): - self.assertEqual( - self.import_(['.id', 'value'], [['42', '36']]), - error(1, u"Unknown database identifier '42'")) - def test_create_with_xid(self): - self.assertEqual( - self.import_(['id', 'value'], [['somexmlid', '42']]), - ok(1)) - self.assertEqual( - 'somexmlid', - self.xid(self.browse()[0])) - - def test_update_with_id(self): - id = self.model.create(self.cr, openerp.SUPERUSER_ID, {'value': 36}) - self.assertEqual( - 36, - self.model.browse(self.cr, openerp.SUPERUSER_ID, id).value) - - self.assertEqual( - self.import_(['.id', 'value'], [[str(id), '42']]), - ok(1)) - self.assertEqual( - [42], # updated value to imported - values(self.read())) - - def test_update_with_xid(self): - self.import_(['id', 'value'], [['somexmlid', '36']]) - self.assertEqual([36], values(self.read())) - - self.import_(['id', 'value'], [['somexmlid', '1234567']]) - self.assertEqual([1234567], values(self.read())) - - def test_wrong_format(self): - self.assertEqual( - self.import_(['value'], [['50%']]), - error(1, u"'50%' does not seem to be an integer for field 'unknown'")) - - -class test_boolean_field(ImporterCase): - model_name = 'export.boolean' - - def test_empty(self): - self.assertEqual( - self.import_(['value'], []), - ok(0)) - - def test_exported(self): - self.assertEqual( - self.import_(['value'], [ - ['False'], - ['True'], - ]), - ok(2)) - records = self.read() - self.assertEqual([ - False, - True, - ], values(records)) - - def test_falses(self): - self.assertEqual( - self.import_(['value'], [ - [u'0'], - [u'no'], - [u'false'], - [u'FALSE'], - [u''], - ]), - ok(5)) - self.assertEqual([ - False, - False, - False, - False, - False, - ], - values(self.read())) - - def test_trues(self): - self.assertEqual( - self.import_(['value'], [ - ['off'], - ['None'], - ['nil'], - ['()'], - ['f'], - ['#f'], - # Problem: OpenOffice (and probably excel) output localized booleans - ['VRAI'], - [u'OFF'], - [u'是的'], - ['!&%#${}'], - ['%(field)s'], - ]), - ok(11)) - self.assertEqual( - [True] * 11, - values(self.read())) - -class test_integer_field(ImporterCase): - model_name = 'export.integer' - - def test_none(self): - self.assertEqual( - self.import_(['value'], []), - ok(0)) - - def test_empty(self): - self.assertEqual( - self.import_(['value'], [['']]), - ok(1)) - self.assertEqual( - [False], - values(self.read())) - - def test_zero(self): - self.assertEqual( - self.import_(['value'], [['0']]), - ok(1)) - self.assertEqual( - self.import_(['value'], [['-0']]), - ok(1)) - self.assertEqual([False, False], values(self.read())) - - def test_positives(self): - self.assertEqual( - self.import_(['value'], [ - ['1'], - ['42'], - [str(2**31-1)], - ['12345678'] - ]), - ok(4)) - self.assertEqual([ - 1, 42, 2**31-1, 12345678 - ], values(self.read())) - - def test_negatives(self): - self.assertEqual( - self.import_(['value'], [ - ['-1'], - ['-42'], - [str(-(2**31 - 1))], - [str(-(2**31))], - ['-12345678'] - ]), - ok(5)) - self.assertEqual([ - -1, -42, -(2**31 - 1), -(2**31), -12345678 - ], values(self.read())) - - @mute_logger('openerp.sql_db') - def test_out_of_range(self): - self.assertEqual( - self.import_(['value'], [[str(2**31)]]), - error(1, "integer out of range\n")) - # auto-rollbacks if error is in process_liness, but not during - # ir.model.data write. Can differentiate because former ends lines - # error lines with "!" - self.cr.rollback() - self.assertEqual( - self.import_(['value'], [[str(-2**32)]]), - error(1, "integer out of range\n")) - - - def test_nonsense(self): - self.assertEqual( - self.import_(['value'], [['zorglub']]), - error(1, u"'zorglub' does not seem to be an integer for field 'unknown'")) - -class test_float_field(ImporterCase): - model_name = 'export.float' - def test_none(self): - self.assertEqual( - self.import_(['value'], []), - ok(0)) - - def test_empty(self): - self.assertEqual( - self.import_(['value'], [['']]), - ok(1)) - self.assertEqual( - [False], - values(self.read())) - - def test_zero(self): - self.assertEqual( - self.import_(['value'], [['0']]), - ok(1)) - self.assertEqual( - self.import_(['value'], [['-0']]), - ok(1)) - self.assertEqual([False, False], values(self.read())) - - def test_positives(self): - self.assertEqual( - self.import_(['value'], [ - ['1'], - ['42'], - [str(2**31-1)], - ['12345678'], - [str(2**33)], - ['0.000001'], - ]), - ok(6)) - self.assertEqual([ - 1, 42, 2**31-1, 12345678, 2.0**33, .000001 - ], values(self.read())) - - def test_negatives(self): - self.assertEqual( - self.import_(['value'], [ - ['-1'], - ['-42'], - [str(-2**31 + 1)], - [str(-2**31)], - ['-12345678'], - [str(-2**33)], - ['-0.000001'], - ]), - ok(7)) - self.assertEqual([ - -1, -42, -(2**31 - 1), -(2**31), -12345678, -2.0**33, -.000001 - ], values(self.read())) - - def test_nonsense(self): - self.assertEqual( - self.import_(['value'], [['foobar']]), - error(1, u"'foobar' does not seem to be a number for field 'unknown'")) - -class test_string_field(ImporterCase): - model_name = 'export.string.bounded' - - def test_empty(self): - self.assertEqual( - self.import_(['value'], [['']]), - ok(1)) - self.assertEqual([False], values(self.read())) - - def test_imported(self): - self.assertEqual( - self.import_(['value'], [ - [u'foobar'], - [u'foobarbaz'], - [u'Með suð í eyrum við spilum endalaust'], - [u"People 'get' types. They use them all the time. Telling " - u"someone he can't pound a nail with a banana doesn't much " - u"surprise him."] - ]), - ok(4)) - self.assertEqual([ - u"foobar", - u"foobarbaz", - u"Með suð í eyrum ", - u"People 'get' typ", - ], values(self.read())) - -class test_unbound_string_field(ImporterCase): - model_name = 'export.string' - - def test_imported(self): - self.assertEqual( - self.import_(['value'], [ - [u'í dag viðrar vel til loftárása'], - # ackbar.jpg - [u"If they ask you about fun, you tell them – fun is a filthy" - u" parasite"] - ]), - ok(2)) - self.assertEqual([ - u"í dag viðrar vel til loftárása", - u"If they ask you about fun, you tell them – fun is a filthy parasite" - ], values(self.read())) - -class test_text(ImporterCase): - model_name = 'export.text' - - def test_empty(self): - self.assertEqual( - self.import_(['value'], [['']]), - ok(1)) - self.assertEqual([False], values(self.read())) - - def test_imported(self): - s = (u"Breiðskífa er notað um útgefna hljómplötu sem inniheldur " - u"stúdíóupptökur frá einum flytjanda. Breiðskífur eru oftast " - u"milli 25-80 mínútur og er lengd þeirra oft miðuð við 33⅓ " - u"snúninga 12 tommu vínylplötur (sem geta verið allt að 30 mín " - u"hvor hlið).\n\nBreiðskífur eru stundum tvöfaldar og eru þær þá" - u" gefnar út á tveimur geisladiskum eða tveimur vínylplötum.") - self.assertEqual( - self.import_(['value'], [[s]]), - ok(1)) - self.assertEqual([s], values(self.read())) - -class test_selection(ImporterCase): - model_name = 'export.selection' - translations_fr = [ - ("Qux", "toto"), - ("Bar", "titi"), - ("Foo", "tete"), - ] - - def test_imported(self): - self.assertEqual( - self.import_(['value'], [ - ['Qux'], - ['Bar'], - ['Foo'], - ['2'], - ]), - ok(4)) - self.assertEqual([3, 2, 1, 2], values(self.read())) - - def test_imported_translated(self): - self.registry('res.lang').load_lang(self.cr, openerp.SUPERUSER_ID, 'fr_FR') - Translations = self.registry('ir.translation') - for source, value in self.translations_fr: - Translations.create(self.cr, openerp.SUPERUSER_ID, { - 'name': 'export.selection,value', - 'lang': 'fr_FR', - 'type': 'selection', - 'src': source, - 'value': value - }) - - self.assertEqual( - self.import_(['value'], [ - ['toto'], - ['tete'], - ['titi'], - ], context={'lang': 'fr_FR'}), - ok(3)) - self.assertEqual([3, 1, 2], values(self.read())) - self.assertEqual( - self.import_(['value'], [['Foo']], context={'lang': 'fr_FR'}), - ok(1)) - - def test_invalid(self): - self.assertEqual( - self.import_(['value'], [['Baz']]), - error(1, u"Value 'Baz' not found in selection field 'unknown'")) - self.cr.rollback() - self.assertEqual( - self.import_(['value'], [[42]]), - error(1, u"Value '42' not found in selection field 'unknown'")) - -class test_selection_function(ImporterCase): - model_name = 'export.selection.function' - translations_fr = [ - ("Corge", "toto"), - ("Grault", "titi"), - ("Wheee", "tete"), - ("Moog", "tutu"), - ] - - def test_imported(self): - """ import uses fields_get, so translates import label (may or may not - be good news) *and* serializes the selection function to reverse it: - import does not actually know that the selection field uses a function - """ - # NOTE: conflict between a value and a label => ? - self.assertEqual( - self.import_(['value'], [ - ['3'], - ["Grault"], - ]), - ok(2)) - self.assertEqual( - [3, 1], - values(self.read())) - - def test_translated(self): - """ Expects output of selection function returns translated labels - """ - self.registry('res.lang').load_lang(self.cr, openerp.SUPERUSER_ID, 'fr_FR') - Translations = self.registry('ir.translation') - for source, value in self.translations_fr: - Translations.create(self.cr, openerp.SUPERUSER_ID, { - 'name': 'export.selection,value', - 'lang': 'fr_FR', - 'type': 'selection', - 'src': source, - 'value': value - }) - self.assertEqual( - self.import_(['value'], [ - ['toto'], - ['tete'], - ], context={'lang': 'fr_FR'}), - ok(2)) - self.assertEqual( - self.import_(['value'], [['Wheee']], context={'lang': 'fr_FR'}), - ok(1)) - -class test_m2o(ImporterCase): - model_name = 'export.many2one' - - def test_by_name(self): - # create integer objects - integer_id1 = self.registry('export.integer').create( - self.cr, openerp.SUPERUSER_ID, {'value': 42}) - integer_id2 = self.registry('export.integer').create( - self.cr, openerp.SUPERUSER_ID, {'value': 36}) - # get its name - name1 = dict(self.registry('export.integer').name_get( - self.cr, openerp.SUPERUSER_ID,[integer_id1]))[integer_id1] - name2 = dict(self.registry('export.integer').name_get( - self.cr, openerp.SUPERUSER_ID,[integer_id2]))[integer_id2] - - self.assertEqual( - self.import_(['value'], [ - # import by name_get - [name1], - [name1], - [name2], - ]), - ok(3)) - # correct ids assigned to corresponding records - self.assertEqual([ - (integer_id1, name1), - (integer_id1, name1), - (integer_id2, name2),], - values(self.read())) - - def test_by_xid(self): - ExportInteger = self.registry('export.integer') - integer_id = ExportInteger.create( - self.cr, openerp.SUPERUSER_ID, {'value': 42}) - xid = self.xid(ExportInteger.browse( - self.cr, openerp.SUPERUSER_ID, [integer_id])[0]) - - self.assertEqual( - self.import_(['value/id'], [[xid]]), - ok(1)) - b = self.browse() - self.assertEqual(42, b[0].value.value) - - def test_by_id(self): - integer_id = self.registry('export.integer').create( - self.cr, openerp.SUPERUSER_ID, {'value': 42}) - self.assertEqual( - self.import_(['value/.id'], [[integer_id]]), - ok(1)) - b = self.browse() - self.assertEqual(42, b[0].value.value) - - def test_by_names(self): - integer_id1 = self.registry('export.integer').create( - self.cr, openerp.SUPERUSER_ID, {'value': 42}) - integer_id2 = self.registry('export.integer').create( - self.cr, openerp.SUPERUSER_ID, {'value': 42}) - name1 = dict(self.registry('export.integer').name_get( - self.cr, openerp.SUPERUSER_ID,[integer_id1]))[integer_id1] - name2 = dict(self.registry('export.integer').name_get( - self.cr, openerp.SUPERUSER_ID,[integer_id2]))[integer_id2] - # names should be the same - self.assertEqual(name1, name2) - - self.assertEqual( - self.import_(['value'], [[name2]]), - ok(1)) - self.assertEqual([ - (integer_id1, name1) - ], values(self.read())) - - def test_fail_by_implicit_id(self): - """ Can't implicitly import records by id - """ - # create integer objects - integer_id1 = self.registry('export.integer').create( - self.cr, openerp.SUPERUSER_ID, {'value': 42}) - integer_id2 = self.registry('export.integer').create( - self.cr, openerp.SUPERUSER_ID, {'value': 36}) - - self.assertEqual( - self.import_(['value'], [ - # import by id, without specifying it - [integer_id1], - [integer_id2], - [integer_id1], - ]), - error(1, u"No matching record found for name '%s' in field 'unknown'" % integer_id1)) - - def test_sub_field(self): - """ Does not implicitly create the record, does not warn that you can't - import m2o subfields (at all)... - """ - self.assertEqual( - self.import_(['value/value'], [['42']]), - error(1, u"Can not create Many-To-One records indirectly, import the field separately")) - - def test_fail_noids(self): - self.assertEqual( - self.import_(['value'], [['nameisnoexist:3']]), - error(1, u"No matching record found for name 'nameisnoexist:3' in field 'unknown'")) - self.cr.rollback() - self.assertEqual( - self.import_(['value/id'], [['noxidhere']]), - error(1, u"No matching record found for external id 'noxidhere' in field 'unknown'")) - self.cr.rollback() - self.assertEqual( - self.import_(['value/.id'], [[66]]), - error(1, u"No matching record found for database id '66' in field 'unknown'")) - -class test_m2m(ImporterCase): - model_name = 'export.many2many' - - # apparently, one and only thing which works is a - # csv_internal_sep-separated list of ids, xids, or names (depending if - # m2m/.id, m2m/id or m2m[/anythingelse] - def test_ids(self): - id1 = self.registry('export.many2many.other').create( - self.cr, openerp.SUPERUSER_ID, {'value': 3, 'str': 'record0'}) - id2 = self.registry('export.many2many.other').create( - self.cr, openerp.SUPERUSER_ID, {'value': 44, 'str': 'record1'}) - id3 = self.registry('export.many2many.other').create( - self.cr, openerp.SUPERUSER_ID, {'value': 84, 'str': 'record2'}) - id4 = self.registry('export.many2many.other').create( - self.cr, openerp.SUPERUSER_ID, {'value': 9, 'str': 'record3'}) - id5 = self.registry('export.many2many.other').create( - self.cr, openerp.SUPERUSER_ID, {'value': 99, 'str': 'record4'}) - - self.assertEqual( - self.import_(['value/.id'], [ - ['%d,%d' % (id1, id2)], - ['%d,%d,%d' % (id1, id3, id4)], - ['%d,%d,%d' % (id1, id2, id3)], - ['%d' % id5] - ]), - ok(4)) - ids = lambda records: [record.id for record in records] - - b = self.browse() - self.assertEqual(ids(b[0].value), [id1, id2]) - self.assertEqual(values(b[0].value), [3, 44]) - - self.assertEqual(ids(b[2].value), [id1, id2, id3]) - self.assertEqual(values(b[2].value), [3, 44, 84]) - - def test_noids(self): - self.assertEqual( - self.import_(['value/.id'], [['42']]), - error(1, u"No matching record found for database id '42' in field 'unknown'")) - - def test_xids(self): - M2O_o = self.registry('export.many2many.other') - id1 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 3, 'str': 'record0'}) - id2 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 44, 'str': 'record1'}) - id3 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 84, 'str': 'record2'}) - id4 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 9, 'str': 'record3'}) - records = M2O_o.browse(self.cr, openerp.SUPERUSER_ID, [id1, id2, id3, id4]) - - self.assertEqual( - self.import_(['value/id'], [ - ['%s,%s' % (self.xid(records[0]), self.xid(records[1]))], - ['%s' % self.xid(records[3])], - ['%s,%s' % (self.xid(records[2]), self.xid(records[1]))], - ]), - ok(3)) - - b = self.browse() - self.assertEqual(values(b[0].value), [3, 44]) - self.assertEqual(values(b[2].value), [44, 84]) - def test_noxids(self): - self.assertEqual( - self.import_(['value/id'], [['noxidforthat']]), - error(1, u"No matching record found for external id 'noxidforthat' in field 'unknown'")) - - def test_names(self): - M2O_o = self.registry('export.many2many.other') - id1 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 3, 'str': 'record0'}) - id2 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 44, 'str': 'record1'}) - id3 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 84, 'str': 'record2'}) - id4 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 9, 'str': 'record3'}) - records = M2O_o.browse(self.cr, openerp.SUPERUSER_ID, [id1, id2, id3, id4]) - - name = lambda record: record.name_get()[0][1] - - self.assertEqual( - self.import_(['value'], [ - ['%s,%s' % (name(records[1]), name(records[2]))], - ['%s,%s,%s' % (name(records[0]), name(records[1]), name(records[2]))], - ['%s,%s' % (name(records[0]), name(records[3]))], - ]), - ok(3)) - - b = self.browse() - self.assertEqual(values(b[1].value), [3, 44, 84]) - self.assertEqual(values(b[2].value), [3, 9]) - - def test_nonames(self): - self.assertEqual( - self.import_(['value'], [['wherethem2mhavenonames']]), - error(1, u"No matching record found for name 'wherethem2mhavenonames' in field 'unknown'")) - - def test_import_to_existing(self): - M2O_o = self.registry('export.many2many.other') - id1 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 3, 'str': 'record0'}) - id2 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 44, 'str': 'record1'}) - id3 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 84, 'str': 'record2'}) - id4 = M2O_o.create(self.cr, openerp.SUPERUSER_ID, {'value': 9, 'str': 'record3'}) - - xid = 'myxid' - self.assertEqual( - self.import_(['id', 'value/.id'], [[xid, '%d,%d' % (id1, id2)]]), - ok(1)) - self.assertEqual( - self.import_(['id', 'value/.id'], [[xid, '%d,%d' % (id3, id4)]]), - ok(1)) - - b = self.browse() - self.assertEqual(len(b), 1) - # TODO: replacement of existing m2m values is correct? - self.assertEqual(values(b[0].value), [84, 9]) - -class test_o2m(ImporterCase): - model_name = 'export.one2many' - - def test_name_get(self): - s = u'Java is a DSL for taking large XML files and converting them to' \ - u' stack traces' - self.assertEqual( - self.import_( - ['const', 'value'], - [['5', s]]), - error(1, u"No matching record found for name '%s' in field 'unknown'" % s)) - - def test_single(self): - self.assertEqual( - self.import_(['const', 'value/value'], [ - ['5', '63'] - ]), - ok(1)) - - (b,) = self.browse() - self.assertEqual(b.const, 5) - self.assertEqual(values(b.value), [63]) - - def test_multicore(self): - self.assertEqual( - self.import_(['const', 'value/value'], [ - ['5', '63'], - ['6', '64'], - ]), - ok(2)) - - b1, b2 = self.browse() - self.assertEqual(b1.const, 5) - self.assertEqual(values(b1.value), [63]) - self.assertEqual(b2.const, 6) - self.assertEqual(values(b2.value), [64]) - - def test_multisub(self): - self.assertEqual( - self.import_(['const', 'value/value'], [ - ['5', '63'], - ['', '64'], - ['', '65'], - ['', '66'], - ]), - ok(4)) - - (b,) = self.browse() - self.assertEqual(values(b.value), [63, 64, 65, 66]) - - def test_multi_subfields(self): - self.assertEqual( - self.import_(['value/str', 'const', 'value/value'], [ - ['this', '5', '63'], - ['is', '', '64'], - ['the', '', '65'], - ['rhythm', '', '66'], - ]), - ok(4)) - - (b,) = self.browse() - self.assertEqual(values(b.value), [63, 64, 65, 66]) - self.assertEqual( - values(b.value, 'str'), - 'this is the rhythm'.split()) - - def test_link_inline(self): - id1 = self.registry('export.one2many.child').create(self.cr, openerp.SUPERUSER_ID, { - 'str': 'Bf', 'value': 109 - }) - id2 = self.registry('export.one2many.child').create(self.cr, openerp.SUPERUSER_ID, { - 'str': 'Me', 'value': 262 - }) - - try: - self.import_(['const', 'value/.id'], [ - ['42', '%d,%d' % (id1, id2)] - ]) - except ValueError, e: - # should be Exception(Database ID doesn't exist: export.one2many.child : $id1,$id2) - self.assertIs(type(e), ValueError) - self.assertEqual( - e.args[0], - "invalid literal for int() with base 10: '%d,%d'" % (id1, id2)) - - def test_link(self): - id1 = self.registry('export.one2many.child').create(self.cr, openerp.SUPERUSER_ID, { - 'str': 'Bf', 'value': 109 - }) - id2 = self.registry('export.one2many.child').create(self.cr, openerp.SUPERUSER_ID, { - 'str': 'Me', 'value': 262 - }) - - self.assertEqual( - self.import_(['const', 'value/.id'], [ - ['42', str(id1)], - ['', str(id2)], - ]), - ok(2)) - - [b] = self.browse() - self.assertEqual(b.const, 42) - # automatically forces link between core record and o2ms - self.assertEqual(values(b.value), [109, 262]) - self.assertEqual(values(b.value, field='parent_id'), [b, b]) - - def test_link_2(self): - O2M_c = self.registry('export.one2many.child') - id1 = O2M_c.create(self.cr, openerp.SUPERUSER_ID, { - 'str': 'Bf', 'value': 109 - }) - id2 = O2M_c.create(self.cr, openerp.SUPERUSER_ID, { - 'str': 'Me', 'value': 262 - }) - - self.assertEqual( - self.import_(['const', 'value/.id', 'value/value'], [ - ['42', str(id1), '1'], - ['', str(id2), '2'], - ]), - ok(2)) - - [b] = self.browse() - self.assertEqual(b.const, 42) - self.assertEqual(values(b.value), [1, 2]) - self.assertEqual(values(b.value, field='parent_id'), [b, b]) - -class test_o2m_multiple(ImporterCase): - model_name = 'export.one2many.multiple' - - def test_multi_mixed(self): - self.assertEqual( - self.import_(['const', 'child1/value', 'child2/value'], [ - ['5', '11', '21'], - ['', '12', '22'], - ['', '13', '23'], - ['', '14', ''], - ]), - ok(4)) - - [b] = self.browse() - self.assertEqual(values(b.child1), [11, 12, 13, 14]) - self.assertEqual(values(b.child2), [21, 22, 23]) - - def test_multi(self): - self.assertEqual( - self.import_(['const', 'child1/value', 'child2/value'], [ - ['5', '11', '21'], - ['', '12', ''], - ['', '13', ''], - ['', '14', ''], - ['', '', '22'], - ['', '', '23'], - ]), - ok(6)) - - [b] = self.browse() - self.assertEqual(values(b.child1), [11, 12, 13, 14]) - self.assertEqual(values(b.child2), [21, 22, 23]) - - def test_multi_fullsplit(self): - self.assertEqual( - self.import_(['const', 'child1/value', 'child2/value'], [ - ['5', '11', ''], - ['', '12', ''], - ['', '13', ''], - ['', '14', ''], - ['', '', '21'], - ['', '', '22'], - ['', '', '23'], - ]), - ok(7)) - - [b] = self.browse() - self.assertEqual(b.const, 5) - self.assertEqual(values(b.child1), [11, 12, 13, 14]) - self.assertEqual(values(b.child2), [21, 22, 23]) - -# function, related, reference: written to db as-is... -# => function uses @type for value coercion/conversion diff --git a/openerp/addons/test_new_api/models.py b/openerp/addons/test_new_api/models.py index 0a27be61f6c..084d8e97fbb 100644 --- a/openerp/addons/test_new_api/models.py +++ b/openerp/addons/test_new_api/models.py @@ -248,6 +248,10 @@ class MixedModel(models.Model): lang = fields.Selection(string='Language', selection='_get_lang') reference = fields.Reference(string='Related Document', selection='_reference_models') + comment1 = fields.Html(sanitize=False) + comment2 = fields.Html(sanitize=True, strip_classes=False) + comment3 = fields.Html(sanitize=True, strip_classes=True) + comment4 = fields.Html(sanitize=True, strip_style=True) @api.one def _compute_now(self): diff --git a/openerp/addons/test_new_api/tests/test_related.py b/openerp/addons/test_new_api/tests/test_related.py index f7fa58847a8..95ffe60efc5 100644 --- a/openerp/addons/test_new_api/tests/test_related.py +++ b/openerp/addons/test_new_api/tests/test_related.py @@ -125,15 +125,15 @@ class TestHtmlField(common.TransactionCase): def setUp(self): super(TestHtmlField, self).setUp() - self.partner = self.registry('res.partner') + self.model = self.env['test_new_api.mixed'] def test_00_sanitize(self): - cr, uid, context = self.cr, self.uid, {} - old_columns = self.partner._columns - self.partner._columns = dict(old_columns) - self.partner._columns.update({ - 'comment': fields.html('Secure Html', sanitize=False), - }) + self.assertEqual(self.model._fields['comment1'].sanitize, False) + self.assertEqual(self.model._fields['comment2'].sanitize, True) + self.assertEqual(self.model._fields['comment2'].strip_classes, False) + self.assertEqual(self.model._fields['comment3'].sanitize, True) + self.assertEqual(self.model._fields['comment3'].strip_classes, True) + some_ugly_html = """
Oops this should maybe be sanitized % if object.some_field and not object.oriented: