"""Unit tests for validation pipeline""" import pytest from dss.models.project import Project from dss.models.theme import Theme, DesignToken, TokenCategory from dss.validators.schema import ProjectValidator, ValidationError, ValidationStage @pytest.mark.unit class TestProjectValidator: """Test project validation pipeline""" def test_validate_valid_project(self, valid_project_data): """Test validation passes for valid project""" validator = ProjectValidator() result = validator.validate(valid_project_data) assert result.is_valid is True assert len(result.errors) == 0 assert result.stage == ValidationStage.COMPLETE def test_validate_missing_required_field(self): """Test validation fails when required field is missing""" invalid_data = { "name": "Test Project", # Missing 'id' field "theme": { "name": "Test Theme", "tokens": {} } } validator = ProjectValidator() result = validator.validate(invalid_data) assert result.is_valid is False assert len(result.errors) > 0 assert any("id" in str(err).lower() for err in result.errors) def test_validate_invalid_token_value(self): """Test validation fails for invalid token values""" invalid_data = { "id": "test-project", "name": "Test Project", "theme": { "name": "Test Theme", "tokens": { "primary": { "name": "primary", "value": "", # Empty value is invalid "type": "color", "category": "color" } } } } validator = ProjectValidator() result = validator.validate(invalid_data) assert result.is_valid is False assert ValidationStage.TOKEN_VALIDATION in [err.stage for err in result.errors] def test_validate_token_reference(self): """Test validation of token references""" data_with_ref = { "id": "test-project", "name": "Test Project", "theme": { "name": "Test Theme", "tokens": { "primary": { "name": "primary", "value": "oklch(0.65 0.18 250)", "type": "color", "category": "color" }, "primary-dark": { "name": "primary-dark", "value": "{primary}", # Reference to primary token "type": "color", "category": "color" } } } } validator = ProjectValidator() result = validator.validate(data_with_ref) # Should pass - valid reference assert result.is_valid is True def test_validate_broken_token_reference(self): """Test validation fails for broken token reference""" data_with_broken_ref = { "id": "test-project", "name": "Test Project", "theme": { "name": "Test Theme", "tokens": { "primary": { "name": "primary", "value": "{nonexistent}", # Reference to nonexistent token "type": "color", "category": "color" } } } } validator = ProjectValidator() result = validator.validate(data_with_broken_ref) assert result.is_valid is False assert any("reference" in str(err).lower() for err in result.errors) def test_validate_component_dependencies(self): """Test validation of component dependencies""" data = { "id": "test-project", "name": "Test Project", "theme": { "name": "Test Theme", "tokens": {} }, "components": [ { "name": "Card", "source": "shadcn", "dependencies": ["Button"] # Depends on Button component }, { "name": "Button", "source": "shadcn" } ] } validator = ProjectValidator() result = validator.validate(data) # Should pass - Button exists assert result.is_valid is True def test_validate_missing_component_dependency(self): """Test validation fails for missing component dependency""" data = { "id": "test-project", "name": "Test Project", "theme": { "name": "Test Theme", "tokens": {} }, "components": [ { "name": "Card", "source": "shadcn", "dependencies": ["NonexistentComponent"] } ] } validator = ProjectValidator() result = validator.validate(data) assert result.is_valid is False assert any("dependency" in str(err).lower() for err in result.errors) def test_validation_stages_order(self): """Test validation stages execute in correct order""" # Data that fails at schema stage invalid_schema = {"invalid": "structure"} validator = ProjectValidator() result = validator.validate(invalid_schema) # Should fail at schema stage and not proceed assert result.is_valid is False assert result.stage == ValidationStage.SCHEMA def test_validate_token_category_enum(self): """Test validation accepts valid token categories""" data = { "id": "test-project", "name": "Test Project", "theme": { "name": "Test Theme", "tokens": { "space-md": { "name": "space-md", "value": "16px", "type": "dimension", "category": "spacing" # Valid category } } } } validator = ProjectValidator() result = validator.validate(data) assert result.is_valid is True def test_validate_component_variants(self): """Test validation of component variants""" data = { "id": "test-project", "name": "Test Project", "theme": { "name": "Test Theme", "tokens": {} }, "components": [ { "name": "Button", "source": "shadcn", "variants": ["default", "outline", "ghost", "destructive"] } ] } validator = ProjectValidator() result = validator.validate(data) assert result.is_valid is True @pytest.mark.unit class TestValidationResult: """Test ValidationResult model""" def test_create_valid_result(self): """Test creating a valid validation result""" from dss.validators.schema import ValidationResult result = ValidationResult( is_valid=True, stage=ValidationStage.COMPLETE, errors=[] ) assert result.is_valid is True assert result.stage == ValidationStage.COMPLETE assert len(result.errors) == 0 def test_create_invalid_result_with_errors(self): """Test creating invalid result with errors""" from dss.validators.schema import ValidationResult, ValidationError error = ValidationError( stage=ValidationStage.SCHEMA, message="Missing required field: id", field="id" ) result = ValidationResult( is_valid=False, stage=ValidationStage.SCHEMA, errors=[error] ) assert result.is_valid is False assert len(result.errors) == 1 assert result.errors[0].field == "id"