mirror of
https://github.com/b3nw/nginx-proxy-manager-mcp.git
synced 2026-05-19 23:35:47 -05:00
test: Add tests for access lists, proxy host creation, and config defaults
This commit is contained in:
@@ -35,6 +35,53 @@ def mock_proxy_hosts():
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_access_lists():
|
||||||
|
"""Mock access lists response."""
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"created_on": "2024-01-01T00:00:00Z",
|
||||||
|
"modified_on": "2024-01-01T00:00:00Z",
|
||||||
|
"owner_user_id": 1,
|
||||||
|
"name": "Admin Only",
|
||||||
|
"satisfy_any": False,
|
||||||
|
"pass_auth": True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"created_on": "2024-01-02T00:00:00Z",
|
||||||
|
"modified_on": "2024-01-02T00:00:00Z",
|
||||||
|
"owner_user_id": 1,
|
||||||
|
"name": "Internal Network",
|
||||||
|
"satisfy_any": True,
|
||||||
|
"pass_auth": False,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_created_proxy_host():
|
||||||
|
"""Mock response for created proxy host."""
|
||||||
|
return {
|
||||||
|
"id": 42,
|
||||||
|
"created_on": "2024-01-15T10:00:00Z",
|
||||||
|
"modified_on": "2024-01-15T10:00:00Z",
|
||||||
|
"owner_user_id": 1,
|
||||||
|
"domain_names": ["newapp.example.com"],
|
||||||
|
"forward_host": "10.0.0.50",
|
||||||
|
"forward_port": 3000,
|
||||||
|
"forward_scheme": "http",
|
||||||
|
"enabled": True,
|
||||||
|
"ssl_forced": True,
|
||||||
|
"certificate_id": 24,
|
||||||
|
"block_exploits": True,
|
||||||
|
"allow_websocket_upgrade": True,
|
||||||
|
"access_list_id": 0,
|
||||||
|
"advanced_config": "",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestNpmClientAuth:
|
class TestNpmClientAuth:
|
||||||
"""Test authentication logic."""
|
"""Test authentication logic."""
|
||||||
|
|
||||||
@@ -114,3 +161,69 @@ class TestNpmClientEndpoints:
|
|||||||
assert hosts[0].id == 1
|
assert hosts[0].id == 1
|
||||||
assert hosts[0].domain_names == ["example.com"]
|
assert hosts[0].domain_names == ["example.com"]
|
||||||
assert hosts[0].forward_host == "192.168.1.100"
|
assert hosts[0].forward_host == "192.168.1.100"
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_get_access_lists(self, httpx_mock, mock_token_response, mock_access_lists):
|
||||||
|
"""Test fetching access lists."""
|
||||||
|
httpx_mock.add_response(
|
||||||
|
method="POST",
|
||||||
|
url="http://localhost:81/api/tokens",
|
||||||
|
json=mock_token_response,
|
||||||
|
)
|
||||||
|
httpx_mock.add_response(
|
||||||
|
method="GET",
|
||||||
|
url="http://localhost:81/api/nginx/access-lists",
|
||||||
|
json=mock_access_lists,
|
||||||
|
)
|
||||||
|
|
||||||
|
async with NpmClient(
|
||||||
|
base_url="http://localhost:81/api",
|
||||||
|
identity="test@test.com",
|
||||||
|
secret="password",
|
||||||
|
) as client:
|
||||||
|
access_lists = await client.get_access_lists()
|
||||||
|
|
||||||
|
assert len(access_lists) == 2
|
||||||
|
assert access_lists[0].id == 1
|
||||||
|
assert access_lists[0].name == "Admin Only"
|
||||||
|
assert access_lists[0].pass_auth is True
|
||||||
|
assert access_lists[1].id == 2
|
||||||
|
assert access_lists[1].name == "Internal Network"
|
||||||
|
assert access_lists[1].satisfy_any is True
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_create_proxy_host(
|
||||||
|
self, httpx_mock, mock_token_response, mock_created_proxy_host
|
||||||
|
):
|
||||||
|
"""Test creating a proxy host."""
|
||||||
|
httpx_mock.add_response(
|
||||||
|
method="POST",
|
||||||
|
url="http://localhost:81/api/tokens",
|
||||||
|
json=mock_token_response,
|
||||||
|
)
|
||||||
|
httpx_mock.add_response(
|
||||||
|
method="POST",
|
||||||
|
url="http://localhost:81/api/nginx/proxy-hosts",
|
||||||
|
json=mock_created_proxy_host,
|
||||||
|
status_code=201,
|
||||||
|
)
|
||||||
|
|
||||||
|
async with NpmClient(
|
||||||
|
base_url="http://localhost:81/api",
|
||||||
|
identity="test@test.com",
|
||||||
|
secret="password",
|
||||||
|
) as client:
|
||||||
|
host = await client.create_proxy_host(
|
||||||
|
domain_names=["newapp.example.com"],
|
||||||
|
forward_host="10.0.0.50",
|
||||||
|
forward_port=3000,
|
||||||
|
certificate_id=24,
|
||||||
|
ssl_forced=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert host.id == 42
|
||||||
|
assert host.domain_names == ["newapp.example.com"]
|
||||||
|
assert host.forward_host == "10.0.0.50"
|
||||||
|
assert host.forward_port == 3000
|
||||||
|
assert host.ssl_forced is True
|
||||||
|
assert host.certificate_id == 24
|
||||||
|
|||||||
91
tests/test_config.py
Normal file
91
tests/test_config.py
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
"""Tests for configuration handling."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from pydantic_settings.exceptions import SettingsError
|
||||||
|
|
||||||
|
from npm_mcp.config import DEFAULT_PROXY_SETTINGS, Settings
|
||||||
|
|
||||||
|
|
||||||
|
class TestProxyDefaults:
|
||||||
|
"""Test NPM_PROXY_DEFAULTS parsing and merging."""
|
||||||
|
|
||||||
|
def test_default_proxy_settings(self):
|
||||||
|
"""Test that default settings are correct."""
|
||||||
|
settings = Settings(identity="test", secret="test")
|
||||||
|
defaults = settings.get_proxy_defaults()
|
||||||
|
|
||||||
|
assert defaults["forward_scheme"] == "http"
|
||||||
|
assert defaults["certificate_id"] == 0
|
||||||
|
assert defaults["ssl_forced"] is True
|
||||||
|
assert defaults["block_exploits"] is True
|
||||||
|
assert defaults["allow_websocket_upgrade"] is True
|
||||||
|
assert defaults["access_list_id"] == 0
|
||||||
|
assert defaults["advanced_config"] == ""
|
||||||
|
|
||||||
|
def test_proxy_defaults_json_parsing(self, monkeypatch):
|
||||||
|
"""Test parsing JSON string from environment variable."""
|
||||||
|
monkeypatch.setenv("NPM_IDENTITY", "test")
|
||||||
|
monkeypatch.setenv("NPM_SECRET", "test")
|
||||||
|
monkeypatch.setenv("NPM_PROXY_DEFAULTS", '{"certificate_id": 24, "ssl_forced": false}')
|
||||||
|
|
||||||
|
settings = Settings()
|
||||||
|
defaults = settings.get_proxy_defaults()
|
||||||
|
|
||||||
|
# Overridden values
|
||||||
|
assert defaults["certificate_id"] == 24
|
||||||
|
assert defaults["ssl_forced"] is False
|
||||||
|
|
||||||
|
# Default values preserved
|
||||||
|
assert defaults["forward_scheme"] == "http"
|
||||||
|
assert defaults["block_exploits"] is True
|
||||||
|
|
||||||
|
def test_proxy_defaults_dict_passthrough(self):
|
||||||
|
"""Test that dict values pass through correctly."""
|
||||||
|
settings = Settings(
|
||||||
|
identity="test",
|
||||||
|
secret="test",
|
||||||
|
proxy_defaults={"certificate_id": 18, "access_list_id": 5},
|
||||||
|
)
|
||||||
|
defaults = settings.get_proxy_defaults()
|
||||||
|
|
||||||
|
assert defaults["certificate_id"] == 18
|
||||||
|
assert defaults["access_list_id"] == 5
|
||||||
|
|
||||||
|
def test_proxy_defaults_empty_env_raises(self, monkeypatch):
|
||||||
|
"""Test that empty string env var raises SettingsError."""
|
||||||
|
monkeypatch.setenv("NPM_IDENTITY", "test")
|
||||||
|
monkeypatch.setenv("NPM_SECRET", "test")
|
||||||
|
monkeypatch.setenv("NPM_PROXY_DEFAULTS", "")
|
||||||
|
|
||||||
|
# pydantic-settings tries to JSON decode empty string and fails
|
||||||
|
with pytest.raises(SettingsError):
|
||||||
|
Settings()
|
||||||
|
|
||||||
|
def test_proxy_defaults_invalid_json_raises(self, monkeypatch):
|
||||||
|
"""Test that invalid JSON raises SettingsError."""
|
||||||
|
monkeypatch.setenv("NPM_IDENTITY", "test")
|
||||||
|
monkeypatch.setenv("NPM_SECRET", "test")
|
||||||
|
monkeypatch.setenv("NPM_PROXY_DEFAULTS", "{not valid json}")
|
||||||
|
|
||||||
|
# pydantic-settings tries to JSON decode and fails
|
||||||
|
with pytest.raises(SettingsError):
|
||||||
|
Settings()
|
||||||
|
|
||||||
|
def test_proxy_defaults_merges_not_replaces(self):
|
||||||
|
"""Test that user defaults merge with base defaults."""
|
||||||
|
settings = Settings(
|
||||||
|
identity="test",
|
||||||
|
secret="test",
|
||||||
|
proxy_defaults={"certificate_id": 24},
|
||||||
|
)
|
||||||
|
defaults = settings.get_proxy_defaults()
|
||||||
|
|
||||||
|
# All keys should be present
|
||||||
|
assert set(defaults.keys()) == set(DEFAULT_PROXY_SETTINGS.keys())
|
||||||
|
|
||||||
|
# User value applied
|
||||||
|
assert defaults["certificate_id"] == 24
|
||||||
|
|
||||||
|
# Other defaults preserved
|
||||||
|
assert defaults["ssl_forced"] is True
|
||||||
|
assert defaults["block_exploits"] is True
|
||||||
Reference in New Issue
Block a user