from odoo import fields from odoo.tests.common import TransactionCase, tagged, new_test_user @tagged('-at_install', 'post_install') class TestSchema(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() cls.Parent = cls.env['runbot.test.model.parent'] cls.Child = cls.env['runbot.test.model.child'] cls.user_basic = new_test_user( cls.env, 'basic', ) def test_parent_schema(self): schema = self.Parent._get_public_schema() self.assertNotIn('private_field', schema) self.assertEqual( schema['field_bool'], { '__type': 'boolean', } ) self.assertIn('field_many2one', schema) sub_schema = schema['field_many2one'] self.assertIn('field_many2many', schema) self.assertIn('field_many2many', sub_schema) self.assertTrue(self.Parent._verify_schema(schema)) def test_child_schema(self): schema = self.Child._get_public_schema() self.assertIn('parent_id', schema) self.assertIn('data', schema) sub_schema = schema['parent_id'] # The reverse relation should not be part of the sub schema, as we already # traversed that relation self.assertNotIn('field_one2many', sub_schema) self.assertTrue(self.Child._verify_schema(schema)) def test_parent_read_basic(self): today = fields.Date.today() now = fields.Datetime.now() parent = self.Parent.create({ 'field_bool': True, 'field_date': today, 'field_datetime': now, 'field_json': {'test': 1} }) self.assertEqual( parent._read_schema({'field_bool': None, 'field_date': None, 'field_datetime': None, 'field_json': None}), [{ 'id': parent.id, 'field_bool': True, 'field_date': today.isoformat(), 'field_datetime': now.isoformat(), 'field_json': {'test': 1} }] ) def test_parent_read_m2o(self): parent_1 = self.Parent.create({'field_integer': 1}) parent_2 = self.Parent.create({'field_integer': 2, 'field_many2one': parent_1.id}) # Read without sub schema self.assertEqual( parent_1._read_schema({'field_many2one': None}), [{'id': parent_1.id, 'field_many2one': None}] ) self.assertEqual( parent_2._read_schema({'field_many2one': None}), [{'id': parent_2.id, 'field_many2one': parent_1.id}] ) # Read with sub schema self.assertEqual( parent_1._read_schema({'field_many2one': {'field_integer': None}}), [{'id': parent_1.id, 'field_many2one': None}] ) self.assertEqual( parent_2._read_schema({'field_many2one': {'field_integer': None}}), [{'id': parent_2.id, 'field_many2one': {'id': parent_1.id, 'field_integer': parent_1.field_integer}}] ) both = parent_1 | parent_2 # Read both with sub schema self.assertEqual( both._read_schema({'field_integer': None, 'field_many2one': {'field_integer': None}}), [ {'id': parent_1.id, 'field_integer': parent_1.field_integer, 'field_many2one': None}, {'id': parent_2.id, 'field_integer': parent_2.field_integer, 'field_many2one': { 'id': parent_1.id, 'field_integer': parent_1.field_integer, }}, ] ) def test_parent_read_one2many(self): parent = self.Parent.create({ 'field_float': 13.37, 'field_one2many': [ (0, 0, {'data': 1}), (0, 0, {'data': 2}), (0, 0, {'data': 3}), ] }) parent_no_o2m = self.Parent.create({ 'field_float': 13.37, }) # Basic read self.assertEqual( parent._read_schema({ 'field_float': None, 'field_one2many': { 'data': None } }), [{ 'id': parent.id, 'field_float': 13.37, 'field_one2many': [ {'id': parent.field_one2many[0].id, 'data': 1}, {'id': parent.field_one2many[1].id, 'data': 2}, {'id': parent.field_one2many[2].id, 'data': 3}, ] }] ) self.assertEqual( parent_no_o2m._read_schema({ 'field_float': None, 'field_one2many': { 'data': None, }, }), [{ 'id': parent_no_o2m.id, 'field_float': 13.37, 'field_one2many': [], }] ) # Reading parent_id through field_one2many_computed is allowed since relationship is not known self.env.invalidate_all() schema = { 'field_float': None, 'field_one2many': { 'data': None, 'parent_id': { 'field_float': None, }, }, } self.assertEqual( parent._read_schema(schema), [{ 'id': parent.id, 'field_float': 13.37, 'field_one2many': [ {'id': parent.field_one2many[0].id, 'data': 1, 'parent_id': {'id': parent.id, 'field_float': 13.37}}, {'id': parent.field_one2many[1].id, 'data': 2, 'parent_id': {'id': parent.id, 'field_float': 13.37}}, {'id': parent.field_one2many[2].id, 'data': 3, 'parent_id': {'id': parent.id, 'field_float': 13.37}}, ] }] ) # It should not work with basic user with self.assertRaises(ValueError): parent.with_user(self.user_basic)._read_schema(schema) # It should however work with the computed version schema['field_one2many_computed'] = schema['field_one2many'] schema.pop('field_one2many') self.assertEqual( parent.with_user(self.user_basic)._read_schema(schema), [{ 'id': parent.id, 'field_float': 13.37, 'field_one2many_computed': [ {'id': parent.field_one2many[0].id, 'data': 1, 'parent_id': {'id': parent.id, 'field_float': 13.37}}, {'id': parent.field_one2many[1].id, 'data': 2, 'parent_id': {'id': parent.id, 'field_float': 13.37}}, {'id': parent.field_one2many[2].id, 'data': 3, 'parent_id': {'id': parent.id, 'field_float': 13.37}}, ] }] ) def test_parent_read_m2m(self): parent = self.Parent.create({ 'field_integer': 1, 'field_many2many': [ (0, 0, {'field_integer': 2}), ], }) other_parent = parent.field_many2many self.assertEqual( parent._read_schema({'field_integer': None, 'field_many2many': None}), [ {'id': parent.id, 'field_many2many': list(parent.field_many2many.ids), 'field_integer': 1}, ], ) self.env.invalidate_all() schema = { 'field_many2many_computed': { 'field_many2many_computed': { 'field_integer': None } } } self.assertEqual( parent._read_schema(schema), [ {'id': parent.id, 'field_many2many_computed': [ {'id': other_parent.id, 'field_many2many_computed': [ {'id': parent.id, 'field_integer': 1} ]} ]} ] ) with self.assertRaises(ValueError): self.assertEqual( parent.with_user(self.user_basic)._read_schema(schema), [ {'id': parent.id, 'field_many2many_computed': [ {'id': other_parent.id, 'field_many2many_computed': [ {'id': parent.id, 'field_integer': 1} ]} ]} ] ) def test_parent_read_cyclic_parent(self): parent_1 = self.Parent.create({ 'field_integer': 1, }) parent_2 = self.Parent.create({ 'field_integer': 2, 'field_many2one': parent_1.id, }) parent_1.field_many2one = parent_2 self.env.invalidate_all() both = (parent_1 | parent_2) self.assertEqual( both._read_schema({'field_many2one': None}), [ {'id': parent_1.id, 'field_many2one': parent_2.id}, {'id': parent_2.id, 'field_many2one': parent_1.id}, ] ) self.assertEqual( both.with_user(self.user_basic)._read_schema({'field_many2one': None}), [ {'id': parent_1.id, 'field_many2one': parent_2.id}, {'id': parent_2.id, 'field_many2one': parent_1.id}, ] ) schema = {'field_many2one': {'field_many2one': None}} self.assertEqual( both._read_schema(schema), [ {'id': parent_1.id, 'field_many2one': {'id': parent_2.id, 'field_many2one': parent_1.id}}, {'id': parent_2.id, 'field_many2one': {'id': parent_1.id, 'field_many2one': parent_2.id}}, ] ) with self.assertRaises(ValueError): self.assertEqual( both.with_user(self.user_basic)._read_schema(schema), [ {'id': parent_1.id, 'field_many2one': {'id': parent_2.id, 'field_many2one': parent_1.id}}, {'id': parent_2.id, 'field_many2one': {'id': parent_1.id, 'field_many2one': parent_2.id}}, ] )