Spaces:
Running
Running
| """ | |
| tests/test_generator.py | |
| Tests for server/claim_generator.py — run with: pytest tests/test_generator.py -v | |
| """ | |
| import pytest | |
| from server.claim_generator import ( | |
| generate_claim, | |
| generate_episode_pool, | |
| FRAUD_TYPES, | |
| COVERAGE_TYPES, | |
| ClaimScenario, | |
| ) | |
| class TestDeterminism: | |
| def test_same_seed_returns_same_claim(self): | |
| a = generate_claim(42, "medical_inflation", "health", "medium") | |
| b = generate_claim(42, "medical_inflation", "health", "medium") | |
| assert a.claim_id == b.claim_id | |
| assert a.claimant["name"] == b.claimant["name"] | |
| assert a.payout_amount_inr == b.payout_amount_inr | |
| assert a.ground_truth == b.ground_truth | |
| def test_different_seeds_return_different_claims(self): | |
| a = generate_claim(1, "medical_inflation", "health", "medium") | |
| b = generate_claim(2, "medical_inflation", "health", "medium") | |
| assert a.claim_id != b.claim_id | |
| def test_claim_id_encodes_seed_and_fraud_type(self): | |
| c = generate_claim(99, "staged_accident", "auto", "easy") | |
| assert "0099" in c.claim_id | |
| assert "STA" in c.claim_id | |
| class TestAllFraudTypes: | |
| def test_all_fraud_types_generate_correctly(self, fraud_type): | |
| c = generate_claim(0, fraud_type, "health", "medium") | |
| assert isinstance(c, ClaimScenario) | |
| assert c.fraud_type == fraud_type | |
| assert c.ground_truth in {"approve_claim", "deny_claim", "escalate_to_human"} | |
| assert len(c.documents) >= 2 | |
| assert len(c.available_actions) >= 5 | |
| def test_fraud_types_have_signals(self, fraud_type): | |
| c = generate_claim(0, fraud_type, "health", "easy") | |
| assert len(c.expected_fraud_signals) > 0, f"{fraud_type} should have fraud signals on easy" | |
| def test_clean_claim_approves_and_no_signals(self): | |
| c = generate_claim(0, "none", "auto", "easy") | |
| assert c.ground_truth == "approve_claim" | |
| assert c.expected_fraud_signals == [] | |
| def test_coordinated_ring_has_linked_claims(self): | |
| c = generate_claim(0, "coordinated_ring", "auto", "medium") | |
| assert len(c.linked_claims) >= 3 | |
| def test_coordinated_ring_escalates(self): | |
| c = generate_claim(0, "coordinated_ring", "health", "medium") | |
| assert c.ground_truth == "escalate_to_human" | |
| def test_identity_fraud_has_verify_action(self): | |
| c = generate_claim(0, "identity_fraud", "health", "medium") | |
| assert "verify_identity" in c.available_actions | |
| class TestDifficulty: | |
| def test_easy_has_low_ambiguity(self): | |
| c = generate_claim(0, "medical_inflation", "health", "easy") | |
| assert c.ambiguity_score < 0.3 | |
| def test_hard_has_high_ambiguity(self): | |
| c = generate_claim(0, "medical_inflation", "health", "hard") | |
| assert c.ambiguity_score > 0.6 | |
| def test_easy_max_steps_10(self): | |
| c = generate_claim(0, "staged_accident", "auto", "easy") | |
| assert c.max_steps == 10 | |
| def test_medium_max_steps_18(self): | |
| c = generate_claim(0, "staged_accident", "auto", "medium") | |
| assert c.max_steps == 18 | |
| def test_hard_max_steps_28(self): | |
| c = generate_claim(0, "staged_accident", "auto", "hard") | |
| assert c.max_steps == 28 | |
| class TestCoverageTypes: | |
| def test_all_coverage_types_generate(self, coverage): | |
| c = generate_claim(0, "medical_inflation", coverage, "medium") | |
| assert c.coverage_type == coverage | |
| assert c.payout_amount_inr > 0 | |
| class TestEpisodePool: | |
| def test_500_unique_episodes_no_duplicates(self): | |
| pool = generate_episode_pool(count=500) | |
| assert len(pool) == 500 | |
| ids = [e.claim_id for e in pool] | |
| assert len(set(ids)) == 500, "All 500 episodes must have unique claim IDs" | |
| def test_pool_covers_all_fraud_types(self): | |
| pool = generate_episode_pool(count=100) | |
| found_types = {e.fraud_type for e in pool} | |
| assert found_types == set(FRAUD_TYPES) | |
| class TestValidation: | |
| def test_invalid_fraud_type_raises(self): | |
| with pytest.raises(ValueError): | |
| generate_claim(0, "nonexistent_fraud", "health", "medium") | |
| def test_invalid_coverage_raises(self): | |
| with pytest.raises(ValueError): | |
| generate_claim(0, "medical_inflation", "crypto", "medium") | |
| def test_invalid_difficulty_raises(self): | |
| with pytest.raises(ValueError): | |
| generate_claim(0, "medical_inflation", "health", "extreme") | |
| def test_ambiguity_always_in_0_1_range(self): | |
| for seed in range(50): | |
| c = generate_claim(seed, "coordinated_ring", "auto", "hard") | |
| assert 0.0 <= c.ambiguity_score <= 1.0 | |