Spaces:
Running
Running
Download test_robinhood.py from Simzy/command-center-chat: direct link, hf CLI and curl.
- Browser
- Download file 11.1 kB
-
https://huggingface.co/spaces/Simzy/command-center-chat/resolve/main/test_robinhood.py
- Command line
-
hf download hf://spaces/Simzy/command-center-chat/test_robinhood.py
-
curl -L -o test_robinhood.py https://huggingface.co/spaces/Simzy/command-center-chat/resolve/main/test_robinhood.py
11.1 kB
| import json | |
| import os | |
| import unittest | |
| import uuid | |
| from fastapi.testclient import TestClient | |
| from main import RATE, app, refresh_file, snapshot_file | |
| SAMPLE = { | |
| "updatedAt": "2026-09-28T15:04:00Z", | |
| "account": {"label": "", "last4": "999988886740", "accountNumber": "1234999988886740"}, | |
| "totalValue": 118532.25, | |
| "equityValue": 175464.27, | |
| "cryptoValue": 26130.89, | |
| "cash": -83062.91, | |
| "currency": "USD", | |
| "positions": [ | |
| { | |
| "symbol": "pltr", | |
| "quantity": 149.998, | |
| "avgCost": 142.02, | |
| "price": 0, | |
| "marketValue": 0, | |
| "dayChangePct": None, | |
| } | |
| ], | |
| } | |
| class RobinhoodBridgeTest(unittest.TestCase): | |
| def setUp(self) -> None: | |
| self._env = { | |
| "ROBINHOOD_BRIDGE_SECRET": os.environ.get("ROBINHOOD_BRIDGE_SECRET"), | |
| "CHAT_BRIDGE_SECRET": os.environ.get("CHAT_BRIDGE_SECRET"), | |
| } | |
| os.environ.pop("ROBINHOOD_BRIDGE_SECRET", None) | |
| os.environ["CHAT_BRIDGE_SECRET"] = "chat-secret-value" | |
| RATE.clear() | |
| self._wipe_files() | |
| self.client = TestClient(app) | |
| def tearDown(self) -> None: | |
| self.client.close() | |
| self._wipe_files() | |
| for key, value in self._env.items(): | |
| if value is None: | |
| os.environ.pop(key, None) | |
| else: | |
| os.environ[key] = value | |
| def _wipe_files(self) -> None: | |
| for path in (snapshot_file(), refresh_file()): | |
| if path.exists(): | |
| path.unlink() | |
| tmp = path.with_suffix(path.suffix + ".tmp") | |
| if tmp.exists(): | |
| tmp.unlink() | |
| def test_get_empty_snapshot_is_public(self) -> None: | |
| res = self.client.get("/api/robinhood") | |
| self.assertEqual(res.status_code, 200) | |
| self.assertEqual(res.json(), {"snapshot": None, "refreshPending": False}) | |
| self.assertEqual(res.headers.get("cache-control"), "no-store") | |
| def test_post_requires_bearer_and_masks_account(self) -> None: | |
| denied = self.client.post("/api/robinhood", json=SAMPLE) | |
| self.assertEqual(denied.status_code, 401) | |
| wrong = self.client.post( | |
| "/api/robinhood", | |
| json=SAMPLE, | |
| headers={"Authorization": "Bearer nope"}, | |
| ) | |
| self.assertEqual(wrong.status_code, 401) | |
| ok = self.client.post( | |
| "/api/robinhood", | |
| json=SAMPLE, | |
| headers={"Authorization": "Bearer chat-secret-value"}, | |
| ) | |
| self.assertEqual(ok.status_code, 200) | |
| self.assertEqual(ok.json()["updatedAt"], "2026-09-28T15:04:00Z") | |
| got = self.client.get("/api/robinhood") | |
| snapshot = got.json()["snapshot"] | |
| self.assertEqual(snapshot["account"], {"label": "Individual", "last4": "6740"}) | |
| self.assertNotIn("accountNumber", snapshot["account"]) | |
| self.assertNotIn("1234999988886740", got.text) | |
| self.assertEqual(snapshot["totalValue"], 118532.25) | |
| self.assertEqual(snapshot["positions"][0]["symbol"], "PLTR") | |
| self.assertEqual(snapshot["positions"][0]["price"], 0) | |
| def test_post_replaces_snapshot(self) -> None: | |
| headers = {"Authorization": "Bearer chat-secret-value"} | |
| self.client.post("/api/robinhood", json=SAMPLE, headers=headers) | |
| replaced = dict(SAMPLE) | |
| replaced["totalValue"] = 10 | |
| replaced["positions"] = [] | |
| res = self.client.post("/api/robinhood", json=replaced, headers=headers) | |
| self.assertEqual(res.status_code, 200) | |
| snapshot = self.client.get("/api/robinhood").json()["snapshot"] | |
| self.assertEqual(snapshot["totalValue"], 10) | |
| self.assertEqual(snapshot["positions"], []) | |
| def test_dedicated_secret_replaces_chat_secret(self) -> None: | |
| os.environ["ROBINHOOD_BRIDGE_SECRET"] = "rh-secret-value" | |
| chat = self.client.post( | |
| "/api/robinhood", | |
| json=SAMPLE, | |
| headers={"Authorization": "Bearer chat-secret-value"}, | |
| ) | |
| self.assertEqual(chat.status_code, 401) | |
| ok = self.client.post( | |
| "/api/robinhood", | |
| json=SAMPLE, | |
| headers={"Authorization": "Bearer rh-secret-value"}, | |
| ) | |
| self.assertEqual(ok.status_code, 200) | |
| def test_missing_secret_is_not_open(self) -> None: | |
| os.environ.pop("ROBINHOOD_BRIDGE_SECRET", None) | |
| os.environ.pop("CHAT_BRIDGE_SECRET", None) | |
| res = self.client.post("/api/robinhood", json=SAMPLE, headers={"Authorization": "Bearer anything"}) | |
| self.assertEqual(res.status_code, 500) | |
| def test_chat_reply_still_uses_chat_secret(self) -> None: | |
| os.environ["ROBINHOOD_BRIDGE_SECRET"] = "rh-secret-value" | |
| body = { | |
| "sessionId": str(uuid.UUID("aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa")), | |
| "clientMsgId": "cmt_test", | |
| "botId": "chief", | |
| "text": "ok", | |
| "status": "final", | |
| } | |
| denied = self.client.post( | |
| "/api/chat/reply", | |
| json=body, | |
| headers={"Authorization": "Bearer rh-secret-value"}, | |
| ) | |
| self.assertEqual(denied.status_code, 401) | |
| ok = self.client.post( | |
| "/api/chat/reply", | |
| json=body, | |
| headers={"Authorization": "Bearer chat-secret-value"}, | |
| ) | |
| self.assertEqual(ok.status_code, 200) | |
| polled = self.client.get(f"/api/chat?sessionId={body['sessionId']}") | |
| self.assertEqual(polled.status_code, 200) | |
| self.assertEqual(polled.json()["messages"][-1]["text"], "ok") | |
| def test_refresh_request_is_public_and_rate_limited_per_ip(self) -> None: | |
| os.environ.pop("ROBINHOOD_BRIDGE_SECRET", None) | |
| os.environ.pop("CHAT_BRIDGE_SECRET", None) | |
| first = self.client.post("/api/robinhood/refresh", headers={"X-Forwarded-For": "203.0.113.10"}) | |
| self.assertEqual(first.status_code, 200) | |
| body = first.json() | |
| self.assertTrue(body["ok"]) | |
| self.assertTrue(body["refreshPending"]) | |
| self.assertRegex(body["requestedAt"], r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$") | |
| self.assertEqual(first.headers.get("cache-control"), "no-store") | |
| stored = json.loads(refresh_file().read_text(encoding="utf-8")) | |
| self.assertEqual(stored, {"requestedAt": body["requestedAt"]}) | |
| again = self.client.post("/api/robinhood/refresh", headers={"X-Forwarded-For": "203.0.113.10"}) | |
| self.assertEqual(again.status_code, 429) | |
| other = self.client.post("/robinhood/refresh", headers={"X-Forwarded-For": "203.0.113.11"}) | |
| self.assertEqual(other.status_code, 200) | |
| def test_refresh_pending_until_snapshot_is_newer(self) -> None: | |
| headers = {"Authorization": "Bearer chat-secret-value"} | |
| old = dict(SAMPLE) | |
| old["updatedAt"] = "2020-01-01T00:00:00Z" | |
| self.client.post("/api/robinhood", json=old, headers=headers) | |
| asked = self.client.post("/api/robinhood/refresh", headers={"X-Forwarded-For": "203.0.113.12"}) | |
| requested_at = asked.json()["requestedAt"] | |
| got = self.client.get("/api/robinhood") | |
| body = got.json() | |
| self.assertEqual(got.headers.get("cache-control"), "no-store") | |
| self.assertTrue(body["refreshPending"]) | |
| self.assertEqual(body["refreshRequestedAt"], requested_at) | |
| self.assertEqual(body["snapshot"]["updatedAt"], "2020-01-01T00:00:00Z") | |
| pending = self.client.get("/api/robinhood/pending-refresh") | |
| self.assertEqual(pending.status_code, 200) | |
| self.assertEqual( | |
| pending.json(), | |
| {"refreshPending": True, "refreshRequestedAt": requested_at}, | |
| ) | |
| alias = self.client.get("/robinhood/pending-refresh") | |
| self.assertEqual(alias.json()["refreshPending"], True) | |
| def test_pending_flag_is_false_when_snapshot_is_already_newer(self) -> None: | |
| headers = {"Authorization": "Bearer chat-secret-value"} | |
| future = dict(SAMPLE) | |
| future["updatedAt"] = "2099-01-01T00:00:00Z" | |
| self.client.post("/api/robinhood", json=future, headers=headers) | |
| self.client.post("/api/robinhood/refresh", headers={"X-Forwarded-For": "203.0.113.13"}) | |
| body = self.client.get("/api/robinhood").json() | |
| self.assertFalse(body["refreshPending"]) | |
| self.assertNotIn("refreshRequestedAt", body) | |
| self.assertTrue(refresh_file().is_file()) | |
| self.assertEqual(self.client.get("/api/robinhood/pending-refresh").json(), {"refreshPending": False}) | |
| def test_snapshot_post_clears_pending_refresh(self) -> None: | |
| self.client.post("/api/robinhood/refresh", headers={"X-Forwarded-For": "203.0.113.14"}) | |
| self.assertTrue(refresh_file().is_file()) | |
| denied = self.client.post("/api/robinhood", json=SAMPLE) | |
| self.assertEqual(denied.status_code, 401) | |
| self.assertTrue(self.client.get("/api/robinhood").json()["refreshPending"]) | |
| res = self.client.post( | |
| "/api/robinhood", | |
| json=SAMPLE, | |
| headers={"Authorization": "Bearer chat-secret-value"}, | |
| ) | |
| self.assertEqual(res.status_code, 200) | |
| self.assertFalse(refresh_file().exists()) | |
| body = self.client.get("/api/robinhood").json() | |
| self.assertFalse(body["refreshPending"]) | |
| self.assertNotIn("refreshRequestedAt", body) | |
| self.assertEqual(self.client.get("/robinhood/pending-refresh").json(), {"refreshPending": False}) | |
| def test_delete_refresh_requires_snapshot_bearer(self) -> None: | |
| self.client.post("/api/robinhood/refresh", headers={"X-Forwarded-For": "203.0.113.15"}) | |
| denied = self.client.delete("/api/robinhood/refresh") | |
| self.assertEqual(denied.status_code, 401) | |
| self.assertTrue(refresh_file().is_file()) | |
| os.environ["ROBINHOOD_BRIDGE_SECRET"] = "rh-secret-value" | |
| chat = self.client.delete( | |
| "/api/robinhood/refresh", | |
| headers={"Authorization": "Bearer chat-secret-value"}, | |
| ) | |
| self.assertEqual(chat.status_code, 401) | |
| self.assertTrue(refresh_file().is_file()) | |
| ok = self.client.delete( | |
| "/robinhood/refresh", | |
| headers={"Authorization": "Bearer rh-secret-value"}, | |
| ) | |
| self.assertEqual(ok.status_code, 200) | |
| self.assertEqual(ok.json(), {"ok": True, "refreshPending": False}) | |
| self.assertFalse(refresh_file().exists()) | |
| self.assertFalse(self.client.get("/api/robinhood").json()["refreshPending"]) | |
| def test_refresh_cors_allows_phone_origin(self) -> None: | |
| res = self.client.options( | |
| "/api/robinhood/refresh", | |
| headers={ | |
| "Origin": "https://simzy420.github.io", | |
| "Access-Control-Request-Method": "POST", | |
| }, | |
| ) | |
| self.assertIn(res.status_code, (200, 204)) | |
| self.assertEqual(res.headers.get("access-control-allow-origin"), "https://simzy420.github.io") | |
| allow = res.headers.get("access-control-allow-methods", "") | |
| self.assertIn("POST", allow) | |
| self.assertIn("DELETE", allow) | |
| if __name__ == "__main__": | |
| unittest.main() | |