feat(kpi): expand KPI runtime monitoring, prompt advisory envelopes, and missing field resiliency
This commit is contained in:
@@ -12,6 +12,7 @@ REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(REPO_ROOT / "bin"))
|
||||
|
||||
import invite
|
||||
import invite_handler
|
||||
from invite_handler import InviteCodeInfo, InviteHandler, RedemptionResult, salvage_blocked_node
|
||||
from settings_rpa import NodeUsage, SettingsRPA
|
||||
|
||||
@@ -176,7 +177,136 @@ class TestInviteHandlerMocked(unittest.TestCase):
|
||||
self.assertFalse(res["success"])
|
||||
self.assertEqual(res["invite_code"], "REDCJ7")
|
||||
self.assertIn("An onboarding agent or fresh client profile must redeem this code", res["error"])
|
||||
self.assertTrue(res.get("field_missing"))
|
||||
|
||||
def test_salvage_blocked_node_with_loopback_dm(self):
|
||||
with patch.object(InviteHandler, "find_code") as mock_find:
|
||||
mock_find.return_value = InviteCodeInfo(
|
||||
node="646",
|
||||
code="REDCJ7",
|
||||
uses_remaining=30,
|
||||
use_count=0,
|
||||
max_uses=30,
|
||||
has_redeemed=True,
|
||||
invite_state="ELIGIBLE",
|
||||
reward=None,
|
||||
method_used="api",
|
||||
)
|
||||
with patch("invite_handler.send_loopback_notice", return_value=True) as mock_notice:
|
||||
res = salvage_blocked_node("646", notify_target="heartbeat-opm", notify_agent="opm")
|
||||
self.assertFalse(res["success"])
|
||||
self.assertTrue(res.get("field_missing"))
|
||||
self.assertTrue(res.get("loopback_notified"))
|
||||
mock_notice.assert_called_once()
|
||||
call_args = mock_notice.call_args[0]
|
||||
self.assertEqual(call_args[0], "opm")
|
||||
self.assertEqual(call_args[1], "heartbeat-opm")
|
||||
self.assertIn("REDCJ7", call_args[2])
|
||||
|
||||
@patch("invite_handler.SettingsRPA")
|
||||
def test_redeem_code_dom_missing_row_api_fallback_success(self, mock_rpa_cls):
|
||||
mock_rpa = MagicMock()
|
||||
mock_rpa.open_settings_dialog.return_value = True
|
||||
mock_rpa.select_tab.return_value = True
|
||||
mock_rpa_cls.return_value.__enter__.return_value = mock_rpa
|
||||
|
||||
h = InviteHandler("dev")
|
||||
h.ws = MagicMock()
|
||||
with patch.object(h, "connect"), patch("time.sleep", return_value=None):
|
||||
with patch("invite_handler.cdp_evaluate", return_value={"found": False, "text": "General"}):
|
||||
with patch.object(h, "redeem_code_api") as mock_api:
|
||||
mock_api.return_value = RedemptionResult(
|
||||
target_node="dev",
|
||||
code="REDCJ7",
|
||||
success=True,
|
||||
status="redeemed",
|
||||
reason=None,
|
||||
detail="API success",
|
||||
method_used="api",
|
||||
)
|
||||
res = h.redeem_code_dom("REDCJ7")
|
||||
self.assertTrue(res.success)
|
||||
self.assertEqual(res.status, "redeemed")
|
||||
self.assertIn("Redeem field was missing in Settings DOM; redeemed successfully via API fallback!", res.detail)
|
||||
mock_rpa.close_settings_dialog.assert_called_once()
|
||||
|
||||
@patch("invite_handler.SettingsRPA")
|
||||
def test_redeem_code_dom_missing_row_already_redeemed(self, mock_rpa_cls):
|
||||
mock_rpa = MagicMock()
|
||||
mock_rpa.open_settings_dialog.return_value = True
|
||||
mock_rpa.select_tab.return_value = True
|
||||
mock_rpa_cls.return_value.__enter__.return_value = mock_rpa
|
||||
|
||||
h = InviteHandler("646")
|
||||
h.ws = MagicMock()
|
||||
with patch.object(h, "connect"), patch("time.sleep", return_value=None):
|
||||
with patch("invite_handler.cdp_evaluate", return_value={"found": False, "has_additional": True, "text": "Additional tokens"}):
|
||||
with patch.object(h, "redeem_code_api") as mock_api:
|
||||
mock_api.return_value = RedemptionResult(
|
||||
target_node="646",
|
||||
code="REDCJ7",
|
||||
success=False,
|
||||
status="already_redeemed",
|
||||
reason="already_redeemed",
|
||||
detail="Already redeemed",
|
||||
method_used="api",
|
||||
)
|
||||
res = h.redeem_code_dom("REDCJ7")
|
||||
self.assertFalse(res.success)
|
||||
self.assertEqual(res.status, "already_redeemed")
|
||||
self.assertTrue(res.field_missing)
|
||||
self.assertIn("already redeemed an invite code", res.detail)
|
||||
|
||||
@patch("invite_handler.SettingsRPA")
|
||||
def test_redeem_code_dom_missing_input_box_with_loopback(self, mock_rpa_cls):
|
||||
mock_rpa = MagicMock()
|
||||
mock_rpa.open_settings_dialog.return_value = True
|
||||
mock_rpa.select_tab.return_value = True
|
||||
mock_rpa_cls.return_value.__enter__.return_value = mock_rpa
|
||||
|
||||
h = InviteHandler("pip")
|
||||
h.ws = MagicMock()
|
||||
|
||||
def mock_eval(ws, js, *args, **kwargs):
|
||||
if "Redeem invite code" in js:
|
||||
return {"found": True}
|
||||
if "found_input" in js:
|
||||
return {"found_input": False}
|
||||
return True
|
||||
|
||||
with patch.object(h, "connect"), patch("time.sleep", return_value=None):
|
||||
with patch("invite_handler.cdp_evaluate", side_effect=mock_eval), patch("invite_handler.cdp_send_escape"):
|
||||
with patch.object(h, "redeem_code_api") as mock_api:
|
||||
mock_api.return_value = RedemptionResult(
|
||||
target_node="pip",
|
||||
code="TEST01",
|
||||
success=False,
|
||||
status="dom_input_missing",
|
||||
reason="input_field_missing",
|
||||
detail="API fallback also failed",
|
||||
method_used="api",
|
||||
)
|
||||
with patch("invite_handler.send_loopback_notice", return_value=True) as mock_notice:
|
||||
res = h.redeem_code_dom("TEST01", notify_target="pip tasks", notify_agent="pip")
|
||||
self.assertFalse(res.success)
|
||||
self.assertTrue(res.field_missing)
|
||||
self.assertEqual(res.reason, "input_field_missing")
|
||||
self.assertTrue(res.loopback_notified)
|
||||
mock_notice.assert_called_once()
|
||||
self.assertIn("pip tasks", res.loopback_detail)
|
||||
|
||||
@patch("subprocess.run")
|
||||
def test_send_loopback_notice(self, mock_subproc):
|
||||
mock_subproc.return_value = MagicMock(returncode=0)
|
||||
ok = invite_handler.send_loopback_notice("opm", "646 tasks", "Test alert")
|
||||
self.assertTrue(ok)
|
||||
mock_subproc.assert_called_once()
|
||||
cmd = mock_subproc.call_args[0][0]
|
||||
self.assertIn("send", cmd)
|
||||
self.assertIn("646 tasks", cmd)
|
||||
self.assertIn("Test alert", cmd)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user