From fb43199c8b94fb9549886598cc7111e8c7fcf9d5 Mon Sep 17 00:00:00 2001 From: "Tommy (tong)" Date: Wed, 18 May 2022 15:37:41 +0000 Subject: [PATCH] [FIX] base_import_module: fix imported static files cannot be replaced Issue: Imported module is not able to search existing static files to replace them Cause: After changing the new loc calculation, ir.attachment will link to the ir.model.data. However, those attachments will not able to search anymore without sudo. Therefore, the system will try to create the attachment again. It will return error because constraint "ir_model_data_module_name_uniq_index" will prevent ir.model.data to create again. Solution: Use sudo to search the attachment. closes odoo/odoo#93752 X-original-commit: 8f604847eb1ec96955ee724ad7b882c74160b9d7 Signed-off-by: Vincent Schippefilt (vsc) --- addons/base_import_module/models/ir_module.py | 2 +- .../tests/test_import_module.py | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/addons/base_import_module/models/ir_module.py b/addons/base_import_module/models/ir_module.py index 7bca006c1f9..0daea8b8772 100644 --- a/addons/base_import_module/models/ir_module.py +++ b/addons/base_import_module/models/ir_module.py @@ -100,7 +100,7 @@ class IrModule(models.Model): type='binary', datas=data, ) - attachment = IrAttachment.search([('url', '=', url_path), ('type', '=', 'binary'), ('res_model', '=', 'ir.ui.view')]) + attachment = IrAttachment.sudo().search([('url', '=', url_path), ('type', '=', 'binary'), ('res_model', '=', 'ir.ui.view')]) if attachment: attachment.write(values) else: diff --git a/addons/base_import_module/tests/test_import_module.py b/addons/base_import_module/tests/test_import_module.py index af0a5271d4d..14d05203867 100644 --- a/addons/base_import_module/tests/test_import_module.py +++ b/addons/base_import_module/tests/test_import_module.py @@ -5,6 +5,7 @@ from io import BytesIO from zipfile import ZipFile import odoo.tests +from odoo.tests import new_test_user @odoo.tests.tagged('post_install', '-at_install') class TestImportModule(odoo.tests.TransactionCase): @@ -57,3 +58,68 @@ class TestImportModule(odoo.tests.TransactionCase): asset_data = self.env['ir.model.data'].search([('model', '=', 'ir.asset'), ('res_id', '=', asset.id)]) self.assertEqual(len(asset_data), 0) + + def test_import_and_update_module(self): + self.test_user = new_test_user( + self.env, login='Admin', + groups='base.group_user,base.group_system', + name='Admin', + ) + bundle = 'web.assets_backend' + path = 'test_module/static/src/js/test.js' + manifest_content = json.dumps({ + 'name': 'Test Module', + 'description': 'Test', + 'assets': { + bundle: [ + path + ] + }, + 'license': 'LGPL-3', + }) + stream = BytesIO() + with ZipFile(stream, 'w') as archive: + archive.writestr('test_module/__manifest__.py', manifest_content) + archive.writestr(path, "console.log('AAA');") + + # Import test module + self.env['ir.module.module'].with_user(self.test_user).import_zipfile(stream) + + attachment = self.env['ir.attachment'].search([('url', '=', f'/{path}')]) + self.assertEqual(attachment.name, 'test.js') + self.assertEqual(attachment.type, 'binary') + self.assertEqual(attachment.raw, b"console.log('AAA');") + + asset = self.env['ir.asset'].search([('name', '=', f'test_module.{bundle}./{path}')]) + self.assertEqual(asset.path, f'/{path}') + self.assertEqual(asset.bundle, bundle) + self.assertEqual(asset.directive, 'append') + self.assertEqual(asset.target, False) + + asset_data = self.env['ir.model.data'].search([('model', '=', 'ir.asset'), ('res_id', '=', asset.id)]) + self.assertEqual(asset_data.module, 'test_module') + self.assertEqual(asset_data.name, f'{bundle}_/{path}'.replace(".", "_")) + + # Update test module + stream = BytesIO() + with ZipFile(stream, 'w') as archive: + archive.writestr('test_module/__manifest__.py', manifest_content) + archive.writestr(path, "console.log('BBB');") + + # Import test module + self.env['ir.module.module'].with_user(self.test_user).import_zipfile(stream) + + attachment = self.env['ir.attachment'].search([('url', '=', f'/{path}')]) + self.assertEqual(attachment.name, 'test.js') + self.assertEqual(attachment.type, 'binary') + self.assertEqual(attachment.raw, b"console.log('BBB');") + + asset = self.env['ir.asset'].search([('name', '=', f'test_module.{bundle}./{path}')]) + self.assertEqual(asset.path, f'/{path}') + self.assertEqual(asset.bundle, bundle) + self.assertEqual(asset.directive, 'append') + self.assertEqual(asset.target, False) + + asset_data = self.env['ir.model.data'].search([('model', '=', 'ir.asset'), ('res_id', '=', asset.id)]) + self.assertEqual(asset_data.module, 'test_module') + self.assertEqual(asset_data.name, f'{bundle}_/{path}'.replace(".", "_"))