Spaces:
Sleeping
Sleeping
| """ | |
| Test suite for FitScore Feedback Agent | |
| """ | |
| import pytest | |
| import sys | |
| import os | |
| from unittest.mock import Mock, patch | |
| from fastapi.testclient import TestClient | |
| # Add src to path | |
| sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'src')) | |
| from src.agent import FitScoreFeedbackAgent | |
| from src.models import CandidateRequest, FeedbackRequest | |
| class TestFitScoreFeedbackAgent: | |
| """Test cases for FitScore Feedback Agent""" | |
| def agent(self): | |
| """Create a test agent instance""" | |
| config = { | |
| "host": "0.0.0.0", | |
| "port": 8001, | |
| "debug": True, | |
| "database_url": "sqlite:///test.db" | |
| } | |
| return FitScoreFeedbackAgent(config) | |
| def client(self, agent): | |
| """Create a test client""" | |
| return TestClient(agent.get_app()) | |
| def test_agent_initialization(self, agent): | |
| """Test agent initialization""" | |
| assert agent is not None | |
| assert agent.config is not None | |
| assert agent.feedback_system is not None | |
| assert agent.reinforcement_system is not None | |
| assert agent.advanced_learning is not None | |
| assert agent.adaptive_hiring is not None | |
| assert agent.synapse_ai is not None | |
| def test_root_endpoint(self, client): | |
| """Test root endpoint""" | |
| response = client.get("/") | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert data["message"] == "FitScore Feedback Agent" | |
| assert data["version"] == "1.0.0" | |
| assert data["status"] == "running" | |
| def test_health_endpoint(self, client): | |
| """Test health check endpoint""" | |
| response = client.get("/health") | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert data["status"] == "healthy" | |
| assert data["service"] == "FitScore Feedback Agent" | |
| assert data["version"] == "1.0.0" | |
| assert "timestamp" in data | |
| def test_calculate_fitscore_endpoint(self, client): | |
| """Test FitScore calculation endpoint""" | |
| request_data = { | |
| "candidate_id": "test_candidate_123", | |
| "job_id": "test_job_456", | |
| "recruiter_id": "test_recruiter_789", | |
| "name": "John Doe", | |
| "email": "john.doe@example.com", | |
| "phone": "+1-555-0123", | |
| "location": "San Francisco, CA", | |
| "resume_text": "Experienced software engineer with 5 years in Python and React development." | |
| } | |
| with patch('src.agent.AdaptiveHiringSystem') as mock_adaptive: | |
| mock_adaptive.return_value.evaluate_candidate.return_value = { | |
| 'fitscore': 8.5, | |
| 'verdict': 'Accept', | |
| 'confidence': 0.85, | |
| 'category_scores': { | |
| 'education': 0.9, | |
| 'career_trajectory': 0.8, | |
| 'company_relevance': 0.85, | |
| 'tenure': 0.75, | |
| 'skills': 0.9, | |
| 'bonus': 0.1 | |
| }, | |
| 'justification': 'Strong technical skills and relevant experience...', | |
| 'model_version': 'v1.0' | |
| } | |
| response = client.post("/fitscore/calculate", json=request_data) | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert data["success"] is True | |
| assert "evaluation_id" in data | |
| assert data["fitscore"] == 8.5 | |
| assert data["verdict"] == "Accept" | |
| assert data["confidence"] == 0.85 | |
| def test_feedback_endpoint(self, client): | |
| """Test feedback submission endpoint""" | |
| request_data = { | |
| "job_id": "test_job_456", | |
| "company_id": "test_company_123", | |
| "analysis_id": "test_analysis_789", | |
| "feedback_type": "hired", | |
| "feedback_text": "Excellent candidate with strong technical skills and cultural fit.", | |
| "feedback_category": "skills", | |
| "confidence_score": 0.95, | |
| "email": "hr@company.com", | |
| "linkedin_url": "https://linkedin.com/in/hr-manager" | |
| } | |
| response = client.post("/fitscore/feedback", json=request_data) | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert data["success"] is True | |
| assert "feedback_id" in data | |
| assert "learning_event_id" in data | |
| assert data["message"] == "Feedback recorded and learning event created" | |
| def test_recalculate_endpoint(self, client): | |
| """Test FitScore recalculation endpoint""" | |
| # First create a candidate evaluation | |
| candidate_data = { | |
| "candidate_id": "test_candidate_123", | |
| "job_id": "test_job_456", | |
| "recruiter_id": "test_recruiter_789", | |
| "name": "John Doe", | |
| "email": "john.doe@example.com", | |
| "resume_text": "Experienced software engineer with 5 years in Python and React development." | |
| } | |
| with patch('src.agent.AdaptiveHiringSystem') as mock_adaptive: | |
| mock_adaptive.return_value.evaluate_candidate.return_value = { | |
| 'fitscore': 8.5, | |
| 'verdict': 'Accept', | |
| 'confidence': 0.85, | |
| 'category_scores': {'education': 0.9, 'skills': 0.9}, | |
| 'justification': 'Strong technical skills...', | |
| 'model_version': 'v1.0' | |
| } | |
| # Calculate initial FitScore | |
| response = client.post("/fitscore/calculate", json=candidate_data) | |
| assert response.status_code == 200 | |
| # Submit feedback | |
| feedback_data = { | |
| "job_id": "test_job_456", | |
| "company_id": "test_company_123", | |
| "analysis_id": "test_analysis_789", | |
| "feedback_type": "hired", | |
| "feedback_text": "Excellent candidate!", | |
| "feedback_category": "skills", | |
| "confidence_score": 0.95 | |
| } | |
| response = client.post("/fitscore/feedback", json=feedback_data) | |
| assert response.status_code == 200 | |
| feedback_id = response.json()["feedback_id"] | |
| # Recalculate with feedback | |
| mock_adaptive.return_value.recalculate_with_feedback.return_value = { | |
| 'fitscore': 8.7, | |
| 'verdict': 'Accept', | |
| 'confidence': 0.88, | |
| 'category_scores': {'education': 0.9, 'skills': 0.92}, | |
| 'justification': 'Updated evaluation...', | |
| 'model_version': 'v1.1' | |
| } | |
| response = client.post(f"/fitscore/recalculate?candidate_id=test_candidate_123&job_id=test_job_456&feedback_id={feedback_id}") | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert data["success"] is True | |
| assert data["original_fitscore"] == 8.5 | |
| assert data["updated_fitscore"] == 8.7 | |
| assert data["score_change"] == 0.2 | |
| def test_compare_results_endpoint(self, client): | |
| """Test results comparison endpoint""" | |
| # This would require setting up test data in the database | |
| # For now, we'll test the endpoint structure | |
| response = client.get("/fitscore/compare/test_candidate_123/test_job_456") | |
| # Should return 404 if no evaluations exist | |
| assert response.status_code in [200, 404] | |
| def test_feedback_analytics_endpoint(self, client): | |
| """Test feedback analytics endpoint""" | |
| response = client.get("/analytics/feedback") | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert "total_feedback" in data | |
| assert "feedback_by_type" in data | |
| assert "feedback_by_category" in data | |
| assert "patterns_count" in data | |
| def test_reinforcement_analytics_endpoint(self, client): | |
| """Test reinforcement learning analytics endpoint""" | |
| response = client.get("/analytics/reinforcement") | |
| assert response.status_code == 200 | |
| data = response.json() | |
| assert "total_submissions" in data | |
| assert "success_rate" in data | |
| assert "average_reward" in data | |
| assert "weight_performance" in data | |
| assert "learning_metrics" in data | |
| def test_invalid_feedback_type(self, client): | |
| """Test feedback validation with invalid feedback type""" | |
| request_data = { | |
| "job_id": "test_job_456", | |
| "company_id": "test_company_123", | |
| "analysis_id": "test_analysis_789", | |
| "feedback_type": "invalid_type", # Invalid feedback type | |
| "feedback_text": "Test feedback", | |
| "feedback_category": "skills", | |
| "confidence_score": 0.95 | |
| } | |
| response = client.post("/fitscore/feedback", json=request_data) | |
| assert response.status_code == 422 # Validation error | |
| def test_invalid_confidence_score(self, client): | |
| """Test feedback validation with invalid confidence score""" | |
| request_data = { | |
| "job_id": "test_job_456", | |
| "company_id": "test_company_123", | |
| "analysis_id": "test_analysis_789", | |
| "feedback_type": "hired", | |
| "feedback_text": "Test feedback", | |
| "feedback_category": "skills", | |
| "confidence_score": 1.5 # Invalid confidence score (> 1.0) | |
| } | |
| response = client.post("/fitscore/feedback", json=request_data) | |
| assert response.status_code == 422 # Validation error | |
| def test_invalid_email_format(self, client): | |
| """Test candidate validation with invalid email""" | |
| request_data = { | |
| "candidate_id": "test_candidate_123", | |
| "job_id": "test_job_456", | |
| "recruiter_id": "test_recruiter_789", | |
| "name": "John Doe", | |
| "email": "invalid-email", # Invalid email format | |
| "resume_text": "Experienced software engineer with 5 years in Python and React development." | |
| } | |
| response = client.post("/fitscore/calculate", json=request_data) | |
| assert response.status_code == 422 # Validation error | |
| class TestModels: | |
| """Test cases for Pydantic models""" | |
| def test_candidate_request_valid(self): | |
| """Test valid candidate request""" | |
| data = { | |
| "candidate_id": "test_candidate_123", | |
| "job_id": "test_job_456", | |
| "recruiter_id": "test_recruiter_789", | |
| "name": "John Doe", | |
| "email": "john.doe@example.com", | |
| "resume_text": "Experienced software engineer with 5 years in Python and React development." | |
| } | |
| request = CandidateRequest(**data) | |
| assert request.candidate_id == "test_candidate_123" | |
| assert request.email == "john.doe@example.com" | |
| def test_candidate_request_invalid_email(self): | |
| """Test candidate request with invalid email""" | |
| data = { | |
| "candidate_id": "test_candidate_123", | |
| "job_id": "test_job_456", | |
| "recruiter_id": "test_recruiter_789", | |
| "name": "John Doe", | |
| "email": "invalid-email", | |
| "resume_text": "Experienced software engineer with 5 years in Python and React development." | |
| } | |
| with pytest.raises(ValueError, match="Invalid email format"): | |
| CandidateRequest(**data) | |
| def test_feedback_request_valid(self): | |
| """Test valid feedback request""" | |
| data = { | |
| "job_id": "test_job_456", | |
| "company_id": "test_company_123", | |
| "analysis_id": "test_analysis_789", | |
| "feedback_type": "hired", | |
| "feedback_text": "Excellent candidate!", | |
| "feedback_category": "skills", | |
| "confidence_score": 0.95 | |
| } | |
| request = FeedbackRequest(**data) | |
| assert request.feedback_type == "hired" | |
| assert request.confidence_score == 0.95 | |
| def test_feedback_request_invalid_type(self): | |
| """Test feedback request with invalid feedback type""" | |
| data = { | |
| "job_id": "test_job_456", | |
| "company_id": "test_company_123", | |
| "analysis_id": "test_analysis_789", | |
| "feedback_type": "invalid_type", | |
| "feedback_text": "Test feedback", | |
| "feedback_category": "skills", | |
| "confidence_score": 0.95 | |
| } | |
| with pytest.raises(ValueError, match="Feedback type must be one of"): | |
| FeedbackRequest(**data) | |
| def test_feedback_request_invalid_confidence(self): | |
| """Test feedback request with invalid confidence score""" | |
| data = { | |
| "job_id": "test_job_456", | |
| "company_id": "test_company_123", | |
| "analysis_id": "test_analysis_789", | |
| "feedback_type": "hired", | |
| "feedback_text": "Test feedback", | |
| "feedback_category": "skills", | |
| "confidence_score": 1.5 | |
| } | |
| with pytest.raises(ValueError, match="Confidence score must be between"): | |
| FeedbackRequest(**data) | |
| if __name__ == "__main__": | |
| pytest.main([__file__]) |