From 457384d3e1f2af19822744b6a745d3decfa7c46c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arttu=20Per=C3=A4l=C3=A4?= Date: Tue, 4 Jul 2023 10:37:36 +0300 Subject: [PATCH] Handle dicts in validate_unique_items --- openapi_tester/validators.py | 8 +++++--- tests/test_validators.py | 22 +++++++++++++++++++++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/openapi_tester/validators.py b/openapi_tester/validators.py index 1f4ec559..4e0af329 100644 --- a/openapi_tester/validators.py +++ b/openapi_tester/validators.py @@ -2,6 +2,7 @@ from __future__ import annotations import base64 +import json import re from typing import TYPE_CHECKING from uuid import UUID @@ -147,9 +148,10 @@ def validate_minimum(schema_section: dict[str, Any], data: int | float) -> str | def validate_unique_items(schema_section: dict[str, Any], data: list[Any]) -> str | None: unique_items = schema_section.get("uniqueItems") - if unique_items and len(set(data)) != len(data): - return VALIDATE_UNIQUE_ITEMS_ERROR.format(data=data) - # TODO: handle deep dictionary comparison - for lists of dicts + if unique_items: + comparison_data = (json.dumps(item, sort_keys=True) if isinstance(item, dict) else item for item in data) + if len(set(comparison_data)) != len(data): + return VALIDATE_UNIQUE_ITEMS_ERROR.format(data=data) return None diff --git a/tests/test_validators.py b/tests/test_validators.py index 78c88a3c..7734a477 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -22,7 +22,7 @@ VALIDATE_TYPE_ERROR, ) from openapi_tester.exceptions import DocumentationError, OpenAPISchemaError -from openapi_tester.validators import VALIDATOR_MAP +from openapi_tester.validators import VALIDATOR_MAP, validate_unique_items from tests import ( example_response_types, example_schema_array, @@ -324,3 +324,23 @@ def test_is_nullable_oneof(): with pytest.raises(DocumentationError): tester.test_schema_section({"oneOf": [{"type": "object"}, {"type": "string"}]}, None) + + +def test_validate_unique_items_dict(): + # Only unique objects. + result = validate_unique_items( + {"uniqueItems": True}, + [{"id": 123, "type": "Potato"}, {"id": 234, "type": "Potato"}, {"type": "Tomato", "id": 123}], + ) + assert result is None + + # Repeated object (in reverse key order). + result = validate_unique_items( + {"uniqueItems": True}, + [{"id": 123, "type": "Potato"}, {"id": 234, "type": "Potato"}, {"type": "Potato", "id": 123}], + ) + assert ( + result + == "The array [{'id': 123, 'type': 'Potato'}, {'id': 234, 'type': 'Potato'}, " + "{'type': 'Potato', 'id': 123}] must contain unique items only" + )