from __future__ import annotations from fan_passport.content_importer import import_seed_payload from fan_passport.database import SessionLocal from fan_passport.gamification import GamificationService from tests.conftest import TEST_SEED def test_duplicate_collection_does_not_double_award_points(client) -> None: _ = client with SessionLocal() as session: service = GamificationService(session) result = service.create_profile(display_name="Alex", external_subject="alex") user_id = result.profile.id first = service.collect_item(user_id=user_id, item_type="team", item_id="ALPHA") second = service.collect_item(user_id=user_id, item_type="team", item_id="ALPHA") assert first.duplicate is False assert second.duplicate is True assert second.item.id == first.item.id profile = service.get_profile(user_id) # Profile: start challenge 10 + founder badge 5 # First collect: team points 20 + collect-one-team challenge 30 + team badge 5 assert profile.points_total == 70 def test_group_completion_challenge_unlocks_after_all_group_teams_collected(client) -> None: _ = client with SessionLocal() as session: service = GamificationService(session) result = service.create_profile(display_name="Bea", external_subject="bea") user_id = result.profile.id service.collect_item(user_id=user_id, item_type="team", item_id="ALPHA") after_beta = service.collect_item(user_id=user_id, item_type="team", item_id="BETA") completed_slugs = {item.challenge.slug for item in after_beta.evaluation.completed_challenges} assert "complete-group-a" in completed_slugs snapshot = service.get_passport_snapshot(user_id) group_progress = [ progress for progress, challenge in snapshot.challenges if challenge.slug == "complete-group-a" ][0] assert group_progress.completed is True assert group_progress.progress_count == 2 assert group_progress.target_count == 2 def test_prediction_scoring_can_unlock_giant_killing_achievement(client) -> None: _ = client with SessionLocal() as session: service = GamificationService(session) result = service.create_profile(display_name="Caro", external_subject="caro") user_id = result.profile.id prediction = service.submit_prediction( user_id=user_id, match_id="MATCH-1", predicted_home_score=0, predicted_away_score=1, giant_killing_pick=True, ) assert prediction.prediction.points_awarded == 0 evaluation = service.record_match_result( match_id="MATCH-1", status="final", home_score=0, away_score=1, is_giant_killing=True, ) assert evaluation.evaluated_predictions == 1 assert evaluation.points_awarded_total >= 5 + 35 + 80 + 120 unlocked_slugs = {item.badge.slug for item in evaluation.evaluation.new_badges} assert "upset-prophet" in unlocked_slugs def test_seed_import_is_idempotent(client) -> None: _ = client with SessionLocal() as session: first = import_seed_payload(session, TEST_SEED) second = import_seed_payload(session, TEST_SEED) session.commit() assert first.counts["teams"] == 2 assert second.updated["teams"] == 2