feat(bot_cli): add monitor-once subcommand
This commit is contained in:
parent
e2eb32dacb
commit
f472a94916
@ -67,6 +67,22 @@ def cmd_transfer(args):
|
||||
))
|
||||
|
||||
|
||||
def cmd_monitor_once(args):
|
||||
bot = CM_BOT_HAL()
|
||||
available = bot.get_all_available_acc()
|
||||
print(f"Available accounts: {len(available)} (target: {args.target})")
|
||||
if len(available) >= args.target:
|
||||
print("Already at target; nothing to do.")
|
||||
return
|
||||
for _ in range(len(available), args.target):
|
||||
try:
|
||||
user = bot.create_new_acc()
|
||||
print(f"Created: {user['username']}")
|
||||
except Exception as exc:
|
||||
print(f"ERROR creating account: {exc}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
p = argparse.ArgumentParser(
|
||||
prog="bot_cli",
|
||||
@ -98,6 +114,10 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
sp.add_argument("t_password")
|
||||
sp.set_defaults(func=cmd_transfer)
|
||||
|
||||
sp = sub.add_parser("monitor-once", aliases=["monitor"], help="One iteration of the auto-create monitor.")
|
||||
sp.add_argument("--target", type=int, default=20)
|
||||
sp.set_defaults(func=cmd_monitor_once)
|
||||
|
||||
return p
|
||||
|
||||
|
||||
|
||||
@ -188,5 +188,58 @@ class CmdTransferTests(unittest.TestCase):
|
||||
self.assertIs(args.func, bot_cli.cmd_transfer)
|
||||
|
||||
|
||||
class CmdMonitorOnceTests(unittest.TestCase):
|
||||
@mock.patch.object(bot_cli, "CM_BOT_HAL")
|
||||
def test_does_nothing_when_already_at_target(self, mock_hal_class):
|
||||
mock_hal = mock_hal_class.return_value
|
||||
mock_hal.get_all_available_acc.return_value = [{"username": f"u{i}"} for i in range(20)]
|
||||
out = io.StringIO()
|
||||
with contextlib.redirect_stdout(out):
|
||||
bot_cli.cmd_monitor_once(argparse.Namespace(target=20))
|
||||
text = out.getvalue()
|
||||
self.assertIn("Available accounts: 20", text)
|
||||
self.assertIn("Already at target", text)
|
||||
mock_hal.create_new_acc.assert_not_called()
|
||||
|
||||
@mock.patch.object(bot_cli, "CM_BOT_HAL")
|
||||
def test_creates_accounts_until_target(self, mock_hal_class):
|
||||
mock_hal = mock_hal_class.return_value
|
||||
mock_hal.get_all_available_acc.return_value = [{"username": "u1"}, {"username": "u2"}]
|
||||
mock_hal.create_new_acc.side_effect = [
|
||||
{"username": "u3", "password": "p3", "link": "l3"},
|
||||
{"username": "u4", "password": "p4", "link": "l4"},
|
||||
{"username": "u5", "password": "p5", "link": "l5"},
|
||||
]
|
||||
out = io.StringIO()
|
||||
with contextlib.redirect_stdout(out):
|
||||
bot_cli.cmd_monitor_once(argparse.Namespace(target=5))
|
||||
text = out.getvalue()
|
||||
self.assertEqual(mock_hal.create_new_acc.call_count, 3)
|
||||
self.assertIn("Created: u3", text)
|
||||
self.assertIn("Created: u4", text)
|
||||
self.assertIn("Created: u5", text)
|
||||
|
||||
@mock.patch.object(bot_cli, "CM_BOT_HAL")
|
||||
def test_create_failure_exits_1(self, mock_hal_class):
|
||||
mock_hal = mock_hal_class.return_value
|
||||
mock_hal.get_all_available_acc.return_value = []
|
||||
mock_hal.create_new_acc.side_effect = RuntimeError("fail login")
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
bot_cli.cmd_monitor_once(argparse.Namespace(target=1))
|
||||
self.assertEqual(cm.exception.code, 1)
|
||||
|
||||
def test_monitor_once_subparser_dispatches(self):
|
||||
parser = bot_cli.build_parser()
|
||||
args = parser.parse_args(["monitor-once", "--target", "7"])
|
||||
self.assertIs(args.func, bot_cli.cmd_monitor_once)
|
||||
self.assertEqual(args.target, 7)
|
||||
|
||||
def test_monitor_alias_dispatches(self):
|
||||
parser = bot_cli.build_parser()
|
||||
args = parser.parse_args(["monitor"])
|
||||
self.assertIs(args.func, bot_cli.cmd_monitor_once)
|
||||
self.assertEqual(args.target, 20)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user