"""Unit tests for response schemas.""" import pytest from pydantic import ValidationError from file_upload_complete.schemas.responses import ProcessorResponse class TestProcessorResponse: """Tests for ProcessorResponse model.""" def test_valid_completed_response(self): """Test creating ProcessorResponse with completed status.""" api_response = {'message': 'File processed successfully'} response = ProcessorResponse( status='completed', fileKey='abc-123', apiResponse=api_response ) assert response.status == 'completed' assert response.fileKey == 'abc-123' assert response.apiResponse == api_response def test_valid_quarantined_response(self): """Test creating ProcessorResponse with quarantined status.""" api_response = {'message': 'File quarantined due to virus'} response = ProcessorResponse( status='quarantined', fileKey='def-456', apiResponse=api_response ) assert response.status == 'quarantined' assert response.fileKey == 'def-456' assert response.apiResponse == api_response def test_status_required(self): """Test ProcessorResponse requires status field.""" with pytest.raises(ValidationError) as exc_info: ProcessorResponse(fileKey='abc-123', apiResponse={}) errors = exc_info.value.errors() assert any(error['loc'] == ('status',) for error in errors) def test_file_key_required(self): """Test ProcessorResponse requires fileKey field.""" with pytest.raises(ValidationError) as exc_info: ProcessorResponse(status='completed', apiResponse={}) errors = exc_info.value.errors() assert any(error['loc'] == ('fileKey',) for error in errors) def test_api_response_required(self): """Test ProcessorResponse requires apiResponse field.""" with pytest.raises(ValidationError) as exc_info: ProcessorResponse(status='completed', fileKey='abc-123') errors = exc_info.value.errors() assert any(error['loc'] == ('apiResponse',) for error in errors) def test_invalid_status_value(self): """Test ProcessorResponse rejects invalid status values.""" with pytest.raises(ValidationError) as exc_info: ProcessorResponse( status='invalid_status', fileKey='abc-123', apiResponse={} ) errors = exc_info.value.errors() assert any(error['loc'] == ('status',) for error in errors) def test_api_response_with_dict(self): """Test ProcessorResponse with dict apiResponse.""" api_response = { 'id': '123', 'status': 'success', 'timestamp': '2024-01-01T12:00:00Z', } response = ProcessorResponse( status='completed', fileKey='abc-123', apiResponse=api_response ) assert response.apiResponse == api_response assert response.apiResponse['id'] == '123' def test_api_response_with_list(self): """Test ProcessorResponse with list apiResponse.""" api_response = ['item1', 'item2', 'item3'] response = ProcessorResponse( status='completed', fileKey='abc-123', apiResponse=api_response ) assert response.apiResponse == api_response assert len(response.apiResponse) == 3 def test_api_response_with_string(self): """Test ProcessorResponse with string apiResponse.""" api_response = 'Success message' response = ProcessorResponse( status='completed', fileKey='abc-123', apiResponse=api_response ) assert response.apiResponse == api_response def test_api_response_with_null(self): """Test ProcessorResponse with None apiResponse.""" response = ProcessorResponse( status='completed', fileKey='abc-123', apiResponse=None ) assert response.apiResponse is None def test_api_response_with_number(self): """Test ProcessorResponse with numeric apiResponse.""" response = ProcessorResponse( status='completed', fileKey='abc-123', apiResponse=42 ) assert response.apiResponse == 42 def test_dict_conversion(self): """Test ProcessorResponse can be converted to dict.""" response = ProcessorResponse( status='completed', fileKey='abc-123', apiResponse={'message': 'success'}, ) response_dict = response.model_dump() assert response_dict == { 'status': 'completed', 'fileKey': 'abc-123', 'apiResponse': {'message': 'success'}, } def test_json_serialization(self): """Test ProcessorResponse can be serialized to JSON.""" response = ProcessorResponse( status='quarantined', fileKey='def-456', apiResponse={'reason': 'infected'}, ) json_str = response.model_dump_json() assert isinstance(json_str, str) assert 'quarantined' in json_str assert 'def-456' in json_str def test_file_key_with_uuid_format(self): """Test ProcessorResponse with UUID-formatted file key.""" file_key = '550e8400-e29b-41d4-a716-446655440000' response = ProcessorResponse( status='completed', fileKey=file_key, apiResponse={} ) assert response.fileKey == file_key def test_file_key_with_special_characters(self): """Test ProcessorResponse with special characters in file key.""" file_key = 'file-key_123-abc' response = ProcessorResponse( status='completed', fileKey=file_key, apiResponse={} ) assert response.fileKey == file_key def test_completed_status_literal(self): """Test ProcessorResponse only accepts literal status values.""" # Valid values ProcessorResponse(status='completed', fileKey='abc', apiResponse={}) ProcessorResponse(status='quarantined', fileKey='def', apiResponse={}) # Invalid value should raise error with pytest.raises(ValidationError): ProcessorResponse(status='pending', fileKey='ghi', apiResponse={}) def test_api_response_with_nested_structure(self): """Test ProcessorResponse with deeply nested apiResponse.""" api_response = { 'data': { 'file': { 'id': '123', 'metadata': { 'size': 1024, 'type': 'csv', 'tags': ['processed', 'validated'], }, } }, 'status': 'success', } response = ProcessorResponse( status='completed', fileKey='abc-123', apiResponse=api_response ) assert response.apiResponse['data']['file']['id'] == '123' assert 'processed' in response.apiResponse['data']['file']['metadata']['tags'] def test_empty_file_key(self): """Test ProcessorResponse with empty string file key.""" response = ProcessorResponse(status='completed', fileKey='', apiResponse={}) assert response.fileKey == '' def test_api_response_empty_dict(self): """Test ProcessorResponse with empty dict apiResponse.""" response = ProcessorResponse(status='completed', fileKey='abc', apiResponse={}) assert response.apiResponse == {} def test_response_immutability_after_creation(self): """Test ProcessorResponse fields after creation.""" response = ProcessorResponse( status='completed', fileKey='abc-123', apiResponse={'test': 'data'} ) # Verify fields are accessible assert response.status == 'completed' assert response.fileKey == 'abc-123' assert response.apiResponse == {'test': 'data'}