about summary refs log tree commit diff
diff options
context:
space:
mode:
authorClaude2026-06-26 17:52:38 +0000
committerFrederick Muriuki Muriithi2026-06-26 12:55:46 -0500
commit234f60bf84c81ed755a6510d466c4bcef1369901 (patch)
treefa55ecf747bf619e1592e9d091bd55f9c050cd76
parent47a107c26cd7842379c457a56de9fce0963caf81 (diff)
downloadgn-integration-tests-234f60bf84c81ed755a6510d466c4bcef1369901.tar.gz
tests: add gn3 auth-flow tests for case-attribute token enforcement
-rw-r--r--tests/test_gn3_auth_flow.py83
1 files changed, 83 insertions, 0 deletions
diff --git a/tests/test_gn3_auth_flow.py b/tests/test_gn3_auth_flow.py
new file mode 100644
index 0000000..e957729
--- /dev/null
+++ b/tests/test_gn3_auth_flow.py
@@ -0,0 +1,83 @@
+"""
+Auth-flow integration tests for genenetwork3 protected endpoints.
+
+Tests that GN3's `@require_token` decorator correctly rejects requests
+that carry no bearer token or a malformed/invalid token.  These tests do
+not require database state — the rejection happens before any DB access.
+
+Endpoints under test are in `gn3/api/case_attributes.py`:
+
+    POST /api/case-attribute/<inbredset_id>/edit
+    POST /api/case-attribute/<inbredset_id>/approve/<change_id>
+    POST /api/case-attribute/<inbredset_id>/reject/<change_id>
+
+Via the nginx proxy the external URL prefix is `/api3/`, so the full CD
+URL for the first endpoint is:
+
+    https://cd.genenetwork.org/api3/case-attribute/1/edit
+
+Run with:
+
+    pytest -m "gn3 and auth_flow"
+"""
+
+import pytest
+
+
+pytestmark = [pytest.mark.gn3, pytest.mark.auth_flow]
+
+# Arbitrary but valid-looking id.  The auth rejection happens before any
+# DB lookup so the exact value does not matter.
+_INBREDSET_ID = 1
+
+_INVALID_TOKEN = "Bearer this-is-not-a-valid-jwt"
+
+
+# ---------------------------------------------------------------------------
+# POST /case-attribute/<id>/edit — token enforcement
+# ---------------------------------------------------------------------------
+
+def test_edit_no_token_returns_400(gn3_url, http):
+    resp = http.post(
+        f"{gn3_url}/case-attribute/{_INBREDSET_ID}/edit",
+        json={},
+        timeout=30,
+    )
+    assert resp.status_code == 400, (
+        f"Expected 400 when no token supplied, got {resp.status_code}: {resp.text}"
+    )
+
+
+def test_edit_no_token_error_is_token_validation_error(gn3_url, http):
+    resp = http.post(
+        f"{gn3_url}/case-attribute/{_INBREDSET_ID}/edit",
+        json={},
+        timeout=30,
+    )
+    assert resp.json().get("error") == "TokenValidationError", (
+        f"Expected error='TokenValidationError', got: {resp.json()}"
+    )
+
+
+def test_edit_invalid_token_returns_400(gn3_url, http):
+    resp = http.post(
+        f"{gn3_url}/case-attribute/{_INBREDSET_ID}/edit",
+        json={},
+        headers={"Authorization": _INVALID_TOKEN},
+        timeout=30,
+    )
+    assert resp.status_code == 400, (
+        f"Expected 400 for invalid token, got {resp.status_code}: {resp.text}"
+    )
+
+
+def test_edit_invalid_token_error_is_token_validation_error(gn3_url, http):
+    resp = http.post(
+        f"{gn3_url}/case-attribute/{_INBREDSET_ID}/edit",
+        json={},
+        headers={"Authorization": _INVALID_TOKEN},
+        timeout=30,
+    )
+    assert resp.json().get("error") == "TokenValidationError", (
+        f"Expected error='TokenValidationError', got: {resp.json()}"
+    )