"""Tests for the bank vault: rob-proof storage and net-worth accounting.""" from core import economy from conftest import run UID = 6161 ROBBER = 6162 def _fund(fake_pb, uid: int, balance: int, bank: int = 0) -> None: run(economy.get_user(uid)) rec = fake_pb.record_for(uid) rec["balance"] = balance rec["bank_balance"] = bank class TestDepositWithdraw: def test_deposit_moves_liquid_to_bank(self, fake_pb): _fund(fake_pb, UID, 1000) res = run(economy.do_deposit(UID, 400)) assert res["ok"] and res["balance"] == 600 and res["bank"] == 400 rec = fake_pb.record_for(UID) assert rec["balance"] == 600 and rec["bank_balance"] == 400 def test_withdraw_moves_bank_to_liquid(self, fake_pb): _fund(fake_pb, UID, 100, bank=500) res = run(economy.do_withdraw(UID, 300)) assert res["ok"] and res["balance"] == 400 and res["bank"] == 200 def test_deposit_more_than_liquid_rejected(self, fake_pb): _fund(fake_pb, UID, 100) res = run(economy.do_deposit(UID, 500)) assert not res["ok"] and res["reason"] == "insufficient" assert fake_pb.record_for(UID)["balance"] == 100 # unchanged def test_withdraw_more_than_bank_rejected(self, fake_pb): _fund(fake_pb, UID, 0, bank=100) res = run(economy.do_withdraw(UID, 500)) assert not res["ok"] and res["reason"] == "insufficient" assert fake_pb.record_for(UID)["bank_balance"] == 100 def test_nonpositive_rejected(self, fake_pb): _fund(fake_pb, UID, 1000, bank=1000) assert run(economy.do_deposit(UID, 0))["reason"] == "invalid" assert run(economy.do_withdraw(UID, -5))["reason"] == "invalid" def test_banned_rejected(self, fake_pb): _fund(fake_pb, UID, 1000) fake_pb.record_for(UID)["eco_banned"] = True assert run(economy.do_deposit(UID, 100))["reason"] == "banned" def test_round_trip_conserves_coins(self, fake_pb): _fund(fake_pb, UID, 1000) run(economy.do_deposit(UID, 700)) run(economy.do_withdraw(UID, 700)) rec = fake_pb.record_for(UID) assert rec["balance"] == 1000 and rec["bank_balance"] == 0 class TestRobProof: def test_rob_cannot_touch_banked_coins(self, fake_pb, monkeypatch): # Target keeps everything banked, only a little liquid (< rob threshold). _fund(fake_pb, UID, 50, bank=100_000) _fund(fake_pb, ROBBER, 1000) # Target has < 100 liquid, so a rob is rejected as "broke" - the vault is # invisible to /rob (which only reads balance). res = run(economy.do_rob(ROBBER, UID)) assert not res["ok"] and res["reason"] == "broke" assert fake_pb.record_for(UID)["bank_balance"] == 100_000 # untouched class TestNetWorth: def test_leaderboard_counts_bank(self, fake_pb): _fund(fake_pb, UID, 100, bank=900) # net worth 1000 _fund(fake_pb, ROBBER, 500, bank=0) # net worth 500 board = dict((uid, worth) for uid, worth in run(economy.get_leaderboard(top_n=None))) assert board[str(UID)] == 1000 assert board[str(ROBBER)] == 500 def test_economy_stats_counts_bank(self, fake_pb, monkeypatch): monkeypatch.setattr(economy.house, "HOUSE_ID", None) _fund(fake_pb, UID, 100, bank=900) stats = run(economy.get_economy_stats()) assert stats["total_coins"] == 1000 assert stats["player_coins"] == 1000