From e2eb32dacb556bbcdb009f642e1ebc30bbfd296a Mon Sep 17 00:00:00 2001 From: yiekheng Date: Sat, 2 May 2026 16:59:32 +0800 Subject: [PATCH] feat(bot_cli): add credit and transfer subcommands --- app/bot_cli.py | 25 +++++++++++++++++++++++++ tests/test_bot_cli.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/app/bot_cli.py b/app/bot_cli.py index 4a72c0a..ef788c3 100644 --- a/app/bot_cli.py +++ b/app/bot_cli.py @@ -54,6 +54,19 @@ def cmd_insert_user(args): print(f"OK: inserted {args.f_username} → {args.t_username}") +def cmd_credit(args): + bot = CM_BOT_HAL() + print(f"Credit: {bot.get_user_credit(args.username, args.password)}") + + +def cmd_transfer(args): + bot = CM_BOT_HAL() + print(bot.transfer_credit_api( + args.f_username, args.f_password, + args.t_username, args.t_password, + )) + + def build_parser() -> argparse.ArgumentParser: p = argparse.ArgumentParser( prog="bot_cli", @@ -73,6 +86,18 @@ def build_parser() -> argparse.ArgumentParser: sp.add_argument("t_username") sp.set_defaults(func=cmd_insert_user) + sp = sub.add_parser("credit", help="Read account credit balance.") + sp.add_argument("username") + sp.add_argument("password") + sp.set_defaults(func=cmd_credit) + + sp = sub.add_parser("transfer", help="One-shot credit transfer.") + sp.add_argument("f_username") + sp.add_argument("f_password") + sp.add_argument("t_username") + sp.add_argument("t_password") + sp.set_defaults(func=cmd_transfer) + return p diff --git a/tests/test_bot_cli.py b/tests/test_bot_cli.py index 048763d..d268fa1 100644 --- a/tests/test_bot_cli.py +++ b/tests/test_bot_cli.py @@ -151,5 +151,42 @@ class CmdInsertUserTests(unittest.TestCase): self.assertEqual(args.t_username, "player_x") +class CmdCreditTests(unittest.TestCase): + @mock.patch.object(bot_cli, "CM_BOT_HAL") + def test_prints_credit(self, mock_hal_class): + mock_hal = mock_hal_class.return_value + mock_hal.get_user_credit.return_value = 42.5 + out = io.StringIO() + with contextlib.redirect_stdout(out): + bot_cli.cmd_credit(argparse.Namespace(username="13c1234", password="abc")) + self.assertIn("Credit: 42.5", out.getvalue()) + mock_hal.get_user_credit.assert_called_once_with("13c1234", "abc") + + def test_credit_subparser_dispatches(self): + parser = bot_cli.build_parser() + args = parser.parse_args(["credit", "13c1234", "abc"]) + self.assertIs(args.func, bot_cli.cmd_credit) + + +class CmdTransferTests(unittest.TestCase): + @mock.patch.object(bot_cli, "CM_BOT_HAL") + def test_prints_transfer_result(self, mock_hal_class): + mock_hal = mock_hal_class.return_value + mock_hal.transfer_credit_api.return_value = "Successfully transfer amount: 10.0 from 13c1234 to player_x" + out = io.StringIO() + with contextlib.redirect_stdout(out): + bot_cli.cmd_transfer(argparse.Namespace( + f_username="13c1234", f_password="abc", + t_username="player_x", t_password="0000", + )) + self.assertIn("Successfully transfer", out.getvalue()) + mock_hal.transfer_credit_api.assert_called_once_with("13c1234", "abc", "player_x", "0000") + + def test_transfer_subparser_dispatches(self): + parser = bot_cli.build_parser() + args = parser.parse_args(["transfer", "13c1234", "abc", "player_x", "0000"]) + self.assertIs(args.func, bot_cli.cmd_transfer) + + if __name__ == "__main__": unittest.main()