95 lines
3.4 KiB
Python
95 lines
3.4 KiB
Python
"""Tests for login IP allowlist refresh and cross-worker settings broadcast."""
|
|
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from server.background.ip_allowlist_refresh import RefreshResult, do_refresh
|
|
from server.config import settings
|
|
from server.infrastructure.settings_broadcast import publish_setting_changes
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_publish_setting_changes_broadcasts_each_key():
|
|
mock_redis = AsyncMock()
|
|
mock_redis.publish = AsyncMock(return_value=1)
|
|
|
|
with patch("server.infrastructure.redis.client.get_redis", return_value=mock_redis):
|
|
count = await publish_setting_changes({
|
|
"login_manual_ips": "1.2.3.4",
|
|
"login_subscription_url": "https://example.com/sub",
|
|
})
|
|
|
|
assert count == 2
|
|
assert mock_redis.publish.await_count == 2
|
|
assert settings.LOGIN_MANUAL_IPS == "1.2.3.4"
|
|
assert settings.LOGIN_SUBSCRIPTION_URL == "https://example.com/sub"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_do_refresh_publishes_subscription_ips():
|
|
settings.LOGIN_SUBSCRIPTION_URL = "https://example.com/sub"
|
|
settings.LOGIN_MANUAL_IPS = "10.0.0.1"
|
|
settings.LOGIN_SUBSCRIPTION_IPS = ""
|
|
settings.LOGIN_ALLOWED_IPS = ""
|
|
|
|
mock_repo = MagicMock()
|
|
mock_repo.set = AsyncMock()
|
|
mock_session = MagicMock()
|
|
mock_session.__aenter__ = AsyncMock(return_value=mock_session)
|
|
mock_session.__aexit__ = AsyncMock(return_value=None)
|
|
|
|
mock_response = MagicMock()
|
|
mock_response.status_code = 200
|
|
mock_response.text = "ss://YWVzLTEyODpwbG4@104.194.72.62:443#node1"
|
|
|
|
mock_client = MagicMock()
|
|
mock_client.get = AsyncMock(return_value=mock_response)
|
|
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
|
|
mock_client.__aexit__ = AsyncMock(return_value=None)
|
|
|
|
with (
|
|
patch("server.infrastructure.database.session.AsyncSessionLocal", return_value=mock_session),
|
|
patch("server.infrastructure.database.setting_repo.SettingRepositoryImpl", return_value=mock_repo),
|
|
patch("server.infrastructure.settings_broadcast.publish_setting_changes", new_callable=AsyncMock) as mock_publish,
|
|
patch("httpx.AsyncClient", return_value=mock_client),
|
|
):
|
|
result = await do_refresh()
|
|
|
|
assert result.ok is True
|
|
assert result.subscription_ips == ("104.194.72.62",)
|
|
assert result.subscription_count == 1
|
|
assert settings.LOGIN_SUBSCRIPTION_IPS == "104.194.72.62"
|
|
mock_publish.assert_awaited_once()
|
|
published = mock_publish.await_args.args[0]
|
|
assert published["login_subscription_ips"] == "104.194.72.62"
|
|
assert "10.0.0.1" in published["login_allowed_ips"]
|
|
assert published["login_subscription_last_refresh"]
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_do_refresh_without_subscription_url():
|
|
settings.LOGIN_SUBSCRIPTION_URL = ""
|
|
result = await do_refresh()
|
|
assert result.ok is True
|
|
assert result.subscription_ips == ()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_do_refresh_http_error():
|
|
settings.LOGIN_SUBSCRIPTION_URL = "https://example.com/sub"
|
|
|
|
mock_response = MagicMock()
|
|
mock_response.status_code = 503
|
|
mock_client = MagicMock()
|
|
mock_client.get = AsyncMock(return_value=mock_response)
|
|
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
|
|
mock_client.__aexit__ = AsyncMock(return_value=None)
|
|
|
|
with patch("httpx.AsyncClient", return_value=mock_client):
|
|
result = await do_refresh()
|
|
|
|
assert result.ok is False
|
|
assert result.error is not None
|
|
assert "503" in result.error
|