Files
box/tests/test_settings_rpa.py
T

136 lines
5.6 KiB
Python

#!/usr/bin/env python3
"""test_settings_rpa.py: Unit tests for Settings RPA substrate."""
import json
import sys
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch
REPO_ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(REPO_ROOT / "bin"))
from settings_rpa import NodeUsage, SettingsRPA, cdp_dispatch_mouse_click, cdp_send_command
class TestSettingsRPAPrimitives(unittest.TestCase):
def test_cdp_send_command_matches_id(self):
mock_ws = MagicMock()
mock_ws.recv.return_value = json.dumps({"id": 10000, "result": {"success": True}})
# Mock _REQ_COUNTER next value
with patch("settings_rpa._REQ_COUNTER", iter([10000])):
res = cdp_send_command(mock_ws, "Test.method", {"param": 1})
self.assertEqual(res, {"success": True})
mock_ws.send.assert_called_once()
sent_msg = json.loads(mock_ws.send.call_args[0][0])
self.assertEqual(sent_msg["method"], "Test.method")
def test_cdp_dispatch_mouse_click(self):
mock_ws = MagicMock()
with patch("settings_rpa.cdp_send_command") as mock_send:
mock_send.return_value = {}
res = cdp_dispatch_mouse_click(mock_ws, 100.0, 200.0)
self.assertTrue(res)
self.assertEqual(mock_send.call_count, 2)
# Check mousePressed and mouseReleased
call_methods = [c[0][1] for c in mock_send.call_args_list]
self.assertEqual(call_methods, ["Input.dispatchMouseEvent", "Input.dispatchMouseEvent"])
@patch("settings_rpa.get_cdp_ws")
@patch("settings_rpa.cdp_evaluate")
def test_settings_dialog_check(self, mock_eval, mock_ws):
mock_ws.return_value = (MagicMock(), MagicMock())
mock_eval.return_value = True
rpa = SettingsRPA("646")
rpa.connect()
self.assertTrue(rpa.is_settings_dialog_open())
@patch("settings_rpa.get_cdp_ws")
@patch("settings_rpa.cdp_evaluate")
def test_read_usage_blocked(self, mock_eval, mock_ws):
mock_ws.return_value = (MagicMock(), MagicMock())
# Provide responses: open check (True), tab open check (True), click tab (True), usage dict
usage_payload = {
"dialogText": "Free plan\nWeekly limit resets on Oct 9\n100% used\nAdditional tokens\n100% used (0 tokens left)",
"bars": [
{"label": "Free plan", "percent": 100, "raw_text": "Free plan\nWeekly limit resets on Oct 9\n100% used"},
{"label": "Additional tokens", "percent": 100, "raw_text": "Additional tokens\n100% used (0 tokens left)"},
],
"plan": "Free plan",
"resetText": "Weekly limit resets on Oct 9",
"tokensLeft": "0 tokens left",
}
mock_eval.side_effect = [
True, # is_settings_dialog_open
True, # is_settings_dialog_open in select_tab
True, # click General tab
usage_payload, # read_usage evaluation
]
with SettingsRPA("646") as rpa:
usage = rpa.read_usage(keep_dialog_open=True)
self.assertEqual(usage.node, "646")
self.assertEqual(usage.weekly_percent_used, 100)
self.assertEqual(usage.extra_percent_used, 100)
self.assertTrue(usage.is_blocked)
self.assertEqual(usage.extra_tokens_remaining, "0 tokens left")
self.assertTrue(usage.has_redeemed)
@patch("settings_rpa.get_cdp_ws")
@patch("settings_rpa.cdp_evaluate")
def test_read_usage_not_redeemed(self, mock_eval, mock_ws):
mock_ws.return_value = (MagicMock(), MagicMock())
usage_payload = {
"dialogText": "Free plan\nWeekly limit resets on Oct 9\n20% used\nRedeem invite code",
"bars": [
{"label": "Free plan", "percent": 20, "raw_text": "Free plan\nWeekly limit resets on Oct 9\n20% used"},
],
"plan": "Free plan",
"resetText": "Weekly limit resets on Oct 9",
"tokensLeft": "",
}
mock_eval.side_effect = [
True, # is_settings_dialog_open
True, # is_settings_dialog_open in select_tab
True, # click General tab
usage_payload, # read_usage evaluation
]
with SettingsRPA("646") as rpa:
usage = rpa.read_usage(keep_dialog_open=True)
self.assertEqual(usage.node, "646")
self.assertEqual(usage.weekly_percent_used, 20)
self.assertEqual(usage.extra_percent_used, 0)
self.assertFalse(usage.is_blocked)
self.assertFalse(usage.has_redeemed)
self.assertTrue(usage.stats_loaded)
@patch("settings_rpa.get_cdp_ws")
@patch("settings_rpa.cdp_evaluate")
def test_read_usage_stats_did_not_render(self, mock_eval, mock_ws):
mock_ws.return_value = (MagicMock(), MagicMock())
def eval_side_effect(ws, js, *args, **kwargs):
if "role=\"dialog\"" in js and "Weekly limit" in js:
return None
return True
mock_eval.side_effect = eval_side_effect
with SettingsRPA("646", timeout=0.5) as rpa:
# Shorten deadline by patching time.time or passing small timeout
with patch("time.sleep", return_value=None):
usage = rpa.read_usage(keep_dialog_open=True)
self.assertEqual(usage.node, "646")
self.assertFalse(usage.stats_loaded)
self.assertFalse(usage.is_blocked)
self.assertIn("Unavailable", usage.weekly_reset_text)
self.assertEqual(usage.extra_tokens_remaining, "Unavailable")
if __name__ == "__main__":
unittest.main()