diff --git a/packages/serialization/json/kiota_serialization_json/json_parse_node.py b/packages/serialization/json/kiota_serialization_json/json_parse_node.py index dda72087..45b023b5 100644 --- a/packages/serialization/json/kiota_serialization_json/json_parse_node.py +++ b/packages/serialization/json/kiota_serialization_json/json_parse_node.py @@ -351,7 +351,7 @@ def _assign_field_values(self, item: Parsable) -> None: if field_value is None: continue field_deserializer = field_deserializers[field_name] - field_deserializer(JsonParseNode(field_value)) + field_deserializer(self._create_new_node(field_value)) elif item_additional_data is not None: item_additional_data[field_name] = self.try_get_anything(field_value) else: diff --git a/packages/serialization/json/kiota_serialization_json/json_serialization_writer.py b/packages/serialization/json/kiota_serialization_json/json_serialization_writer.py index 695b6e98..036f458d 100644 --- a/packages/serialization/json/kiota_serialization_json/json_serialization_writer.py +++ b/packages/serialization/json/kiota_serialization_json/json_serialization_writer.py @@ -519,7 +519,7 @@ def _serialize_value(self, temp_writer: JsonSerializationWriter, value: U) -> No if on_before := self.on_before_object_serialization: on_before(value) if on_start := self.on_start_object_serialization: - on_start(value, self) + on_start(value, temp_writer) value.serialize(temp_writer) diff --git a/packages/serialization/json/tests/helpers/__init__.py b/packages/serialization/json/tests/helpers/__init__.py index f2c0b4a9..8e759d04 100644 --- a/packages/serialization/json/tests/helpers/__init__.py +++ b/packages/serialization/json/tests/helpers/__init__.py @@ -1,4 +1,5 @@ from .entity import Entity from .office_location import OfficeLocation +from .team import Team from .user import User from .user2 import User2 diff --git a/packages/serialization/json/tests/helpers/team.py b/packages/serialization/json/tests/helpers/team.py new file mode 100644 index 00000000..49c354d0 --- /dev/null +++ b/packages/serialization/json/tests/helpers/team.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from dataclasses import dataclass +from collections.abc import Callable +from typing import Optional + +from kiota_abstractions.serialization import Parsable, ParseNode, SerializationWriter + +from .user import User + + +@dataclass +class Team(Parsable): + lead: Optional[User] = None + + @staticmethod + def create_from_discriminator_value(parse_node: Optional[ParseNode] = None) -> Team: + return Team() + + def get_field_deserializers(self) -> dict[str, Callable[[ParseNode], None]]: + return {"lead": lambda n: setattr(self, 'lead', n.get_object_value(User))} + + def serialize(self, writer: SerializationWriter) -> None: + writer.write_object_value("lead", self.lead) diff --git a/packages/serialization/json/tests/unit/test_json_parse_node.py b/packages/serialization/json/tests/unit/test_json_parse_node.py index c5d59dc8..489874df 100644 --- a/packages/serialization/json/tests/unit/test_json_parse_node.py +++ b/packages/serialization/json/tests/unit/test_json_parse_node.py @@ -4,7 +4,7 @@ import pytest from kiota_serialization_json.json_parse_node import JsonParseNode -from ..helpers import OfficeLocation, User +from ..helpers import OfficeLocation, Team, User def test_get_str_value(): @@ -363,3 +363,13 @@ def test_get_collection_of_object_values(users_json): assert result[0].business_phones == ["+1 205 555 0108"] assert result[0].is_active is True assert result[0].mobile_phone is None + + +def test_hooks_run_for_nested_objects(): + seen = [] + parse_node = JsonParseNode(json.loads('{"lead": {"mobile_phone": "+1 234 567 891"}}')) + parse_node.on_before_assign_field_values = lambda value: seen.append(type(value).__name__) + parse_node.on_after_assign_field_values = lambda value: seen.append(type(value).__name__) + team = parse_node.get_object_value(Team) + assert team.lead.mobile_phone == "+1 234 567 891" + assert seen == ["Team", "User", "User", "Team"] diff --git a/packages/serialization/json/tests/unit/test_json_serialization_writer.py b/packages/serialization/json/tests/unit/test_json_serialization_writer.py index d115c1bc..69ef56e6 100644 --- a/packages/serialization/json/tests/unit/test_json_serialization_writer.py +++ b/packages/serialization/json/tests/unit/test_json_serialization_writer.py @@ -6,7 +6,7 @@ from kiota_serialization_json.json_serialization_writer import JsonSerializationWriter -from ..helpers import OfficeLocation, User, User2 +from ..helpers import OfficeLocation, Team, User, User2 @pytest.fixture @@ -353,3 +353,25 @@ def test_write_composed_type_with_no_key(user_1): # The union type should serialize the inner user object, not an empty object assert content_string == '{"id": "8f841f30-e6e3-439a-a812-ebd369559c36", '\ '"updated_at": "2022-01-27T12:59:45.596117+00:00", "is_active": true}' + + +def clear_is_active(value, writer): + if isinstance(value, User): + writer.write_null_value("is_active") + + +def test_on_start_writes_into_the_root_object(): + json_serialization_writer = JsonSerializationWriter() + json_serialization_writer.on_start_object_serialization = clear_is_active + json_serialization_writer.write_object_value(None, User(mobile_phone="+1 234 567 891")) + content = json_serialization_writer.get_serialized_content() + assert json.loads(content) == {"is_active": None, "mobile_phone": "+1 234 567 891"} + + +def test_on_start_writes_into_the_nested_object(): + json_serialization_writer = JsonSerializationWriter() + json_serialization_writer.on_start_object_serialization = clear_is_active + team = Team(lead=User(mobile_phone="+1 234 567 891")) + json_serialization_writer.write_object_value(None, team) + content = json_serialization_writer.get_serialized_content() + assert json.loads(content) == {"lead": {"is_active": None, "mobile_phone": "+1 234 567 891"}}