|
3 | 3 | import uuid |
4 | 4 | from copy import deepcopy |
5 | 5 | from datetime import datetime, timedelta |
6 | | -from unittest.mock import patch |
| 6 | +from unittest.mock import AsyncMock, MagicMock, patch |
7 | 7 |
|
8 | 8 | import pytest |
9 | 9 |
|
| 10 | +import stac_fastapi.core.redis_utils as redis_utils |
| 11 | +from stac_fastapi.core.redis_utils import ( |
| 12 | + RedisSentinelSettings, |
| 13 | + RedisSettings, |
| 14 | + connect_redis, |
| 15 | + connect_redis_sentinel, |
| 16 | + get_prev_link, |
| 17 | + save_self_link, |
| 18 | +) |
10 | 19 | from stac_fastapi.types.errors import ConflictError |
11 | 20 |
|
12 | 21 | from ..conftest import create_collection, create_item |
@@ -1623,3 +1632,87 @@ async def test_use_datetime_false(app_client, load_test_data, txn_client, monkey |
1623 | 1632 |
|
1624 | 1633 | assert "test-item-datetime-only" not in found_ids |
1625 | 1634 | assert "test-item-start-end-only" in found_ids |
| 1635 | + |
| 1636 | + |
| 1637 | +@pytest.mark.asyncio |
| 1638 | +async def test_connect_redis(monkeypatch): |
| 1639 | + # Reset the global before the test |
| 1640 | + redis_utils.redis_pool = None |
| 1641 | + |
| 1642 | + redis_mock = AsyncMock() |
| 1643 | + redis_pool_mock = AsyncMock() |
| 1644 | + |
| 1645 | + # Patch aioredis classes |
| 1646 | + monkeypatch.setattr( |
| 1647 | + "stac_fastapi.core.redis_utils.aioredis.Redis", |
| 1648 | + lambda **kwargs: redis_mock, |
| 1649 | + ) |
| 1650 | + monkeypatch.setattr( |
| 1651 | + "stac_fastapi.core.redis_utils.aioredis.ConnectionPool", |
| 1652 | + lambda **kwargs: redis_pool_mock, |
| 1653 | + ) |
| 1654 | + |
| 1655 | + settings = RedisSettings(REDIS_HOST="localhost", REDIS_PORT=6379) |
| 1656 | + redis = await connect_redis(settings) |
| 1657 | + |
| 1658 | + assert redis is redis_mock |
| 1659 | + |
| 1660 | + |
| 1661 | +@pytest.mark.asyncio |
| 1662 | +async def test_connect_redis_sentinel(monkeypatch): |
| 1663 | + # Reset the global before the test |
| 1664 | + redis_utils.redis_pool = None |
| 1665 | + |
| 1666 | + master_mock = AsyncMock() |
| 1667 | + |
| 1668 | + # Sentinel itself is synchronous |
| 1669 | + sentinel_mock = MagicMock() |
| 1670 | + sentinel_mock.master_for.return_value = master_mock |
| 1671 | + |
| 1672 | + # Patch Sentinel constructor |
| 1673 | + monkeypatch.setattr( |
| 1674 | + "stac_fastapi.core.redis_utils.Sentinel", |
| 1675 | + lambda *a, **k: sentinel_mock, |
| 1676 | + ) |
| 1677 | + |
| 1678 | + settings = RedisSentinelSettings( |
| 1679 | + REDIS_SENTINEL_HOSTS="localhost", |
| 1680 | + REDIS_SENTINEL_PORTS="26379", |
| 1681 | + REDIS_SENTINEL_MASTER_NAME="master", |
| 1682 | + ) |
| 1683 | + |
| 1684 | + redis = await connect_redis_sentinel(settings) |
| 1685 | + |
| 1686 | + # Should return our injected master_mock |
| 1687 | + assert redis is master_mock |
| 1688 | + |
| 1689 | + # Verify correct args passed |
| 1690 | + sentinel_mock.master_for.assert_called_once_with( |
| 1691 | + service_name="master", |
| 1692 | + db=0, |
| 1693 | + decode_responses=True, |
| 1694 | + retry_on_timeout=True, |
| 1695 | + client_name="stac-fastapi-app", |
| 1696 | + max_connections=10, |
| 1697 | + health_check_interval=30, |
| 1698 | + ) |
| 1699 | + |
| 1700 | + |
| 1701 | +@pytest.mark.asyncio |
| 1702 | +async def test_save_and_get_prev_link(monkeypatch): |
| 1703 | + fake_redis = AsyncMock() |
| 1704 | + |
| 1705 | + await save_self_link(fake_redis, "token123", "http://example.com/page2") |
| 1706 | + fake_redis.setex.assert_awaited_once_with( |
| 1707 | + "nav:self:token123", 1800, "http://example.com/page2" |
| 1708 | + ) |
| 1709 | + |
| 1710 | + fake_redis.get.return_value = "http://example.com/page2" |
| 1711 | + result = await get_prev_link(fake_redis, "token123") |
| 1712 | + assert result == "http://example.com/page2" |
| 1713 | + |
| 1714 | + result_none = await get_prev_link(fake_redis, None) |
| 1715 | + assert result_none is None |
| 1716 | + |
| 1717 | + await get_prev_link(fake_redis, "token456") |
| 1718 | + fake_redis.get.assert_awaited_with("nav:self:token456") |
0 commit comments