diff --git a/fia_api/core/auth/experiments.py b/fia_api/core/auth/experiments.py index a73aa408..50bab560 100644 --- a/fia_api/core/auth/experiments.py +++ b/fia_api/core/auth/experiments.py @@ -1,4 +1,4 @@ -"""Module containing user experiment fetching""" +"""Module containing user experiment fetching.""" import os from http import HTTPStatus @@ -7,20 +7,29 @@ import requests from fia_api.core.auth import AUTH_URL +from fia_api.core.cache import cache_get_json, cache_set_json API_KEY = os.environ.get("AUTH_API_KEY", "shh") +AUTH_EXPERIMENTS_CACHE_TTL_SECONDS = int(os.environ.get("AUTH_EXPERIMENTS_CACHE_TTL_SECONDS", "120")) def get_experiments_for_user_number(user_number: int) -> list[int]: - """ - Given a user number fetch and return the experiment (RB) numbers for that user + """Given a user number fetch and return the experiment (RB) numbers for + that user. + :param user_number: The user number to fetch for :return: List of ints (experiment numbers) """ + cache_key = f"fia_api:auth:experiments:{user_number}" + cached = cache_get_json(cache_key) + if isinstance(cached, list): + return cached + response = requests.get( f"{AUTH_URL}/experiments?user_number={user_number}", timeout=30, headers={"Authorization": f"Bearer {API_KEY}"} ) if response.status_code == HTTPStatus.OK: experiments: list[Any] = response.json() + cache_set_json(cache_key, experiments, AUTH_EXPERIMENTS_CACHE_TTL_SECONDS) return experiments return [] diff --git a/test/core/auth/test_experiments.py b/test/core/auth/test_experiments.py index 771003df..7fb6d555 100644 --- a/test/core/auth/test_experiments.py +++ b/test/core/auth/test_experiments.py @@ -1,26 +1,48 @@ -"""Test cases for experiments module""" +"""Test cases for experiments module.""" from http import HTTPStatus from unittest.mock import Mock, patch -from fia_api.core.auth.experiments import get_experiments_for_user_number +from fia_api.core.auth.experiments import AUTH_EXPERIMENTS_CACHE_TTL_SECONDS, get_experiments_for_user_number +@patch("fia_api.core.auth.experiments.cache_set_json") +@patch("fia_api.core.auth.experiments.cache_get_json") @patch("fia_api.core.auth.experiments.requests.get") -def test_get_experiments_for_user_number_bad_status_returns_empty_list(mock_get): - """Test when non OK status returned""" +def test_get_experiments_for_user_number_bad_status_returns_empty_list(mock_get, mock_cache_get, mock_cache_set): + """Test when non OK status returned.""" + mock_cache_get.return_value = None mock_response = Mock() mock_get.return_value = mock_response mock_response.status_code = HTTPStatus.NOT_FOUND assert get_experiments_for_user_number(1234) == [] + mock_cache_set.assert_not_called() +@patch("fia_api.core.auth.experiments.cache_set_json") +@patch("fia_api.core.auth.experiments.cache_get_json") @patch("fia_api.core.auth.experiments.requests.get") -def test_get_experiments_for_user_number_returns_experiment_numbers(mock_get): - """Test when OK status returned""" +def test_get_experiments_for_user_number_returns_experiment_numbers(mock_get, mock_cache_get, mock_cache_set): + """Test when OK status returned.""" + mock_cache_get.return_value = None mock_response = Mock() mock_get.return_value = mock_response mock_response.status_code = HTTPStatus.OK mock_response.json.return_value = [1, 2, 3, 4] assert get_experiments_for_user_number(1234) == [1, 2, 3, 4] + mock_cache_set.assert_called_once_with( + "fia_api:auth:experiments:1234", + [1, 2, 3, 4], + AUTH_EXPERIMENTS_CACHE_TTL_SECONDS, + ) + + +@patch("fia_api.core.auth.experiments.cache_get_json") +@patch("fia_api.core.auth.experiments.requests.get") +def test_get_experiments_for_user_number_uses_cache(mock_get, mock_cache_get): + """Test that cached experiments are returned and no request is made.""" + mock_cache_get.return_value = [10, 20] + + assert get_experiments_for_user_number(1234) == [10, 20] + mock_get.assert_not_called()