about summary refs log tree commit diff
path: root/tests/unit/auth
diff options
context:
space:
mode:
authorClaude Sonnet 4.62026-08-28 19:30:00 +0000
committerFrederick Muriuki Muriithi2026-08-28 14:38:08 -0500
commit3348d266228e1f4b374d0af6e33fe4948eb1bfaa (patch)
tree7c6bf3f9e1fcdde94ddcde69118cbddbe71f2e48 /tests/unit/auth
parentd9b8803bd808a338a72b03aa55932c8d589892d8 (diff)
downloadgn-auth-3348d266228e1f4b374d0af6e33fe4948eb1bfaa.tar.gz
Add unit tests for system admin resource-ownership endpoints
Four tests covering the two new endpoints added in the previous commit:

  POST /auth/system/administration/resources/<id>/assign-owner
  POST /auth/system/administration/resources/<id>/revoke-owner

Tests:
  - assign-owner returns 401 when no Authorization header is sent
  - revoke-owner returns 401 when no Authorization header is sent
  - assign-owner returns 403 for a user without system:resource:assign-owner
  - revoke-owner returns 403 for a user without system:resource:assign-owner

The 401 tests exercise the @require_oauth decorator directly.  The 403 tests
mock require_oauth.acquire (same pattern as test_admin_user_roles.py) and use
unaff@iliated.user (TEST_USERS[3]) who has no roles and therefore no
system:resource:assign-owner privilege on the system resource.

Reviewed-By: Frederick M. Muriithi <fredmanglis@gmail.com>
Diffstat (limited to 'tests/unit/auth')
-rw-r--r--tests/unit/auth/test_system_admin_resources.py94
1 files changed, 94 insertions, 0 deletions
diff --git a/tests/unit/auth/test_system_admin_resources.py b/tests/unit/auth/test_system_admin_resources.py
new file mode 100644
index 0000000..76f3ca3
--- /dev/null
+++ b/tests/unit/auth/test_system_admin_resources.py
@@ -0,0 +1,94 @@
+"""Tests for system admin resource-ownership endpoints.
+
+Covers POST /auth/system/administration/resources/<id>/assign-owner
+     and POST /auth/system/administration/resources/<id>/revoke-owner.
+"""
+import pytest
+
+from tests.unit.auth import conftest
+from tests.unit.auth.fixtures.resource_fixtures import TEST_RESOURCES
+
+# Arbitrary target resource for the endpoint path — the privilege check fires
+# before any resource lookup, so the resource need not exist for 401/403 tests.
+_TARGET_RESOURCE = str(TEST_RESOURCES[0].resource_id)
+
+# Minimal body for both endpoints (the target user for ownership change).
+_BODY = {"user_id": str(conftest.TEST_USERS[3].user_id)}
+
+_ASSIGN_URL = f"/auth/system/administration/resources/{_TARGET_RESOURCE}/assign-owner"
+_REVOKE_URL = f"/auth/system/administration/resources/{_TARGET_RESOURCE}/revoke-owner"
+
+_NON_SYSADMIN = conftest.TEST_USERS[3]  # unaff@iliated.user — no roles at all
+
+
+def _mock_token(mocker, user, clients):
+    """Patch require_oauth.acquire in the admin resources module."""
+    mocker.patch(
+        "gn_auth.auth.system.admin.resources.require_oauth.acquire",
+        conftest.get_tokeniser(
+            user,
+            tuple(c for c in clients if c.user == user)[0]))
+
+
+# ---------------------------------------------------------------------------
+# No-token tests (401)
+# ---------------------------------------------------------------------------
+
+@pytest.mark.unit_test
+def test_assign_owner_no_token_returns_401(fxtr_app):
+    """
+    GIVEN: no Authorization header
+    WHEN: POST .../assign-owner
+    THEN: 401 is returned
+    """
+    with fxtr_app.test_client() as http:
+        res = http.post(_ASSIGN_URL, json=_BODY)
+    assert res.status_code == 401
+
+
+@pytest.mark.unit_test
+def test_revoke_owner_no_token_returns_401(fxtr_app):
+    """
+    GIVEN: no Authorization header
+    WHEN: POST .../revoke-owner
+    THEN: 401 is returned
+    """
+    with fxtr_app.test_client() as http:
+        res = http.post(_REVOKE_URL, json=_BODY)
+    assert res.status_code == 401
+
+
+# ---------------------------------------------------------------------------
+# Non-sysadmin tests (403)
+# ---------------------------------------------------------------------------
+
+@pytest.mark.unit_test
+def test_assign_owner_non_sysadmin_returns_403(fxtr_app, mocker, fxtr_oauth2_clients):
+    """
+    GIVEN: a valid token for a user without system:resource:assign-owner
+    WHEN: POST .../assign-owner
+    THEN: 403 is returned
+    """
+    _conn, clients = fxtr_oauth2_clients
+    _mock_token(mocker, _NON_SYSADMIN, clients)
+    with fxtr_app.test_client() as http:
+        res = http.post(
+            _ASSIGN_URL, json=_BODY,
+            headers={"Authorization": "Bearer some-mocked-token"})
+    assert res.status_code == 403
+
+
+@pytest.mark.unit_test
+def test_revoke_owner_non_sysadmin_returns_403(fxtr_app, mocker, fxtr_oauth2_clients):
+    """
+    GIVEN: a valid token for a user without system:resource:assign-owner
+    WHEN: POST .../revoke-owner
+    THEN: 403 is returned
+    """
+    _conn, clients = fxtr_oauth2_clients
+    _mock_token(mocker, _NON_SYSADMIN, clients)
+    with fxtr_app.test_client() as http:
+        res = http.post(
+            _REVOKE_URL, json=_BODY,
+            headers={"Authorization": "Bearer some-mocked-token"})
+    assert res.status_code == 403