From f24c39a02726e42110210c9e62d21cfd41d1747d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 09:26:04 +0000 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=A7=AA=20Add=20tests=20for=20api=5Fto?= =?UTF-8?q?kens=20edge=20cases=20to=20improve=20coverage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- tests/test_api_tokens.py | 78 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/tests/test_api_tokens.py b/tests/test_api_tokens.py index 331631b7..6ae60f4e 100644 --- a/tests/test_api_tokens.py +++ b/tests/test_api_tokens.py @@ -101,6 +101,42 @@ def _cleanup(app): app.dependency_overrides.clear() +# --------------------------------------------------------------------------- +# Tests – Auth Helper +# --------------------------------------------------------------------------- + +class TestGetOwnerId: + """Tests for the _get_owner_id dependency helper.""" + + @pytest.mark.unit + def test_get_owner_id_unauthenticated(self): + """_get_owner_id should raise a 401 if the user is not authenticated.""" + from unittest.mock import MagicMock, patch + + from fastapi import HTTPException + + from app.api.api_tokens import _get_owner_id + + mock_request = MagicMock() + with patch("app.api.api_tokens.get_current_owner_id", return_value=None): + with pytest.raises(HTTPException) as exc_info: + _get_owner_id(mock_request) + assert exc_info.value.status_code == 401 + assert exc_info.value.detail == "Not authenticated" + + @pytest.mark.unit + def test_get_owner_id_authenticated(self): + """_get_owner_id should return owner_id if user is authenticated.""" + from unittest.mock import MagicMock, patch + + from app.api.api_tokens import _get_owner_id + + mock_request = MagicMock() + with patch("app.api.api_tokens.get_current_owner_id", return_value="owner123"): + owner_id = _get_owner_id(mock_request) + assert owner_id == "owner123" + + # --------------------------------------------------------------------------- # Tests – Token CRUD # --------------------------------------------------------------------------- @@ -157,6 +193,48 @@ class TestTokenCreate: finally: _cleanup(app) + @pytest.mark.unit + def test_create_token_database_error(self, tok_engine, tok_session): + """Creating a token should rollback and raise 500 if database commit fails.""" + from unittest.mock import patch + + from sqlalchemy.orm import Session as SASession + + from app.main import app + + client = _make_client(tok_engine) + try: + # Wrap commit: flush first so changes are staged in the transaction, + # then raise to simulate a commit failure after data has been written. + def _fail_after_flush(self): + self.flush() # stage changes inside the open transaction + raise Exception("DB Failure") + + # Spy on rollback so we can assert it is called. + rollback_called = False + real_rollback = SASession.rollback + + def _spy_rollback(self): + nonlocal rollback_called + rollback_called = True + real_rollback(self) + + with ( + patch.object(SASession, "commit", _fail_after_flush), + patch.object(SASession, "rollback", _spy_rollback), + ): + resp = client.post("/api/api-tokens/", json={"name": "DB Error Create Test"}) + assert resp.status_code == 500 + + # rollback() must have been called to undo the flushed changes. + assert rollback_called, "db.rollback() was not called after commit failure in create_token" + + # After rollback the token must not exist in the database. + db_token = tok_session.query(ApiToken).filter(ApiToken.name == "DB Error Create Test").first() + assert db_token is None + finally: + _cleanup(app) + class TestTokenList: """Tests for GET /api/api-tokens/.""" From 0425d46c4440191cd410434ba64c1bc9cdb53cbb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 16 Mar 2026 09:26:26 +0000 Subject: [PATCH 2/3] style: apply ruff auto-fix - Auto-formatted code with ruff format - Applied ruff linting fixes with --fix Co-authored-by: github-actions[bot] --- tests/test_api_tokens.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_api_tokens.py b/tests/test_api_tokens.py index 6ae60f4e..62999124 100644 --- a/tests/test_api_tokens.py +++ b/tests/test_api_tokens.py @@ -105,6 +105,7 @@ def _cleanup(app): # Tests – Auth Helper # --------------------------------------------------------------------------- + class TestGetOwnerId: """Tests for the _get_owner_id dependency helper.""" From d58c43c7b57ed462d42b58d2033677495d3e0f1e Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 16 Mar 2026 09:39:41 +0000 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=A7=AA=20Fix=20test=5Fapi=5Ftokens=20?= =?UTF-8?q?syntax=20to=20avoid=20CI=20failures=20in=20older=20Python=20ver?= =?UTF-8?q?sions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- tests/test_api_tokens.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/tests/test_api_tokens.py b/tests/test_api_tokens.py index 62999124..bdc5d9ed 100644 --- a/tests/test_api_tokens.py +++ b/tests/test_api_tokens.py @@ -220,12 +220,10 @@ class TestTokenCreate: rollback_called = True real_rollback(self) - with ( - patch.object(SASession, "commit", _fail_after_flush), - patch.object(SASession, "rollback", _spy_rollback), - ): - resp = client.post("/api/api-tokens/", json={"name": "DB Error Create Test"}) - assert resp.status_code == 500 + with patch.object(SASession, "commit", _fail_after_flush): + with patch.object(SASession, "rollback", _spy_rollback): + resp = client.post("/api/api-tokens/", json={"name": "DB Error Create Test"}) + assert resp.status_code == 500 # rollback() must have been called to undo the flushed changes. assert rollback_called, "db.rollback() was not called after commit failure in create_token" @@ -405,12 +403,10 @@ class TestTokenRevoke: rollback_called = True real_rollback(self) - with ( - patch.object(SASession, "commit", _fail_after_flush), - patch.object(SASession, "rollback", _spy_rollback), - ): - resp = client.delete(f"/api/api-tokens/{token_id}") - assert resp.status_code == 500 + with patch.object(SASession, "commit", _fail_after_flush): + with patch.object(SASession, "rollback", _spy_rollback): + resp = client.delete(f"/api/api-tokens/{token_id}") + assert resp.status_code == 500 # rollback() must have been called to undo the flushed changes. assert rollback_called, "db.rollback() was not called after commit failure"