def test_export_import(self): """ Ensure export+import gives the same result as loading a language """ # load language and generate missing terms to create missing empty terms with mute_logger('odoo.addons.base.models.ir_translation'): self.env["base.language.install"].create({ 'overwrite': True, 'lang_ids': [(6, 0, [self.env.ref('base.lang_fr').id])], }).lang_install() self.env["base.update.translations"].create({ 'lang': 'fr_FR' }).act_update() translations = self.env["ir.translation"].search([ ('lang', '=', 'fr_FR'), ('module', '=', 'test_translation_import'), ('value', '!=', ''), ]) # minus 3 as the original fr.po contains 3 fake code translations (cf # test_no_duplicate test) which are not found by babel_extract_terms init_translation_count = len(translations) - 3 module = self.env.ref('base.module_test_translation_import') export = self.env["base.language.export"].create({ 'lang': 'fr_FR', 'format': 'po', 'modules': [Command.set([module.id])] }) export.act_getfile() po_file = export.data self.assertIsNotNone(po_file) translations.unlink() import_fr = self.env["base.language.import"].create({ 'name': 'French', 'code': 'fr_FR', 'data': export.data, 'filename': export.name, 'overwrite': False, }) with mute_logger('odoo.addons.base.models.res_lang'): import_fr.import_lang() import_translation = self.env["ir.translation"].search([ ('lang', '=', 'fr_FR'), ('module', '=', 'test_translation_import'), ('value', '!=', ''), ]) self.assertEqual(init_translation_count, len(import_translation))
def test_lang_paynow_debrand(self): with mute_logger("odoo.addons.base.models.ir_translation"): self.env["base.language.install"].create( {"lang": "nl_NL", "overwrite": True} ).lang_install() with mute_logger("odoo.tools.translate"): self.env["base.update.translations"].create({"lang": "nl_NL"}).act_update() ctx = dict(lang="nl_NL") paynow_template = self.env.ref("mail.mail_notification_paynow") paynow_arch = paynow_template.with_context(ctx).arch self.assertIn("Aangeboden door", paynow_arch) res = self.env["mail.template"].with_context(ctx)._debrand_body(paynow_arch) self.assertNotIn("Aangeboden door", res)
def test_export_import_csv(self): """ Ensure can reimport exported csv """ self.env.ref("base.lang_fr").active = True module = self.env.ref('base.module_test_translation_import') export = self.env["base.language.export"].create({ 'lang': 'fr_FR', 'format': 'csv', 'modules': [Command.set([module.id])] }) export.act_getfile() po_file = export.data self.assertIsNotNone(po_file) self.env["ir.translation"].search([ ('lang', '=', 'fr_FR'), ('module', '=', 'test_translation_import') ]).unlink() import_fr = self.env["base.language.import"].create({ 'name': 'French', 'code': 'fr_FR', 'data': export.data, 'filename': export.name, 'overwrite': False, }) with mute_logger('odoo.addons.base.models.res_lang'): import_fr.with_context(create_empty_translation=True).import_lang()
def test_transition_execution_error(self): """ Should return an error when a transition's condition crashes """ # Call to the scanner are done on the model using the scanner code scanner_hardware = self.env['scanner.hardware'] # the result is the list of nested scenario since or scenario is a # menu with the parent menu as title scenario_step_types = self.env.ref( 'stock_scanner.scanner_scenario_step_types') # Launch the Step types scenario scanner_hardware.scanner_call(self.hardware.code, action='action', message=scenario_step_types.name) # Remove all outgoing transitions from the current step self.hardware.step_id.out_transition_ids.write({ 'condition': 'undefined_function()', }) # Try to go to the next step with mute_logger('stock_scanner'): ret = scanner_hardware.scanner_call(self.hardware.code, action='action') self.assertEqual(ret, ('R', [ 'Please contact', 'your', 'administrator', ], 0))
def test_assign_employee(self): with self.registry.cursor() as cr: env = self.env(cr=cr) request = env['request.request'].with_context( mail_create_nolog=True, mail_notrack=True, ).create({ 'type_id': env.ref('generic_request.request_type_sequence').id, 'request_text': 'Test', }) with disable_mail_auto_delete(env): request.with_context(mail_notrack=False, ).write({ 'user_id': self.request_demo_user.id, }) assign_messages = env['mail.mail'].search([ ('model', '=', 'request.request'), ('res_id', '=', request.id), ('body_html', 'ilike', '%%/mail/view/request/%s%%' % request.id), ]) self.assertEqual(len(assign_messages), 1) self.authenticate(self.request_demo_user.login, 'demo') with mute_logger('odoo.addons.base.models.ir_model'): # Hide errors about missing menus res = self.url_open('/mail/view/request/%s' % request.id) self.assertEqual(res.status_code, 200) self.assertNotRegex(res.url, r'^%s/web/login.*$' % self.base_url) self.assertRegex(res.url, r'^%s/web#.*id=%s.*$' % (self.base_url, request.id))
def test_no_duplicate_assignment(self): user = self.ResUsers.sudo().create({ 'name': 'User', 'login': '******', 'email': '*****@*****.**', 'company_id': self.company_id.id, }) project = self.Project.create({ 'name': 'Project', }) role = self.Role.create({ 'name': 'Role', }) self.Assignment.create({ 'project_id': project.id, 'role_id': role.id, 'user_id': user.id, }) with self.assertRaises(IntegrityError), mute_logger('odoo.sql_db'): self.Assignment.create({ 'project_id': project.id, 'role_id': role.id, 'user_id': user.id, })
def test_step_code_syntax(self): """ Should raise if the python code contains syntax errors """ step = self.env.ref('stock_scanner.' 'scanner_scenario_step_sentinel_introduction') with self.assertRaises(exceptions.ValidationError): with mute_logger('stock_scanner'): step.python_code = 'function('
def test_import_from_po_file(self): """Test the import from a single po file works""" with file_open('test_translation_import/i18n/tlh.po', 'rb') as f: po_file = base64.encodestring(f.read()) import_tlh = self.env["base.language.import"].create({ 'name': 'Klingon', 'code': 'tlh', 'data': po_file, 'filename': 'tlh.po', }) with mute_logger('odoo.addons.base.models.res_lang'): import_tlh.import_lang() tlh_lang = self.env['res.lang']._lang_get('tlh') self.assertTrue(tlh_lang, "The imported language was not creates") trans_count = self.env['ir.translation'].search_count([('lang', '=', 'tlh')]) self.assertEqual(trans_count, 1, "The imported translations were not created") self.env.context = dict(self.env.context, lang="tlh") self.assertEqual(_("Klingon"), "tlhIngan", "The code translation was not applied")
def test_lazy_translation(self): """Test the import from a single po file works""" with file_open('test_translation_import/i18n/tlh.po', 'rb') as f: po_file = base64.encodestring(f.read()) import_tlh = self.env["base.language.import"].create({ 'name': 'Klingon', 'code': 'tlh', 'data': po_file, 'filename': 'tlh.po', }) with mute_logger('odoo.addons.base.models.res_lang'): import_tlh.import_lang() context = {'lang': "tlh"} self.assertEqual(_("Klingon"), "tlhIngan", "The direct code translation was not applied") context = None # Comparison of lazy strings must be explicitely casted to string with self.assertRaises(NotImplementedError): TRANSLATED_TERM == "Klingon" self.assertEqual(str(TRANSLATED_TERM), "Klingon", "The translation should not be applied yet") context = {'lang': "tlh"} self.assertEqual(str(TRANSLATED_TERM), "tlhIngan", "The lazy code translation was not applied")
def test_import_from_csv_file(self): """Test the import from a single CSV file works""" with file_open('test_translation_import/i18n/dot.csv', 'rb') as f: po_file = base64.encodestring(f.read()) import_tlh = self.env["base.language.import"].create({ 'name': 'Dothraki', 'code': 'dot', 'data': po_file, 'filename': 'dot.csv', }) with mute_logger('odoo.addons.base.models.res_lang'): import_tlh.import_lang() dot_lang = self.env['res.lang']._lang_get('dot') self.assertTrue(dot_lang, "The imported language was not creates") trans_count = self.env['ir.translation'].search_count([('lang', '=', 'dot')]) self.assertEqual(trans_count, 1, "The imported translations were not created") self.env.context = dict(self.env.context, lang="dot") self.assertEqual(_("Accounting"), "samva", "The code translation was not applied")
def test_02_check_code_unique(self): with self.assertRaises(psycopg2.IntegrityError): with mute_logger("odoo.sql_db"), self.cr.savepoint(): self.product2 = self.product_obj.create({ "name": "Test Product 2", "default_code": "TSTP1" })
def test_02_delete(self): """ Delete: NOT NULL and ON DELETE RESTRICT constraints """ b1 = self.o.execute(self.db_name, 1, "admin", "test_rpc.model_b", "create", {"name": "B1"}) b2 = self.o.execute(self.db_name, 1, "admin", "test_rpc.model_b", "create", {"name": "B2"}) self.o.execute(self.db_name, 1, "admin", "test_rpc.model_a", "create", { "name": "A1", "field_b1": b1, "field_b2": b2 }) # Unlink b1 => NOT NULL constraint raises # FORWARD-PORT: in master, `required=True` implies `ondelete="restrict"` # => the message should be the same than 'Unlink b2' case. try: with mute_logger("odoo.sql_db"): self.o.execute(self.db_name, 1, "admin", "test_rpc.model_b", "unlink", b1) raise except Exception as e: self.assertIn("The operation cannot be completed:", e.faultString) self.assertIn("Create/update: a mandatory field is not set.", e.faultString) self.assertIn( "Delete: another model requires the record being deleted. If possible, archive it instead.", e.faultString, ) self.assertIn( "Model: Model A (test_rpc.model_a), Field: required field (field_b1)", e.faultString) # Unlink b2 => ON DELETE RESTRICT constraint raises try: with mute_logger("odoo.sql_db"): self.o.execute(self.db_name, 1, "admin", "test_rpc.model_b", "unlink", b2) raise except Exception as e: self.assertIn("The operation cannot be completed:", e.faultString) self.assertIn( " another model requires the record being deleted. If possible, archive it instead.", e.faultString) self.assertIn( "Model: Model A (test_rpc.model_a), Constraint: test_rpc_model_a_field_b2_fkey", e.faultString)
def test_transition_condition_syntax(self): """ Should raise if the condition contains syntax errors """ transition = self.env.ref( 'stock_scanner.' 'scanner_scenario_transition_sentinel_intro_scroll') with self.assertRaises(exceptions.ValidationError): with mute_logger('stock_scanner'): transition.condition = 'function('
def test_zip_ql_constraints(self): """Test UNIQUE name within it's area for zips""" with self.assertRaises( psycopg2.IntegrityError), mute_logger("odoo.sql_db"): self.env["res.city.zip"].create({ "name": "666", "city_id": self.city_lausanne.id })
def test_zip_ql_constraints(self): """Test UNIQUE name within it's area for zips""" with self.assertRaises( psycopg2.IntegrityError), mute_logger('odoo.sql_db'): self.env['res.city.zip'].create({ 'name': '666', 'city_id': self.city_lausanne.id, })
def test_city_sql_contraint(self): """Test UNIQUE name within it's area for cities""" with self.assertRaises( psycopg2.IntegrityError), mute_logger("odoo.sql_db"): self.env["res.city"].create({ "name": "Barcelona", "state_id": self.state_bcn.id, "country_id": self.ref("base.es"), })
def test_city_sql_contraint(self): """Test UNIQUE name within it's area for cities""" with self.assertRaises( psycopg2.IntegrityError), mute_logger('odoo.sql_db'): self.env['res.city'].create({ 'name': 'Barcelona', 'state_id': self.state_bcn.id, 'country_id': self.ref('base.es'), })
def test_type_access_rights_0010(self): with mute_logger('odoo.models'): with self.assertRaises(exceptions.AccessError): # pylint: disable=pointless-statement self.ut_simple_type.sudo(self.demo_test_user_1).read(['name']) simple_group = self.env['res.groups'].create({ 'name': 'Test simple group' }) self.assertFalse( simple_group in self.ut_simple_type.sudo().access_group_ids) # Add to Request Category Access Group new simple_group self.ut_simple_type.sudo().write({ 'access_group_ids': [(4, simple_group.id)], }) self.assertTrue( simple_group in self.ut_simple_type.sudo().access_group_ids) with mute_logger('odoo.models'): with self.assertRaises(exceptions.AccessError): # pylint: disable=pointless-statement self.ut_simple_type.sudo(self.demo_test_user_1).read(['name']) website_user = self.env.ref( 'crnd_wsd.group_service_desk_website_user') # self.assertFalse(self.demo_test_user_1 in website_user.users) # Add demo-user to 'website_user' # self.demo_test_user_1.groups_id |= website_user self.assertTrue(self.demo_test_user_1 in website_user.users) # Add demo-user to 'simple_group' self.demo_test_user_1.groups_id |= simple_group # Ensure, after adding to group simple_group the # simple_category is readable self.assertTrue(self.ut_simple_type.sudo( self.demo_test_user_1).read(['name']))
def test_check_partner_holiday_constraint(self): vals = { "partner_id": self.partner_2.id, "day_from": "1", "month_from": "12", "day_to": "1", "month_to": "01", } with self.assertRaises(psycopg2.IntegrityError), mute_logger('odoo.sql_db'): self.env["res.partner.holiday"].create(vals)
def test_090_user_request_type_access(self): with mute_logger('odoo.models'): with self.assertRaises(exceptions.AccessError): self.usimple_type.name # pylint: disable=pointless-statement # Subscribe demo-user to 'simple request' type self.simple_type.message_subscribe(self.demo_user.partner_id.ids) # Ensure, after subscription simple_type is readable self.assertTrue(self.usimple_type.name)
def test_export_import(self): """ Ensure export+import gives the same result as loading a language """ # load language and generate missing terms to create missing empty terms with mute_logger('odoo.addons.base.models.ir_translation'): self.env["base.language.install"].create({'lang': 'fr_FR'}).lang_install() self.env["base.update.translations"].create({'lang': 'fr_FR'}).act_update() translations = self.env["ir.translation"].search([ ('lang', '=', 'fr_FR'), ('module', '=', 'test_translation_import') ]) # minus 3 as the original fr.po contains 3 fake code translations (cf # test_no_duplicate test) which are not found by babel_extract_terms init_translation_count = len(translations) - 3 module = self.env.ref('base.module_test_translation_import') export = self.env["base.language.export"].create({ 'lang': 'fr_FR', 'format': 'po', 'modules': [(6, 0, [module.id])] }) export.act_getfile() po_file = export.data self.assertIsNotNone(po_file) translations.unlink() import_fr = self.env["base.language.import"].create({ 'name': 'French', 'code': 'fr_FR', 'data': export.data, 'filename': export.name, }) with mute_logger('odoo.addons.base.models.res_lang'): import_fr.with_context(create_empty_translation=True).import_lang() import_translation = self.env["ir.translation"].search([ ('lang', '=', 'fr_FR'), ('module', '=', 'test_translation_import') ]) self.assertEqual(init_translation_count, len(import_translation))
def test_followers_no_DID(self): """Test that a follower cannot suffer from dissociative identity disorder. It cannot be both a partner and a channel. """ with self.assertRaises(IntegrityError), mute_logger('odoo.sql_db'): self.env['mail.followers'].create({ 'res_model': self.test_record._name, 'res_id': self.test_record.id, 'partner_id': self.user_employee.partner_id.id, 'channel_id': self.channel_listen.id, })
def test_validation_error(self): self._activate_certificate(self.certificate_password) self.main_company.partner_id.country_id = False self.move.action_post() self.move.name = "2999/99999" with self.assertRaises(exceptions.UserError), mute_logger( "odoo.addons.l10n_es_facturae.reports.report_facturae" ): self.wizard.with_context( active_ids=self.move.ids, active_model="account.move" ).create_facturae_file()
def test_fields_browse_restriction(self): """Test access to records having restricted fields""" partner = self.env['res.partner'].sudo(self.demo_user) self._set_field_groups(partner, 'email', GROUP_SYSTEM) # accessing fields must no raise exceptions... partner = partner.search([], limit=1) partner.name # ... except if they are restricted with self.assertRaises(AccessError): with mute_logger('odoo.models'): partner.email
def test_fields_browse_restriction(self): """Test access to records having restricted fields""" partner = self.env['res.partner'].with_user(self.demo_user) self._set_field_groups(partner, 'email', GROUP_SYSTEM) # accessing fields must no raise exceptions... partner = partner.search([], limit=1) partner.name # ... except if they are restricted with self.assertRaises(AccessError): with mute_logger('odoo.models'): partner.email
def test_02_delete(self): """ Delete: NOT NULL and ON DELETE RESTRICT constraints """ b1 = self.rpc("test_rpc.model_b", "create", {"name": "B1"}) b2 = self.rpc("test_rpc.model_b", "create", {"name": "B2"}) self.rpc("test_rpc.model_a", "create", { "name": "A1", "field_b1": b1, "field_b2": b2 }) try: with mute_logger("odoo.sql_db"): self.rpc("test_rpc.model_b", "unlink", b1) raise except Exception as e: self.assertIn("The operation cannot be completed:", e.faultString) self.assertIn( "another model requires the record being deleted. If possible, archive it instead.", e.faultString, ) self.assertIn( "Model: Model A (test_rpc.model_a), Constraint: test_rpc_model_a_field_b1_fkey", e.faultString, ) # Unlink b2 => ON DELETE RESTRICT constraint raises try: with mute_logger("odoo.sql_db"): self.rpc("test_rpc.model_b", "unlink", b2) raise except Exception as e: self.assertIn("The operation cannot be completed:", e.faultString) self.assertIn( " another model requires the record being deleted. If possible, archive it instead.", e.faultString, ) self.assertIn( "Model: Model A (test_rpc.model_a), Constraint: test_rpc_model_a_field_b2_fkey", e.faultString, )
def test_document_page_tag(self): testtag = self.env['document.page.tag'].name_create('test') # check we're charitable on duplicates self.assertEqual( testtag, self.env['document.page.tag'].name_create('Test'), ) # check we can't create nonunique tags with self.assertRaises(IntegrityError): with mute_logger('odoo.sql_db'): testtag2 = self.env['document.page.tag'].create({ 'name': 'test2', }) testtag2.write({'name': 'test'})
def test_export_pollution(self): """ Test that exporting the translation only exports the translations of the module """ with file_open('test_translation_import/i18n/dot.csv', 'rb') as f: csv_file = base64.b64encode(f.read()) # dot.csv only contains one term import_tlh = self.env["base.language.import"].create({ 'name': 'Dothraki', 'code': 'dot', 'data': csv_file, 'filename': 'dot.csv', }) with mute_logger('odoo.addons.base.models.res_lang'): import_tlh.import_lang() # create a translation that has the same src as an existing field but no module # information and a different res_id that the real field # this translation should not be included in the export self.env['ir.translation'].create({ 'src': '1XBUO5PUYH2RYZSA1FTLRYS8SPCNU1UYXMEYMM25ASV7JC2KTJZQESZYRV9L8CGB', 'value': '1XBUO5PUYH2RYZSA1FTLRYS8SPCNU1UYXMEYMM25ASV7JC2KTJZQESZYRV9L8CGB in Dothraki', 'type': 'model', 'name': 'ir.model.fields,field_description', 'res_id': -1, 'lang': 'dot', }) module = self.env.ref('base.module_test_translation_import') export = self.env["base.language.export"].create({ 'lang': 'dot', 'format': 'po', 'modules': [(6, 0, [module.id])] }) export.act_getfile() po_file = export.data reader = TranslationFileReader(base64.b64decode(po_file).decode(), fileformat='po') for row in reader: if row['value']: # should contains only one row from the csv, not the manual one self.assertEqual(row['src'], "Accounting") self.assertEqual(row['value'], "samva")
def test_companywide_assignments_1(self): user = self.ResUsers.sudo().create( { "name": "User", "login": "******", "email": "*****@*****.**", "company_id": self.company_id.id, } ) role = self.Role.create({"name": "Role"}) self.Assignment.create({"role_id": role.id, "user_id": user.id}) with self.assertRaises(IntegrityError), mute_logger("odoo.sql_db"): self.Assignment.create({"role_id": role.id, "user_id": user.id})
def test_1(self): self.SudoSaleOrder.create({ 'name': 'Test #1', 'partner_id': self.env.ref('base.res_partner_1').id, }) with self.assertRaises(IntegrityError), mute_logger('odoo.sql_db'): self.SudoSaleOrder.create({ 'name': 'Test #1', 'partner_id': self.env.ref('base.res_partner_1').id, })
def test_fields_browse_restriction(self): """Test access to records having restricted fields""" # Invalidate cache to avoid restricted value to be available # in the cache self.user_demo.invalidate_cache() partner = self.env['res.partner'].with_user(self.user_demo) self._set_field_groups(partner, 'email', GROUP_SYSTEM) # accessing fields must no raise exceptions... partner = partner.search([], limit=1) partner.name # ... except if they are restricted with self.assertRaises(AccessError): with mute_logger('odoo.models'): partner.email
def test_unlink_retry_task(self): """ Unlink RETRY task """ Task = self.env['celery.task'] vals = { 'uuid': str(uuid.uuid4()), 'user_id': self.env.user.id, 'model': 'celery.task', 'method': 'dummy_method', } task = Task.create(vals) task.state = STATE_STARTED with self.assertRaisesRegex(UserError, 'You cannot delete a running task'), mute_logger('odoo.sql_db'): task.unlink()
def test_no_DID(self): """Test that a follower cannot suffer from dissociative identity disorder. It cannot be both a partner and a channel. """ test_record = self.env['mail.channel'].create({ 'name': 'I used to be schizo, but now we are alright.' }) test_channel = self.env['mail.channel'].create({'name': 'Follower Channel'}) with self.assertRaises(IntegrityError), mute_logger('odoo.sql_db'): self.env['mail.followers'].create({ 'res_model': test_record._name, 'res_id': test_record.id, 'partner_id': self.user_employee.partner_id.id, 'channel_id': test_channel.id, })
def test_import_from_csv_file(self): """Test the import from a single CSV file works""" with file_open('test_translation_import/i18n/dot.csv', 'rb') as f: po_file = base64.encodestring(f.read()) import_tlh = self.env["base.language.import"].create({ 'name': 'Dothraki', 'code': 'dot', 'data': po_file, 'filename': 'dot.csv', }) with mute_logger('odoo.addons.base.models.res_lang'): import_tlh.import_lang() lang_count = self.env['res.lang'].search_count([('code', '=', 'dot')]) self.assertEqual(lang_count, 1, "The imported language was not creates") trans_count = self.env['ir.translation'].search_count([('lang', '=', 'dot')]) self.assertEqual(trans_count, 1, "The imported translations were not created") self.env.context = dict(self.env.context, lang="dot") self.assertEqual(_("Accounting"), "samva", "The code translation was not applied")