From 234f60bf84c81ed755a6510d466c4bcef1369901 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 26 Jun 2026 17:52:38 +0000 Subject: tests: add gn3 auth-flow tests for case-attribute token enforcement --- tests/test_gn3_auth_flow.py | 83 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 tests/test_gn3_auth_flow.py (limited to 'tests') 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//edit + POST /api/case-attribute//approve/ + POST /api/case-attribute//reject/ + +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//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()}" + ) -- cgit 1.4.1