From 8eb2e97113deaf60258bbc8a63949a551cd07be2 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:04:58 +0000 Subject: [PATCH] Add unit tests for generate_api_token function Enhance the coverage and robustness of the `generate_api_token` helper in `app/api/api_tokens.py` by introducing three unit tests. The new tests verify: - The exact character length of the generated string based on `TOKEN_BYTES`. - The character set strictly adheres to URL-safe characters and the expected `TOKEN_PREFIX`. - `secrets.token_urlsafe` is explicitly called with `TOKEN_BYTES`. Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> --- tests/test_api_tokens.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/test_api_tokens.py b/tests/test_api_tokens.py index 331631b7..5415b9c7 100644 --- a/tests/test_api_tokens.py +++ b/tests/test_api_tokens.py @@ -534,6 +534,42 @@ class TestTokenUtils: tokens = {generate_api_token() for _ in range(100)} assert len(tokens) == 100 + @pytest.mark.unit + def test_generate_api_token_length(self): + """Generated tokens should have the exact expected length based on TOKEN_BYTES.""" + import math + from app.api.api_tokens import generate_api_token, TOKEN_PREFIX, TOKEN_BYTES + + # base64url encoding of N bytes without padding: ceil(N * 4 / 3) characters + expected_b64_len = math.ceil(TOKEN_BYTES * 4 / 3) + expected_total_len = len(TOKEN_PREFIX) + expected_b64_len + + token = generate_api_token() + assert len(token) == expected_total_len + + @pytest.mark.unit + def test_generate_api_token_charset(self): + """Generated tokens should only contain URL-safe base64 characters and the prefix.""" + import re + from app.api.api_tokens import generate_api_token, TOKEN_PREFIX + + token = generate_api_token() + # Check it starts with prefix and the rest is base64url chars ([A-Za-z0-9_-]) + pattern = f"^{re.escape(TOKEN_PREFIX)}[A-Za-z0-9_\\-]+$" + assert re.match(pattern, token) is not None + + @pytest.mark.unit + def test_generate_api_token_uses_secrets(self): + """Generated tokens should use secrets.token_urlsafe with the correct number of bytes.""" + from unittest.mock import patch + from app.api.api_tokens import generate_api_token, TOKEN_BYTES, TOKEN_PREFIX + + with patch("app.api.api_tokens.secrets.token_urlsafe", return_value="mocked_token") as mock_secrets: + token = generate_api_token() + mock_secrets.assert_called_once_with(TOKEN_BYTES) + assert token == f"{TOKEN_PREFIX}mocked_token" + + @pytest.mark.unit def test_hash_token_deterministic(self): """Hashing the same token should always produce the same result."""