import pytest from apps.gamification.services import desired_effect, sync_source_effects pytestmark = [pytest.mark.integration, pytest.mark.django_db] def test_authenticated_summary_returns_progress_and_activity_breakdown(client, user_factory, auth_headers): member = user_factory() sync_source_effects( "event_registration", "verified-1", [desired_effect(member, "attendance", "participant")], ) response = client.get("/api/gamification/me", **auth_headers(member)) assert response.status_code == 200 summary = response.json() assert summary["points_total"] == 30 assert summary["points_event"] == 30 assert summary["points_blog"] == 0 assert summary["current_level"]["id"] == "contributor" assert summary["next_level"]["id"] == "ally" assert summary["activity_counts"]["attendance"] == 1 assert "attendance-1" in {badge["id"] for badge in summary["badges"]} assert summary["points_per_activity"] == {"attendance": 30, "post": 20, "comment": 5, "like": 1, "save": 1} assert summary["badge_thresholds"]["likes"] == [10, 50, 100] def test_public_profile_exposes_badges_but_never_points_even_when_details_are_hidden( client, user_factory, ): member = user_factory( username="ranked_public_member", show_public_profile_details=False, mobile="09195550999", ) sync_source_effects( "event_registration", "verified-public-1", [desired_effect(member, "attendance", "participant")], ) response = client.get(f"/api/auth/public-profile/{member.username}") assert response.status_code == 200 profile = response.json() assert profile["details_visible"] is False assert profile["mobile"] is None assert "attendance-1" in {badge["id"] for badge in profile["badges"]} assert all(set(badge) == {"id", "category", "label"} for badge in profile["badges"]) assert not {"points_total", "points_event", "points_blog", "activity_counts"} & profile.keys() def test_gamification_summary_requires_authentication(client): assert client.get("/api/gamification/me").status_code == 401