diff options
| author | Denis Ledoux <dle@odoo.com> | 2020-05-06 16:03:58 +0000 |
|---|---|---|
| committer | Denis Ledoux <dle@odoo.com> | 2020-05-11 15:23:25 +0000 |
| commit | 9d2ca693776fdc89ed869bf3742d3150c0e6b318 (patch) | |
| tree | 8e4945538bd1bc0a8f3f51459885064e838a6431 /odoo/addons/test_new_api/tests/test_new_fields.py | |
| parent | 1311b0a0966906d354cb084ba5374c3814583fa2 (diff) | |
[FIX] registry: transitive dependencies of custom fields may not exist
This is related to
826c86e9ab31963e410887a30326f45bcfadf5ea
The case is the same,
a custom field with an invalid depends,
except that this time its through a transitive dependency.
e.g.
custom_field_2 depends on custom_field_1
custom_field_1 depends on unexisting_field
The loading of the registry completely fails,
because the loading of the field `custom_field_2` raises a
`KeyError` exception in
`def transitive_dependencies` @ `dependencies[field]`
because the `custom_field_1` was skipped @ line
`dependencies[field] = set(field.resolve_depends(model))`
Landing in a state where the server can no longer start at all,
and the user can't therefore solve its custom field himself
to repair the situation.
closes odoo/odoo#51057
X-original-commit: 7b642884cc4d643a5a998b4639bf26b4e81cc46e
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
Diffstat (limited to 'odoo/addons/test_new_api/tests/test_new_fields.py')
| -rw-r--r-- | odoo/addons/test_new_api/tests/test_new_fields.py | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index 80ac2de233c..6df342aaf94 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -158,6 +158,78 @@ class TestFields(TransactionCaseWithUserDemo): field = self.env['test_new_api.message']._fields['x_bool_false_computed'] self.assertFalse(field.depends) + def test_10_computed_custom_invalid_transitive_depends(self): + self.patch(type(self.env["ir.model.fields"]), "_check_depends", lambda self: True) + self.env["ir.model.fields"].create( + { + "name": "x_computed_custom_valid_depends", + "model_id": self.env.ref("test_new_api.model_test_new_api_foo").id, + "state": "manual", + "field_description": "A compute with a valid depends", + "compute": "for r in self: r['x_computed_custom_valid_depends'] = False", + "depends": "value1", + "store": False, + "ttype": "boolean", + } + ) + self.env["ir.model.fields"].create( + { + "name": "x_computed_custom_valid_transitive_depends", + "model_id": self.env.ref("test_new_api.model_test_new_api_foo").id, + "state": "manual", + "field_description": "A compute with a valid transitive depends", + "compute": "for r in self: r['x_computed_custom_valid_transitive_depends'] = False", + "depends": "x_computed_custom_valid_depends", + "store": False, + "ttype": "boolean", + } + ) + self.env["ir.model.fields"].create( + { + "name": "x_computed_custom_invalid_depends", + "model_id": self.env.ref("test_new_api.model_test_new_api_foo").id, + "state": "manual", + "field_description": "A compute with an invalid depends", + "compute": "for r in self: r['x_computed_custom_invalid_depends'] = False", + "depends": "bar", + "store": False, + "ttype": "boolean", + } + ) + self.env["ir.model.fields"].create( + { + "name": "x_computed_custom_invalid_transitive_depends", + "model_id": self.env.ref("test_new_api.model_test_new_api_foo").id, + "state": "manual", + "field_description": "A compute with an invalid transitive depends", + "compute": "for r in self: r['x_computed_custom_invalid_transitive_depends'] = False", + "depends": "x_computed_custom_invalid_depends", + "store": False, + "ttype": "boolean", + } + ) + fields = self.env["test_new_api.foo"]._fields + triggers = self.env.registry.field_triggers + value1 = fields["value1"] + valid_depends = fields["x_computed_custom_valid_depends"] + valid_transitive_depends = fields["x_computed_custom_valid_transitive_depends"] + invalid_depends = fields["x_computed_custom_invalid_depends"] + invalid_transitive_depends = fields["x_computed_custom_invalid_transitive_depends"] + # `x_computed_custom_valid_depends` in the triggers of the field `value1` + self.assertTrue(valid_depends in triggers[value1][None]) + # `x_computed_custom_valid_transitive_depends` in the triggers `x_computed_custom_valid_depends` and `value1` + self.assertTrue(valid_transitive_depends in triggers[valid_depends][None]) + self.assertTrue(valid_transitive_depends in triggers[value1][None]) + # `x_computed_custom_invalid_depends` not in any triggers, as it was invalid and was skipped + self.assertEqual( + sum(invalid_depends in field_triggers.get(None, []) for field_triggers in triggers.values()), 0 + ) + # `x_computed_custom_invalid_transitive_depends` in the triggers of `x_computed_custom_invalid_depends` only + self.assertTrue(invalid_transitive_depends in triggers[invalid_depends][None]) + self.assertEqual( + sum(invalid_transitive_depends in field_triggers.get(None, []) for field_triggers in triggers.values()), 1 + ) + def test_10_display_name(self): """ test definition of automatic field 'display_name' """ field = type(self.env['test_new_api.discussion']).display_name |
