"""Tests for company name input validation on analysis endpoints.""" from datetime import datetime from unittest.mock import Mock import pytest from fastapi.testclient import TestClient from SPARC.api import app from SPARC.types import CompanyAnalysisResult @pytest.fixture def client(): """Create test client.""" return TestClient(app) @pytest.fixture def mock_analyzer(mocker): """Mock the global analyzer so valid requests succeed.""" mock = Mock() mock._analyze_company_safe.return_value = CompanyAnalysisResult( company_name="nvidia", analysis="Test analysis", patent_count=1, success=True, timestamp=datetime.now(), ) mocker.patch("SPARC.api._analyzer", mock) return mock class TestCompanyNameValidation: """Test that company names are validated on analysis endpoints.""" # --- Too short --- def test_single_char_rejected(self, client, mock_analyzer): """A one-character company name should be rejected.""" response = client.get("/analyze/X") assert response.status_code == 422 # --- Too long --- def test_over_128_chars_rejected(self, client, mock_analyzer): """A company name longer than 128 characters should be rejected.""" long_name = "A" * 129 response = client.get(f"/analyze/{long_name}") assert response.status_code == 422 def test_exactly_128_chars_accepted(self, client, mock_analyzer): """A company name of exactly 128 characters should be accepted.""" max_name = "A" * 128 response = client.get(f"/analyze/{max_name}") assert response.status_code != 422 # --- Special characters --- @pytest.mark.parametrize( "bad_name", [ "nvidia!", "intel@corp", "test#company", "foo$bar", "a%b", "x^y", "semi;colon", "drop'table", 'say"hello', "path/traversal", "back\\slash", "pipe|char", "star*glob", "question?mark", "