"""Infra schema tests.""" from typing import Any, Dict, Optional import pytest from pdp.constants.constants import CacheEntryType from pdp.fastapi.schemas.infra import ( BludgeonCacheRequest, BludgeonCacheResponse, BustCacheRequest, BustCacheResponse, BustCacheResult, CacheItem, CacheResult, ListCacheRequest, ListCacheResponse, ) @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ({}, True, None, "Missing key and value"), ({"key": [], "value": {}}, True, None, "Key should be a string"), ({"key": "something"}, True, None, "Missing value"), ( {"key": "something", "value": {}}, False, {"key": "something", "value": {}}, "Valid cache result", ), ], ) def test_cache_result( payload: Optional[Dict[str, Any]], expect_exception: bool, expected: Dict[str, Any], description: str, ) -> None: """Test the CacheResult model.""" if expect_exception: with pytest.raises(Exception): CacheResult.model_validate(payload) else: actual = CacheResult.model_validate(payload) assert actual == CacheResult(**expected), description @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ({}, True, None, "Missing keys"), ({"keys": []}, True, None, "Keys should not be empty list"), ({"keys": [{}]}, True, None, "Keys should be a list of strings"), ( { "keys": ["something"], }, False, { "keys": ["something"], }, "Valid list cache request", ), ], ) def test_list_cache_request( payload: Optional[Dict[str, Any]], expect_exception: bool, expected: Dict[str, Any], description: str, ) -> None: """Test the ListCacheRequest model.""" if expect_exception: with pytest.raises(Exception): ListCacheRequest.model_validate(payload) else: actual = ListCacheRequest.model_validate(payload) assert actual == ListCacheRequest(**expected), description @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ({}, True, None, "Missing items"), ({"items": [{}]}, True, None, "Keys should be a list of CacheResult"), ( { "items": [{"key": "something", "value": {}}], }, False, { "items": [{"key": "something", "value": {}}], }, "Valid list cache response", ), ], ) def test_list_cache_response( payload: Optional[Dict[str, Any]], expect_exception: bool, expected: Dict[str, Any], description: str, ) -> None: """Test the ListCacheResponse model.""" if expect_exception: with pytest.raises(Exception): ListCacheResponse.model_validate(payload) else: actual = ListCacheResponse.model_validate(payload) assert actual == ListCacheResponse(**expected), description @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ({}, True, None, "Missing key, value, and deleted"), ( {"key": [], "value": {}, "deleted": True}, True, None, "Key should be a string", ), ({"key": "something", "deleted": True}, True, None, "Missing value"), ({"key": "something", "value": {}}, True, None, "Missing deleted"), ( {"key": "something", "value": {}, "deleted": True}, False, {"key": "something", "value": {}, "deleted": True}, "Valid bust cache result", ), ], ) def test_bust_cache_result( payload: Optional[Dict[str, Any]], expect_exception: bool, expected: Dict[str, Any], description: str, ) -> None: """Test the BustCacheResult model.""" if expect_exception: with pytest.raises(Exception): BustCacheResult.model_validate(payload) else: actual = BustCacheResult.model_validate(payload) assert actual == BustCacheResult(**expected), description @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ({}, True, None, "Missing keys"), ({"keys": []}, True, None, "Keys should not be empty list"), ({"keys": [{}]}, True, None, "Keys should be a list of strings"), ( { "keys": ["something"], }, False, { "keys": ["something"], }, "Valid bust cache request", ), ], ) def test_bust_cache_request( payload: Optional[Dict[str, Any]], expect_exception: bool, expected: Dict[str, Any], description: str, ) -> None: """Test the BustCacheRequest model.""" if expect_exception: with pytest.raises(Exception): BustCacheRequest.model_validate(payload) else: actual = BustCacheRequest.model_validate(payload) assert actual == BustCacheRequest(**expected), description @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ({}, True, None, "Missing items"), ({"items": [{}]}, True, None, "Keys should be a list of BustCacheResult"), ( { "items": [{"key": "something", "value": {}, "deleted": True}], }, False, { "items": [{"key": "something", "value": {}, "deleted": True}], }, "Valid bust cache response", ), ], ) def test_bust_cache_response( payload: Optional[Dict[str, Any]], expect_exception: bool, expected: Dict[str, Any], description: str, ) -> None: """Test the BustCacheResponse model.""" if expect_exception: with pytest.raises(Exception): BustCacheResponse.model_validate(payload) else: actual = BustCacheResponse.model_validate(payload) assert actual == BustCacheResponse(**expected), description @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ({"any key": {}}, False, {"any key": {}}, "Type Any includes a dict"), ( { "tenant_hierarchy_fff741c2-6def-4493-bfdf-c2bcb1128e02": { "vendor_id": 6971, "uuid": "fff741c2-6def-4493-bfdf-c2bcb1128e02", "company_brand_uuid": "d25a4cd1-e820-45f2-be5c-56edcfeb8298", "parent_company_uuid": "955a1bbd-b623-4ea1-ab5f-8d6620c442fb", } }, False, { "tenant_hierarchy_fff741c2-6def-4493-bfdf-c2bcb1128e02": { "vendor_id": 6971, "uuid": "fff741c2-6def-4493-bfdf-c2bcb1128e02", "company_brand_uuid": "d25a4cd1-e820-45f2-be5c-56edcfeb8298", "parent_company_uuid": "955a1bbd-b623-4ea1-ab5f-8d6620c442fb", } }, "Type Any includes a tenant hierarchy", ), ( "a string", False, "a string", "Type Any includes strings", ), ([], False, [], "Type Any includes lists"), (None, False, None, "Type Any includes None"), (2, False, 2, "Type Any includes numbers"), ], ) def test_cache_item( payload: Optional[Dict[str, Any]], expect_exception: bool, expected: Optional[Dict[str, Any]], description: str, ) -> None: """Test the CacheItem model.""" if expect_exception: with pytest.raises(Exception): CacheItem.model_validate(payload) else: actual = CacheItem.model_validate(payload) assert actual == CacheItem(root=expected), description @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ({}, True, None, "Missing cache_entry_type"), ({"cache_entry_type": "no.such.type"}, True, None, "Invalid cache_entry_type"), ( { "cache_entry_type": CacheEntryType.CACHE_ENTRY_TENANT_HIERARCHY.value, "delete": "invalid.for.bool.field", }, True, None, "Invalid `delete` field value.", ), ( { "cache_entry_type": CacheEntryType.CACHE_ENTRY_TENANT_HIERARCHY.value, "delete": True, }, False, {"cache_entry_type": CacheEntryType.CACHE_ENTRY_TENANT_HIERARCHY.value}, "Valid cache_entry_type and delete field values.", ), ], ) def test_bludgeon_cache_request( payload: Optional[Dict[str, Any]], expect_exception: bool, expected: Optional[Dict[str, Any]], description: str, ) -> None: """Test the BludgeonCacheRequest model.""" if expect_exception: with pytest.raises(Exception): BludgeonCacheRequest.model_validate(payload) else: actual = BludgeonCacheRequest.model_validate(payload) assert actual == BludgeonCacheRequest.model_validate(payload) @pytest.mark.parametrize( "payload, expect_exception, expected, description", [ ({}, True, None, "Missing all fields"), ( {"total_rows_before_delete": 0, "total_rows_affected": 0}, True, None, "Missing performed_delete", ), ( {"total_rows_before_delete": 0, "performed_delete": 0}, True, None, "Missing total_rows_affected", ), ( {"total_rows_affected": 0, "performed_delete": 0}, True, None, "Missing total_rows_before_delete", ), ( { "total_rows_before_delete": 0, "total_rows_affected": 0, "performed_delete": 0, }, False, { "total_rows_before_delete": 0, "total_rows_affected": 0, "performed_delete": 0, }, "Has all fields.", ), ], ) def test_bludgeon_cache_response( payload: Optional[Dict[str, Any]], expect_exception: bool, expected: Optional[Dict[str, Any]], description: str, ) -> None: """Test the BludgeonCacheRequest model.""" if expect_exception: with pytest.raises(Exception): BludgeonCacheResponse.model_validate(payload) else: actual = BludgeonCacheResponse.model_validate(payload) assert actual == BludgeonCacheResponse.model_validate(payload)