Files
box/tests/test_invite.py
T
operator b824f6d405 feat(box): add invite code handler, Settings RPA, and agent onboarding pipeline
- Support invite code discovery in main chat and redemption in settings menu
- Add Settings RPA primitives with Radix UI mouse dispatch and retry polling for async DOM
- Attribute 'has_redeemed' binary from the Additional tokens ticker / entrypoint visibility
- Unblock agent @646 by repairing warp-def/dev tunnels and redeeming REDCJ7 via dev (+1B tokens)
- Implement 'box onboard' pipeline to provision infra, authenticate, and auto-redeem queued codes
- Add 'box onboard feed-matrix' ranking all agents by work done over time, job count, and role
- Register 'InputType.SALVAGE' in loop modulation (CRITICAL priority, 600s timeout, 3 nudges to opm)
- Ingest recurring balance audits into canonical HEARTBEAT.md and TOOLS.md
2026-10-06 19:33:17 +00:00

262 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Tests for the invite code + usage handler (mocked CDP).
No live browser traffic: get_cdp_ws / cdp_evaluate are patched and the
DOM/API contracts asserted from fixtures captured live from muse.ai.
"""
import sys
import unittest
from pathlib import Path
from unittest import mock
REPO_ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(REPO_ROOT / "bin"))
import invite
API_OK = {"status": 200, "data": {
"code": "F4BGHN", "has_redeemed_invite_code": True,
"uses_remaining": 30, "use_count": 0, "reward": None}}
POPOVER_TEXT = (
"Invite friends\n\nInvite a friend and you'll both get 1 billion Muse "
"tokens when they redeem your code in Settings within 48 hours of "
"joining. 30 uses left.\n\nF4BGHN\n"
"Invite code revealed: F4BGHN\nCopy referral link")
PIP_GENERAL = (
"General\nWallet\nWeekly limit resets on Oct 10\n100% used\n"
"Additional tokens\nNever expires\n10% used (901M tokens left)\n"
"Upgrade\nLanguage\nAppearance\nMode\nTheme color")
SIX_GENERAL = (
"100% used\nAdditional tokens\nNever expires\n"
"100% used (0 tokens left)\nUpgrade\nLanguage\nAppearance\n"
"Mode\nTheme color")
class NormalizeTests(unittest.TestCase):
def test_accepts_and_normalizes(self):
self.assertEqual(invite.normalize_code("F4BGHN"), "F4BGHN")
self.assertEqual(invite.normalize_code("f4bghn"), "F4BGHN")
self.assertEqual(invite.normalize_code(" redcj7\n"), "REDCJ7")
def test_rejects_malformed(self):
for bad in ("", "ABC12", "ABCDEFG", "ABC-12", "ABC 12",
"abcde!", None, 123, "F4BGH\nN"):
self.assertIsNone(invite.normalize_code(bad), bad)
class GetInviteTests(unittest.TestCase):
def setUp(self):
p = mock.patch("time.sleep")
p.start()
self.addCleanup(p.stop)
g = mock.patch.object(invite, "get_cdp_ws",
return_value=(mock.Mock(), {}))
self.get_ws = g.start()
self.addCleanup(g.stop)
c = mock.patch.object(invite, "cdp_evaluate")
self.cdp = c.start()
self.addCleanup(c.stop)
def test_bad_node_before_cdp(self):
with self.assertRaises(invite.InviteError):
invite.get_invite("nope")
self.get_ws.assert_not_called()
def test_api_success(self):
self.cdp.return_value = dict(API_OK)
res = invite.get_invite("pip")
self.assertEqual(res, {"ok": True, "node": "pip", "source": "api",
"code": "F4BGHN", "has_redeemed": True,
"uses_remaining": 30, "use_count": 0,
"reward": None})
def test_api_failure_falls_back_to_popover(self):
self.cdp.side_effect = [{"error": "boom"}, "CLICKED",
POPOVER_TEXT, "ESC"]
res = invite.get_invite("pip")
self.assertTrue(res["ok"])
self.assertEqual(res["source"], "dom")
self.assertEqual(res["code"], "F4BGHN")
self.assertIsNone(res["has_redeemed"])
def test_no_api_no_popover(self):
self.cdp.side_effect = [None, "NO_BUTTON", "ESC"]
res = invite.get_invite("pip")
self.assertFalse(res["ok"])
self.assertIn("popover", res["error"])
def test_connection_error(self):
self.get_ws.side_effect = ConnectionError("refused")
res = invite.get_invite("def")
self.assertFalse(res["ok"])
self.assertIn("CDP", res["error"])
class RedeemTests(unittest.TestCase):
def setUp(self):
g = mock.patch.object(invite, "get_cdp_ws",
return_value=(mock.Mock(), {}))
self.get_ws = g.start()
self.addCleanup(g.stop)
c = mock.patch.object(invite, "cdp_evaluate")
self.cdp = c.start()
self.addCleanup(c.stop)
def test_bad_code_before_cdp(self):
for bad in ("xyz", "", None, "ABC-12"):
with self.assertRaises(invite.InviteError, msg=bad):
invite.redeem_invite("646", bad)
self.get_ws.assert_not_called()
def test_bad_node_before_cdp(self):
with self.assertRaises(invite.InviteError):
invite.redeem_invite("nope", "F4BGHN")
self.get_ws.assert_not_called()
def test_success(self):
self.cdp.return_value = {"status": 200, "ok": True, "data": {
"success": True, "redemptionStatus": "redeemed",
"detail": "You both got 1 billion Muse tokens."}}
res = invite.redeem_invite("646", "f4bghn")
self.assertTrue(res["ok"])
self.assertEqual(res["code"], "F4BGHN")
self.assertEqual(res["redemption_status"], "redeemed")
sent_js = self.cdp.call_args[0][1]
self.assertIn("F4BGHN", sent_js)
def test_reason_passthrough(self):
self.cdp.return_value = {"status": 400, "ok": False, "data": {
"success": False, "reason": "already_redeemed",
"detail": "You’ve already redeemed an invite code."}}
res = invite.redeem_invite("muse", "REDCJ7")
self.assertFalse(res["ok"])
self.assertEqual(res["reason"], "already_redeemed")
self.assertIn("already redeemed", res["detail"])
def test_transport_error(self):
self.cdp.side_effect = RuntimeError("ws blew up")
res = invite.redeem_invite("646", "F4BGHN")
self.assertFalse(res["ok"])
self.assertIn("ws blew up", res["error"])
def test_connection_error(self):
self.get_ws.side_effect = ConnectionError("refused")
res = invite.redeem_invite("646", "F4BGHN")
self.assertFalse(res["ok"])
self.assertEqual(res["code"], "F4BGHN")
class UsageTests(unittest.TestCase):
def test_parse_pip_general(self):
self.assertEqual(invite.parse_usage_text(PIP_GENERAL), {
"weekly_reset": "Oct 10", "weekly_used_pct": 100,
"additional_expires": "Never expires",
"additional_used_pct": 10,
"additional_left": "901M tokens left",
"has_redeemed": True})
def test_parse_646_general_partial(self):
self.assertEqual(invite.parse_usage_text(SIX_GENERAL), {
"weekly_reset": None, "weekly_used_pct": 100,
"additional_expires": "Never expires",
"additional_used_pct": 100,
"additional_left": "0 tokens left",
"has_redeemed": True})
def test_parse_empty(self):
self.assertEqual(invite.parse_usage_text(""), {
"weekly_reset": None, "weekly_used_pct": None,
"additional_expires": None, "additional_used_pct": None,
"additional_left": None, "has_redeemed": False})
def test_bad_node_before_cdp(self):
with mock.patch.object(invite, "get_cdp_ws") as g:
with self.assertRaises(invite.InviteError):
invite.get_usage("nope")
g.assert_not_called()
def test_settings_open_failure(self):
with mock.patch.object(invite, "get_cdp_ws",
return_value=(mock.Mock(), {})), \
mock.patch.object(invite, "open_settings",
return_value=False):
res = invite.get_usage("pip")
self.assertFalse(res["ok"])
self.assertIn("did not open", res["error"])
def test_success(self):
with mock.patch.object(invite, "get_cdp_ws",
return_value=(mock.Mock(), {})), \
mock.patch.object(invite, "open_settings",
return_value=True), \
mock.patch("hatch_menu.dialog.goto_tab",
return_value=True), \
mock.patch("hatch_menu.dialog.dialog_text",
return_value=PIP_GENERAL):
res = invite.get_usage("pip")
self.assertTrue(res["ok"])
self.assertEqual(res["weekly_reset"], "Oct 10")
self.assertEqual(res["additional_left"], "901M tokens left")
self.assertTrue(res["has_redeemed"])
def test_general_tab_failure(self):
with mock.patch.object(invite, "get_cdp_ws",
return_value=(mock.Mock(), {})), \
mock.patch.object(invite, "open_settings",
return_value=True), \
mock.patch("hatch_menu.dialog.goto_tab",
return_value=False):
res = invite.get_usage("pip")
self.assertFalse(res["ok"])
self.assertIn("General tab", res["error"])
class FleetTests(unittest.TestCase):
def test_invite_status_aggregates_and_never_raises(self):
with mock.patch.object(
invite, "get_invite",
side_effect=[{"ok": True, "node": "646"},
invite.InviteError("bad")]):
res = invite.fleet_invite_status(["646", "bogus"])
self.assertTrue(res["646"]["ok"])
self.assertFalse(res["bogus"]["ok"])
def test_usage_aggregates(self):
with mock.patch.object(
invite, "get_usage",
return_value={"ok": True, "node": "pip"}):
res = invite.fleet_usage(["pip"])
self.assertTrue(res["pip"]["ok"])
class ShimTests(unittest.TestCase):
"""open_settings/click_settings_tab delegate to the tree (single copy).
Trusted-click behavior itself is covered by tests/test_hatch_menu.py.
"""
def test_open_settings_delegates(self):
ws = mock.Mock()
with mock.patch("hatch_menu.dialog.open_settings",
return_value=True) as m:
self.assertTrue(invite.open_settings(ws))
m.assert_called_once_with(ws)
def test_open_settings_failure_passthrough(self):
with mock.patch("hatch_menu.dialog.open_settings",
return_value=False):
self.assertFalse(invite.open_settings(mock.Mock()))
def test_click_settings_tab_delegates(self):
ws = mock.Mock()
with mock.patch("hatch_menu.dialog.goto_tab",
return_value=True) as m:
self.assertTrue(invite.click_settings_tab(ws, "General"))
m.assert_called_once_with(ws, "General")
if __name__ == "__main__":
unittest.main()