#!/usr/bin/env python # -*- coding: utf-8 -*- """ JSON Schema Validator Test Module Unit tests for ddms_compliance_suite.json_schema_validator.validator module, validates JSON data against schema definitions. """ import os import sys import unittest import json from unittest import mock from pathlib import Path # Add project root to Python path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) # Import classes and functions to test from ddms_compliance_suite.json_schema_validator.validator import JSONSchemaValidator from ddms_compliance_suite.models.rule_models import JSONSchemaDefinition, RuleCategory, TargetType class TestJSONSchemaValidator(unittest.TestCase): """JSON Schema Validator Test Class""" def setUp(self): """Setup before tests""" # Create validator instance self.validator = JSONSchemaValidator() # Test schema definition self.well_schema = { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "required": ["wellName", "wellID", "status", "coordinates"], "properties": { "wellName": { "type": "string", "description": "Well name" }, "wellID": { "type": "string", "pattern": "^W[0-9]{10}$", "description": "Well unique identifier, must be W followed by 10 digits" }, "status": { "type": "string", "enum": ["active", "inactive", "abandoned", "suspended"], "description": "Current well status" }, "coordinates": { "type": "object", "required": ["longitude", "latitude"], "properties": { "longitude": { "type": "number", "minimum": -180, "maximum": 180, "description": "Longitude coordinate" }, "latitude": { "type": "number", "minimum": -90, "maximum": 90, "description": "Latitude coordinate" } } } } } # Create a schema rule self.schema_rule = JSONSchemaDefinition( id="well-data-schema", name="Well Data Schema", description="Defines JSON structure for well data", category=RuleCategory.JSON_SCHEMA, version="1.0.0", target_type=TargetType.DATA_OBJECT, target_identifier="Well", schema_content=self.well_schema ) def test_valid_data(self): """Test that valid data passes validation""" # Valid test data valid_data = { "wellName": "Test Well-01", "wellID": "W0123456789", "status": "active", "coordinates": { "longitude": 116.3833, "latitude": 39.9167 } } # Validate result = self.validator.validate(valid_data, self.well_schema) # Assert self.assertTrue(result.is_valid) self.assertEqual(len(result.errors), 0) def test_missing_required_field(self): """Test missing required field scenario""" # Data missing required field invalid_data = { "wellName": "Test Well-01", "wellID": "W0123456789", # Missing status field "coordinates": { "longitude": 116.3833, "latitude": 39.9167 } } # Validate result = self.validator.validate(invalid_data, self.well_schema) # Assert self.assertFalse(result.is_valid) self.assertTrue(any("status" in error for error in result.errors)) def test_invalid_pattern(self): """Test field with invalid pattern""" # Data with invalid wellID format invalid_data = { "wellName": "Test Well-01", "wellID": "ABCDEFGHIJK", # Does not match W + 10 digits pattern "status": "active", "coordinates": { "longitude": 116.3833, "latitude": 39.9167 } } # Validate result = self.validator.validate(invalid_data, self.well_schema) # Assert self.assertFalse(result.is_valid) self.assertTrue(any("pattern" in error for error in result.errors)) def test_invalid_enum(self): """Test value not in enum""" # Data with status not in enum list invalid_data = { "wellName": "Test Well-01", "wellID": "W0123456789", "status": "unknown", # Not in enum list "coordinates": { "longitude": 116.3833, "latitude": 39.9167 } } # Validate result = self.validator.validate(invalid_data, self.well_schema) # Assert self.assertFalse(result.is_valid) self.assertTrue(any("enum" in error for error in result.errors)) def test_invalid_number_range(self): """Test number out of range""" # Data with longitude out of range invalid_data = { "wellName": "Test Well-01", "wellID": "W0123456789", "status": "active", "coordinates": { "longitude": 200.0, # Outside [-180, 180] range "latitude": 39.9167 } } # Validate result = self.validator.validate(invalid_data, self.well_schema) # Assert self.assertFalse(result.is_valid) self.assertTrue(any("maximum" in error for error in result.errors)) def test_validate_with_rule(self): """Test validation using rule object""" # Valid test data valid_data = { "wellName": "Test Well-01", "wellID": "W0123456789", "status": "active", "coordinates": { "longitude": 116.3833, "latitude": 39.9167 } } # Validate using rule object result = self.validator.validate_with_rule(valid_data, self.schema_rule) # Assert self.assertTrue(result.is_valid) self.assertEqual(len(result.errors), 0) def test_additional_properties(self): """Test handling of additional properties""" # Create a schema that prohibits additional properties strict_schema = dict(self.well_schema) strict_schema["additionalProperties"] = False # Data with extra property data_with_extra = { "wellName": "Test Well-01", "wellID": "W0123456789", "status": "active", "coordinates": { "longitude": 116.3833, "latitude": 39.9167 }, "extra_field": "Extra Field" # Extra field } # Validate result = self.validator.validate(data_with_extra, strict_schema) # Assert self.assertFalse(result.is_valid) self.assertTrue(any("additionalProperties" in error for error in result.errors)) if __name__ == "__main__": unittest.main()