"""Tests for the achievements system (one-time milestone rewards).""" from core import economy from conftest import run UID = 4747 def _fund(fake_pb, **stats) -> None: run(economy.get_user(UID)) rec = fake_pb.record_for(UID) rec.update(stats) class TestNewlyEarned: def test_threshold_met_is_newly_earned(self, fake_pb): _fund(fake_pb, work_count=10) user = run(economy.get_user(UID)) assert "work_10" in economy.newly_earned(user) def test_below_threshold_not_earned(self, fake_pb): _fund(fake_pb, work_count=9) user = run(economy.get_user(UID)) assert "work_10" not in economy.newly_earned(user) def test_already_claimed_not_repeated(self, fake_pb): _fund(fake_pb, work_count=10, achievements_earned=["work_10"]) user = run(economy.get_user(UID)) assert "work_10" not in economy.newly_earned(user) class TestClaim: def test_claims_and_pays_reward_once(self, fake_pb): _fund(fake_pb, work_count=10, balance=0) reward = economy.ACHIEVEMENTS["work_10"]["reward"] res = run(economy.do_check_achievements(UID)) assert res["ok"] and res["new"] == ["work_10"] assert res["reward"] == reward assert fake_pb.record_for(UID)["balance"] == reward assert "work_10" in fake_pb.record_for(UID)["achievements_earned"] # Second call: nothing new, no double pay. res2 = run(economy.do_check_achievements(UID)) assert res2["new"] == [] and res2["reward"] == 0 assert fake_pb.record_for(UID)["balance"] == reward def test_multiple_unlocked_at_once(self, fake_pb): _fund(fake_pb, work_count=100, total_fish_caught=25, balance=0) res = run(economy.do_check_achievements(UID)) # work_10, work_100 and fish_25 all cross at once assert set(res["new"]) == {"work_10", "work_100", "fish_25"} expected = sum(economy.ACHIEVEMENTS[a]["reward"] for a in res["new"]) assert res["reward"] == expected assert fake_pb.record_for(UID)["balance"] == expected def test_nothing_to_claim(self, fake_pb): _fund(fake_pb, balance=500) res = run(economy.do_check_achievements(UID)) assert res["ok"] and res["new"] == [] and res["reward"] == 0 assert fake_pb.record_for(UID)["balance"] == 500 class TestView: def test_view_marks_earned_and_progress(self, fake_pb): _fund(fake_pb, work_count=5, achievements_earned=["beg_50"]) rows = economy.achievements_view(run(economy.get_user(UID))) by_id = {r["id"]: r for r in rows} assert by_id["beg_50"]["earned"] is True assert by_id["work_10"]["earned"] is False assert by_id["work_10"]["progress"] == 5 # capped at goal assert len(rows) == len(economy.ACHIEVEMENTS) def test_progress_capped_at_goal(self, fake_pb): _fund(fake_pb, work_count=9999) rows = {r["id"]: r for r in economy.achievements_view(run(economy.get_user(UID)))} assert rows["work_10"]["progress"] == rows["work_10"]["goal"]