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
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user