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] =?UTF-8?q?=F0=9F=A7=AA=20Add=20tests=20for=20api=5Ftokens?= =?UTF-8?q?=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/."""