# retoor from devplacepy.services.game import economy def test_level_thresholds(): assert economy.level_for_xp(0) == 1 assert economy.level_for_xp(economy.xp_threshold(2)) == 2 assert economy.level_for_xp(economy.xp_threshold(5)) == 5 assert economy.level_for_xp(economy.xp_threshold(economy.MAX_LEVEL) + 9999) == economy.MAX_LEVEL def test_level_progress_span(): progress = economy.level_progress(economy.xp_threshold(3)) assert progress["level"] == 3 assert progress["into_level"] == 0 assert progress["is_max"] is False def test_plot_cost_doubles(): assert economy.plot_cost(economy.STARTING_PLOTS) == economy.PLOT_BASE_COST assert economy.plot_cost(economy.STARTING_PLOTS + 1) == economy.PLOT_BASE_COST * 2 assert economy.plot_cost(economy.STARTING_PLOTS + 2) == economy.PLOT_BASE_COST * 4 def test_perk_cost_grows(): perk = economy.perk_for("yield") assert economy.perk_cost(perk, 0) == perk.base_cost assert economy.perk_cost(perk, 1) == round(perk.base_cost * perk.cost_growth) assert economy.perk_cost(perk, 2) > economy.perk_cost(perk, 1) def test_daily_reward_streak_and_cap(): assert economy.daily_reward(1) == economy.DAILY_BASE assert economy.daily_reward(2) == economy.DAILY_BASE + economy.DAILY_STREAK_STEP assert economy.daily_reward(99) == economy.daily_reward(economy.DAILY_STREAK_CAP) def test_effective_plant_cost_discount(): crop = economy.crop_for("python") assert economy.effective_plant_cost(crop, 0) == crop.cost assert economy.effective_plant_cost(crop, 3) < crop.cost assert economy.effective_plant_cost(crop, 3) >= 1 def test_effective_reward_coins_yield_and_prestige(): crop = economy.crop_for("shell") assert economy.effective_reward_coins(crop, 0, 0) == crop.reward_coins assert economy.effective_reward_coins(crop, 4, 0) > crop.reward_coins assert economy.effective_reward_coins(crop, 0, 2) > crop.reward_coins def test_effective_reward_xp(): crop = economy.crop_for("shell") assert economy.effective_reward_xp(crop, 0) == crop.reward_xp assert economy.effective_reward_xp(crop, 10) > crop.reward_xp def test_growth_perk_speeds_build(): crop = economy.crop_for("python") assert economy.grow_seconds_for(crop, 1, 5) < economy.grow_seconds_for(crop, 1, 0) def test_ci_tier_speeds_build(): crop = economy.crop_for("python") assert economy.grow_seconds_for(crop, 2, 0) < economy.grow_seconds_for(crop, 1, 0) def test_prestige_multiplier(): assert economy.prestige_multiplier(0) == 1.0 assert economy.prestige_multiplier(2) == 1 + 2 * economy.PRESTIGE_BONUS def test_fertilize_cost_has_floor(): assert economy.fertilize_cost(1) == economy.FERTILIZE_MIN_COST assert economy.fertilize_cost(10000) > economy.FERTILIZE_MIN_COST def test_crop_payload_locked_flag(): rust = economy.crop_for("rust") assert economy.crop_payload(rust, 1, 1)["locked"] is True assert economy.crop_payload(rust, 1, rust.min_level)["locked"] is False def test_crop_payload_reflects_perks(): crop = economy.crop_for("python") base = economy.crop_payload(crop, 1, 5) boosted = economy.crop_payload(crop, 1, 5, growth_level=5, discount_level=3, yield_level=4, prestige=1) assert boosted["cost"] < base["cost"] assert boosted["grow_seconds"] < base["grow_seconds"] assert boosted["reward_coins"] > base["reward_coins"] def test_daily_quests_deterministic_count_and_kinds(): first = economy.daily_quests("user-xyz", "2026-06-22") second = economy.daily_quests("user-xyz", "2026-06-22") assert first == second assert len(first) == economy.DAILY_QUEST_COUNT assert all(quest["kind"] in economy.QUEST_DEFS for quest in first) assert all(quest["goal"] > 0 for quest in first) def test_farm_score_empty_is_zero(): assert economy.farm_score({}) == 0 def test_farm_score_counts_every_factor(): score = economy.farm_score( { "xp": 100, "prestige": 2, "total_harvests": 3, "coins": 200, "ci_tier": 3, "plot_count": economy.STARTING_PLOTS + 2, "perk_yield": 1, "perk_growth": 1, "perk_discount": 1, "perk_xp": 1, "streak": 4, } ) expected = ( 100 + 2 * economy.SCORE_PRESTIGE + 3 * economy.SCORE_HARVEST + 200 // economy.SCORE_COIN_DIVISOR + (3 - 1) * economy.SCORE_CI + 2 * economy.SCORE_PLOT + 4 * economy.SCORE_PERK + 4 * economy.SCORE_STREAK ) assert score == expected def test_farm_score_prestige_is_additive_and_substantial(): base = {"xp": 800, "total_harvests": 5} with_prestige = {**base, "prestige": 1} gain = economy.farm_score(with_prestige) - economy.farm_score(base) assert gain == economy.SCORE_PRESTIGE assert gain >= economy.xp_threshold(economy.PRESTIGE_MIN_LEVEL) def test_farm_score_prestige_lifts_above_lower_level_player(): refactorer = {"xp": 200, "prestige": 1} higher_level_no_prestige = {"xp": economy.xp_threshold(5)} assert economy.farm_score(refactorer) > economy.farm_score(higher_level_no_prestige) def test_farm_score_streak_is_capped(): capped = economy.farm_score({"streak": economy.SCORE_STREAK_CAP}) over = economy.farm_score({"streak": economy.SCORE_STREAK_CAP + 50}) assert capped == over def test_farm_score_handles_legacy_null_columns(): assert economy.farm_score( {"xp": 50, "prestige": None, "perk_yield": None, "streak": None} ) == 50 # --- legacy upgrades --------------------------------------------------------- def test_legacy_for_known_and_unknown(): assert economy.legacy_for("multiplier") is not None assert economy.legacy_for("does_not_exist") is None def test_legacy_cost_grows_with_level(): up = economy.legacy_for("multiplier") assert economy.legacy_cost(up, 0) == up.base_cost assert economy.legacy_cost(up, 2) > economy.legacy_cost(up, 1) def test_legacy_multiplier_steps(): assert economy.legacy_multiplier(0) == 1.0 assert economy.legacy_multiplier(3) == 1 + economy.LEGACY_MULT_STEP * 3 def test_stars_for_refactor_scales_with_level_and_prestige(): assert economy.stars_for_refactor(0, 0) == economy.STAR_BASE assert economy.stars_for_refactor(10, 0) == economy.STAR_BASE + 2 assert economy.stars_for_refactor(0, 2) == economy.STAR_BASE + 2 def test_prestige_base_plots_adds_legacy_plots(): assert economy.prestige_base_plots(0) == economy.STARTING_PLOTS assert economy.prestige_base_plots(3) == economy.STARTING_PLOTS + 3 # --- steal economy ----------------------------------------------------------- def test_effective_steal_grace_extends_with_defense(): assert economy.effective_steal_grace(0) == economy.STEAL_GRACE_SECONDS assert economy.effective_steal_grace(2) == ( economy.STEAL_GRACE_SECONDS + economy.LEGACY_DEFENSE_GRACE * 2 ) def test_effective_steal_fraction_drops_with_defense_and_has_floor(): assert economy.effective_steal_fraction(0) == economy.STEAL_FRACTION assert economy.effective_steal_fraction(2) < economy.STEAL_FRACTION assert economy.effective_steal_fraction(99) >= 0.1 def test_steal_reward_coins_is_a_fraction_of_harvest(): crop = economy.crop_for("shell") full = economy.effective_reward_coins(crop) stolen = economy.steal_reward_coins(crop) assert 0 < stolen <= full # --- golden crops ------------------------------------------------------------ def test_is_golden_deterministic_and_bounded(): first = economy.is_golden("plot-7", "2026-06-20T00:00:00+00:00") second = economy.is_golden("plot-7", "2026-06-20T00:00:00+00:00") assert first == second assert isinstance(first, bool) def test_is_golden_requires_both_args(): assert economy.is_golden("", "2026-06-20T00:00:00+00:00") is False assert economy.is_golden("plot-7", "") is False