mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-18 08:52:02 +02:00
279 lines
11 KiB
Python
279 lines
11 KiB
Python
# Copyright 2021 Wakari SRL
|
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)
|
|
from marshmallow import fields
|
|
|
|
from odoo import SUPERUSER_ID, fields as odoo_fields
|
|
from odoo.exceptions import ValidationError
|
|
|
|
from odoo.addons.datamodel.fields import NestedModel
|
|
from odoo.addons.datamodel.tests.common import DatamodelRegistryCase
|
|
|
|
from ..core import ModelSerializer
|
|
from ..field_converter import Binary
|
|
from ..serializers import GenericMinimalSerializer
|
|
|
|
|
|
def _schema_field(model_serializer_cls, field_name):
|
|
schema_cls = model_serializer_cls.__schema_class__
|
|
return schema_cls._declared_fields.get(field_name)
|
|
|
|
|
|
class TestModelSerializer(DatamodelRegistryCase):
|
|
"""Test build of ModelSerializer"""
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self._full_build_model_serializer(GenericMinimalSerializer)
|
|
|
|
def _full_build_model_serializer(self, model_serializer_cls):
|
|
model_serializer_cls._build_datamodel(self.datamodel_registry)
|
|
new_cls = model_serializer_cls._extend_from_odoo_model(
|
|
self.datamodel_registry, self.env
|
|
)
|
|
new_cls._build_datamodel(self.datamodel_registry)
|
|
return self.env.datamodels[model_serializer_cls._name]
|
|
|
|
def _datamodel_instance(self, serializer_cls, values):
|
|
datamodel_cls = self._full_build_model_serializer(serializer_cls)
|
|
instance = datamodel_cls(partial=True)
|
|
for key in values:
|
|
setattr(instance, key, values[key])
|
|
return instance
|
|
|
|
def test_01_required_attrs(self):
|
|
"""Ensure that ModelSerializer has mandatory attributes"""
|
|
msg = ".*require '_model' and '_model_fields' attributes.*"
|
|
with self.assertRaisesRegex(ValidationError, msg):
|
|
|
|
class ModelSerializerBad1(ModelSerializer):
|
|
_name = "modelserializer_no_model"
|
|
|
|
self._full_build_model_serializer(ModelSerializerBad1)
|
|
|
|
with self.assertRaisesRegex(ValidationError, msg):
|
|
|
|
class ModelSerializerBad2(ModelSerializer):
|
|
_name = "modelserializer_no_model_fields"
|
|
_model = "res.partner"
|
|
|
|
self._full_build_model_serializer(ModelSerializerBad2)
|
|
|
|
def test_02_has_field(self):
|
|
"""Ensure that ModelSerializers have the generated fields"""
|
|
|
|
class ModelSerializer1(ModelSerializer):
|
|
_name = "modelserializer1"
|
|
_model = "res.partner"
|
|
_model_fields = ["id"]
|
|
|
|
class ModelSerializer2(ModelSerializer):
|
|
_name = "modelserializer2"
|
|
_inherit = "modelserializer1"
|
|
|
|
for serializer_class in (ModelSerializer1, ModelSerializer2):
|
|
full_cls = self._full_build_model_serializer(serializer_class)
|
|
self.assertTrue(hasattr(full_cls, "id"))
|
|
self.assertIsInstance(_schema_field(full_cls, "id"), fields.Integer)
|
|
|
|
def test_03_simple_field_converter(self):
|
|
"""Ensure that non-relational fields are correctly converted"""
|
|
|
|
fields_conversion = {
|
|
"id": (odoo_fields.Id, fields.Integer, {"dump_only": True}),
|
|
"create_date": (odoo_fields.Datetime, fields.DateTime, {"dump_only": True}),
|
|
"date": (
|
|
odoo_fields.Date,
|
|
fields.Date,
|
|
{"required": False, "allow_none": True},
|
|
),
|
|
"name": (
|
|
odoo_fields.Char,
|
|
fields.String,
|
|
{"required": False, "allow_none": True},
|
|
),
|
|
"comment": (
|
|
odoo_fields.Text,
|
|
fields.String,
|
|
{"required": False, "allow_none": True},
|
|
),
|
|
"active": (
|
|
odoo_fields.Boolean,
|
|
fields.Boolean,
|
|
{"required": False, "allow_none": True},
|
|
),
|
|
"partner_latitude": (
|
|
odoo_fields.Float,
|
|
fields.Float,
|
|
{"required": False, "allow_none": True},
|
|
),
|
|
"active_lang_count": (
|
|
odoo_fields.Integer,
|
|
fields.Integer,
|
|
{"dump_only": True},
|
|
),
|
|
"image_1920": (
|
|
odoo_fields.Image,
|
|
Binary,
|
|
{"required": False, "allow_none": True},
|
|
),
|
|
}
|
|
|
|
class PartnerSerializer(ModelSerializer):
|
|
_name = "partner_serializer"
|
|
_model = "res.partner"
|
|
_model_fields = list(fields_conversion)
|
|
|
|
full_cls = self._full_build_model_serializer(PartnerSerializer)
|
|
for field_name in fields_conversion:
|
|
odoo_field_cls, marsh_field_cls, attrs = fields_conversion[field_name]
|
|
this_field = _schema_field(full_cls, field_name)
|
|
self.assertIsInstance(this_field, marsh_field_cls)
|
|
for attr, attr_val in attrs.items():
|
|
msg = (
|
|
"Error when converting field {}, wrong "
|
|
"attribute value ('{}' should be '{}')".format(
|
|
field_name, attr, attr_val
|
|
),
|
|
)
|
|
self.assertEqual(getattr(this_field, attr), attr_val, msg=msg)
|
|
|
|
def test_04_relational_field_converter(self):
|
|
"""Ensure that relational fields are correctly converted"""
|
|
|
|
class PartnerSerializer(ModelSerializer):
|
|
_name = "partner_serializer"
|
|
_model = "res.partner"
|
|
_model_fields = ["user_id"]
|
|
|
|
full_cls = self._full_build_model_serializer(PartnerSerializer)
|
|
user_field = _schema_field(full_cls, "user_id")
|
|
self.assertIsInstance(user_field, NestedModel)
|
|
self.assertEqual(user_field.datamodel_name, "generic.minimal.serializer")
|
|
self.assertFalse(user_field.many)
|
|
|
|
def test_05_from_recordset(self):
|
|
"""Test `from_recordset` method with only simple fields"""
|
|
|
|
class PartnerSerializer(ModelSerializer):
|
|
_name = "partner_serializer"
|
|
_model = "res.partner"
|
|
_model_fields = ["id", "name"]
|
|
|
|
datamodel_cls = self._full_build_model_serializer(PartnerSerializer)
|
|
self.partner = self.env["res.partner"].create({"name": "Test Partner"})
|
|
datamodel = datamodel_cls.from_recordset(self.partner)
|
|
self.assertIsInstance(datamodel, datamodel_cls)
|
|
self.assertEqual(datamodel.id, self.partner.id)
|
|
self.assertEqual(datamodel.name, self.partner.name)
|
|
self.assertEqual(
|
|
set(PartnerSerializer._model_fields),
|
|
set(datamodel.__schema__.fields.keys()),
|
|
)
|
|
|
|
def test_06_from_recordset_nested(self):
|
|
"""Test `from_recordset` method with nested fields, default nested serializer"""
|
|
|
|
class PartnerSerializer(ModelSerializer):
|
|
_name = "partner_serializer"
|
|
_model = "res.partner"
|
|
_model_fields = ["user_id"]
|
|
|
|
datamodel_cls = self._full_build_model_serializer(PartnerSerializer)
|
|
self.partner = self.env["res.partner"].create({"name": "Test Partner"})
|
|
datamodel1 = datamodel_cls.from_recordset(self.partner)
|
|
self.assertIsInstance(datamodel1, datamodel_cls)
|
|
self.assertEqual(datamodel1.user_id, None)
|
|
self.partner.write({"user_id": SUPERUSER_ID})
|
|
datamodel2 = datamodel_cls.from_recordset(self.partner)
|
|
self.assertIsInstance(datamodel2, datamodel_cls)
|
|
self.assertEqual(datamodel2.user_id.id, SUPERUSER_ID)
|
|
self.assertEqual(
|
|
datamodel2.user_id.display_name, self.partner.user_id.display_name
|
|
)
|
|
self.assertEqual(
|
|
set(PartnerSerializer._model_fields),
|
|
set(datamodel2.__schema__.fields.keys()),
|
|
)
|
|
|
|
def test_07_from_recordset_nested_custom(self):
|
|
"""Test `from_recordset` method with nested fields, custom nested serializer"""
|
|
|
|
class PartnerSerializer(ModelSerializer):
|
|
_name = "partner_serializer"
|
|
_model = "res.partner"
|
|
_model_fields = ["user_id"]
|
|
|
|
user_id = NestedModel("user_serializer")
|
|
|
|
class UserSerializer(ModelSerializer):
|
|
_name = "user_serializer"
|
|
_model = "res.users"
|
|
_model_fields = ["login"]
|
|
|
|
user_dm_cls = self._full_build_model_serializer(UserSerializer)
|
|
datamodel_cls = self._full_build_model_serializer(PartnerSerializer)
|
|
user_field = _schema_field(datamodel_cls, "user_id")
|
|
self.assertEqual(user_field.datamodel_name, "user_serializer")
|
|
self.partner = self.env["res.partner"].create(
|
|
{"name": "Test Partner", "user_id": SUPERUSER_ID}
|
|
)
|
|
datamodel = datamodel_cls.from_recordset(self.partner)
|
|
self.assertIsInstance(datamodel.user_id, user_dm_cls)
|
|
self.assertEqual(datamodel.user_id.login, self.partner.user_id.login)
|
|
self.assertEqual(
|
|
set(UserSerializer._model_fields),
|
|
set(datamodel.user_id.__schema__.fields.keys()),
|
|
)
|
|
|
|
def test_08_to_recordset_write(self):
|
|
"""Test `to_recordset` method with only simple fields, existing partner"""
|
|
|
|
class PartnerSerializer(ModelSerializer):
|
|
_name = "partner_serializer"
|
|
_model = "res.partner"
|
|
_model_fields = ["id", "name"]
|
|
|
|
self.partner = self.env["res.partner"].create({"name": "Test Partner"})
|
|
datamodel = self._datamodel_instance(
|
|
PartnerSerializer,
|
|
{"id": self.partner.id, "name": self.partner.name + "New"},
|
|
)
|
|
new_partner = datamodel.to_recordset()
|
|
self.assertEqual(new_partner, self.partner)
|
|
self.assertEqual(new_partner.name, datamodel.name)
|
|
|
|
def test_09_to_recordset_relational_write(self):
|
|
"""Test `to_recordset` method with relational fields, existing partner"""
|
|
|
|
class PartnerSerializer(ModelSerializer):
|
|
_name = "partner_serializer"
|
|
_model = "res.partner"
|
|
_model_fields = ["id", "name", "child_ids"]
|
|
|
|
self.partner = self.env["res.partner"].create({"name": "Test Partner"})
|
|
self.child_partner = self.env["res.partner"].create(
|
|
{"name": "Test Child Partner"}
|
|
)
|
|
datamodel_child = self._datamodel_instance(
|
|
PartnerSerializer,
|
|
{"id": self.child_partner.id, "name": self.child_partner.name + "New"},
|
|
)
|
|
datamodel_child2 = self._datamodel_instance(
|
|
PartnerSerializer,
|
|
{"name": "Newly Created Partner"},
|
|
)
|
|
datamodel = self._datamodel_instance(
|
|
PartnerSerializer,
|
|
{
|
|
"id": self.partner.id,
|
|
"name": self.partner.name + "New",
|
|
"child_ids": [datamodel_child, datamodel_child2],
|
|
},
|
|
)
|
|
new_partner = datamodel.to_recordset()
|
|
new_partner_child = new_partner.child_ids.filtered(
|
|
lambda p: p.id == self.child_partner.id
|
|
)
|
|
self.assertTrue(bool(new_partner_child))
|
|
self.assertEqual(new_partner_child.name, datamodel_child.name)
|
|
self.assertTrue("Newly Created Partner" in new_partner.child_ids.mapped("name"))
|