feat(bot_cli): add insert-user subcommand (Telegram /3 analog)

This commit is contained in:
yiekheng 2026-05-02 16:59:10 +08:00
parent 66d5feaea1
commit 5844d7598a
2 changed files with 68 additions and 0 deletions

View File

@ -36,6 +36,24 @@ def cmd_set_pin(args):
print(f"OK: f_username={f_username} t_username={t_username}")
def cmd_insert_user(args):
bot = CM_BOT_HAL()
f_password = bot.get_user_pass_from_acc(args.f_username)
if not f_password:
print(f"ERROR: no password for {args.f_username}", file=sys.stderr)
sys.exit(2)
success = bot.insert_user_to_table_user({
"f_username": args.f_username,
"f_password": f_password,
"t_username": args.t_username,
"t_password": bot.security_pin,
})
if not success:
print("ERROR: insert failed", file=sys.stderr)
sys.exit(1)
print(f"OK: inserted {args.f_username}{args.t_username}")
def build_parser() -> argparse.ArgumentParser:
p = argparse.ArgumentParser(
prog="bot_cli",
@ -50,6 +68,11 @@ def build_parser() -> argparse.ArgumentParser:
sp.add_argument("link")
sp.set_defaults(func=cmd_set_pin)
sp = sub.add_parser("insert-user", help="Insert into user table (Telegram /3).")
sp.add_argument("f_username")
sp.add_argument("t_username")
sp.set_defaults(func=cmd_insert_user)
return p

View File

@ -106,5 +106,50 @@ class CmdSetPinTests(unittest.TestCase):
self.assertEqual(args.link, "https://chat.whatsapp.com/abc")
class CmdInsertUserTests(unittest.TestCase):
@mock.patch.object(bot_cli, "CM_BOT_HAL")
def test_inserts_using_password_lookup_and_security_pin(self, mock_hal_class):
mock_hal = mock_hal_class.return_value
mock_hal.get_user_pass_from_acc.return_value = "abc12345"
mock_hal.security_pin = "999111"
mock_hal.insert_user_to_table_user.return_value = True
out = io.StringIO()
with contextlib.redirect_stdout(out):
bot_cli.cmd_insert_user(argparse.Namespace(f_username="13c1234", t_username="player_x"))
self.assertIn("OK: inserted 13c1234 → player_x", out.getvalue())
mock_hal.insert_user_to_table_user.assert_called_once_with({
"f_username": "13c1234",
"f_password": "abc12345",
"t_username": "player_x",
"t_password": "999111",
})
@mock.patch.object(bot_cli, "CM_BOT_HAL")
def test_no_password_for_f_user_exits_2(self, mock_hal_class):
mock_hal = mock_hal_class.return_value
mock_hal.get_user_pass_from_acc.return_value = None
with self.assertRaises(SystemExit) as cm:
bot_cli.cmd_insert_user(argparse.Namespace(f_username="missing", t_username="player_x"))
self.assertEqual(cm.exception.code, 2)
mock_hal.insert_user_to_table_user.assert_not_called()
@mock.patch.object(bot_cli, "CM_BOT_HAL")
def test_insert_failure_exits_1(self, mock_hal_class):
mock_hal = mock_hal_class.return_value
mock_hal.get_user_pass_from_acc.return_value = "abc"
mock_hal.security_pin = "000"
mock_hal.insert_user_to_table_user.return_value = False
with self.assertRaises(SystemExit) as cm:
bot_cli.cmd_insert_user(argparse.Namespace(f_username="13c1234", t_username="player_x"))
self.assertEqual(cm.exception.code, 1)
def test_insert_user_subparser_dispatches(self):
parser = bot_cli.build_parser()
args = parser.parse_args(["insert-user", "13c1234", "player_x"])
self.assertIs(args.func, bot_cli.cmd_insert_user)
self.assertEqual(args.f_username, "13c1234")
self.assertEqual(args.t_username, "player_x")
if __name__ == "__main__":
unittest.main()