[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) <vsc@odoo.com>
This commit is contained in:
Tommy (tong)
2022-06-21 11:20:17 +02:00
parent a2ba3739b8
commit fb43199c8b
2 changed files with 67 additions and 1 deletions
@@ -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:
@@ -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(".", "_"))