import json from edge.events import Event, EventType, Severity from edge.alert import sign, PostClient def _event(): return Event(EventType.FALL, Severity.HIGH, "cam-01", 7, None, 1000.0, 3.0, {"torso_angle": 78.0}, None) class _FakeResp: def __init__(self, code): self.status_code = code def test_sign_is_deterministic(): s1 = sign("secret", "n1", "1000", b"body") s2 = sign("secret", "n1", "1000", b"body") assert s1 == s2 and len(s1) == 64 def test_send_posts_signed_payload(): captured = {} def fake_post(url, data=None, headers=None, timeout=None, **kw): captured["url"] = url captured["headers"] = headers captured["body"] = data captured["kw"] = kw return _FakeResp(200) client = PostClient("https://x/api/events", "pi-01", "secret", nonce_fn=lambda: "n1", now_fn=lambda: 1000.0, http_post=fake_post) ok = client.send(_event(), [b"\xff\xd8jpeg"]) assert ok is True assert captured["headers"]["X-Nonce"] == "n1" assert captured["headers"]["X-Timestamp"] == "1000.0" payload = json.loads(captured["body"]) assert payload["device_id"] == "pi-01" assert payload["event_type"] == "fall" assert len(payload["snapshots"]) == 1 expected = sign("secret", "n1", "1000.0", captured["body"].encode()) assert captured["headers"]["X-Signature"] == expected # cafe24's shared-hosting WAF blocks the default python-requests/x.y User-Agent with an # HTML 403 (curl passes) — a custom UA is required or every event silently 403s. assert captured["headers"]["User-Agent"] == "move-detect-edge/1.0" # The .htaccess http->https 302 must NOT be auto-followed as a GET (405/404); a redirect # is a misconfiguration to surface, not to silently downgrade the POST. assert captured["kw"].get("allow_redirects") is False def test_send_returns_false_on_error_code(): client = PostClient("https://x", "pi-01", "s", lambda: "n", lambda: 1.0, http_post=lambda *a, **k: _FakeResp(500)) assert client.send(_event(), []) is False