# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 import json import pytest from pydantic import ValidationError from tests.context import CustomerModel def instantiate_customer(schema_version): """ utility method to instantiate customer model 1.0.0 with event passed as parameter v1.0.0 represents the current schema in use and is the baseline to detect breaking changes v1.1.0 to v1.4.0 represent changes from v1.0.0 """ sample_event_file = f"events/customerCreated-event-{schema_version}.json" with open(sample_event_file, "r", encoding="utf-8") as event: new_schema_event = json.load(event) return CustomerModel(**new_schema_event) def test_adding_optional_element_backward_compatible(): """ by default, Pydantic models ignore additional fields passed in any optional or mandatory new fields is not considered breaking schema change """ customer = instantiate_customer("1.1.0") with pytest.raises(AttributeError): assert customer.email == "jane@example.com", "Optional email not breaking change" def test_adding_required_element_backward_compatible(): """any optional or mandatory new fields is not considered breaking schema change""" customer = instantiate_customer("1.2.0") with pytest.raises(AttributeError): assert customer.name == "Jane Doe", "New mandatory name not breaking change" def test_removing_required_element_not_backward_compatible(): """missing mandatory field will raise a validation error""" with pytest.raises(Exception) as e_info: customer = instantiate_customer("1.3.0") assert e_info.type == ValidationError assert "field required" in str(e_info.value) assert "firstName" in str(e_info.value) assert "lastName" in str(e_info.value) def test_changing_business_logic_existing_field_backward_compatible(): """ schema test cannot catch changes to business logic in this case, the custoner address value was changed from a full address to just a street number this business logic change does not impact schema of event and hence test passes """ customer = instantiate_customer("1.4.0") assert customer.address == "2 Park St", "Street address not breaking schema change"