import pytest
from linkedin_mcp_server.config.schema import (
AppConfig,
BrowserConfig,
ConfigurationError,
ServerConfig,
)
class TestBrowserConfig:
def test_defaults(self):
config = BrowserConfig()
assert config.headless is True
assert config.default_timeout == 5000
def test_validate_passes(self):
BrowserConfig().validate() # No error
def test_validate_negative_timeout(self):
with pytest.raises(ConfigurationError):
BrowserConfig(default_timeout=-1).validate()
def test_validate_negative_slow_mo(self):
with pytest.raises(ConfigurationError):
BrowserConfig(slow_mo=-1).validate()
class TestServerConfig:
def test_defaults(self):
config = ServerConfig()
assert config.transport == "stdio"
assert config.port == 8000
class TestAppConfig:
def test_validate_invalid_port(self):
config = AppConfig()
config.server.port = 99999
with pytest.raises(ConfigurationError):
config.validate()
class TestConfigSingleton:
def test_get_config_returns_same_instance(self, monkeypatch):
# Mock sys.argv to prevent argparse from parsing pytest's arguments
monkeypatch.setattr("sys.argv", ["linkedin-mcp-server"])
from linkedin_mcp_server.config import get_config
assert get_config() is get_config()
def test_reset_config_clears_singleton(self, monkeypatch):
# Mock sys.argv to prevent argparse from parsing pytest's arguments
monkeypatch.setattr("sys.argv", ["linkedin-mcp-server"])
from linkedin_mcp_server.config import get_config, reset_config
first = get_config()
reset_config()
second = get_config()
assert first is not second
class TestLoaders:
def test_load_from_env_headless_false(self, monkeypatch):
monkeypatch.setenv("HEADLESS", "false")
from linkedin_mcp_server.config.loaders import load_from_env
config = load_from_env(AppConfig())
assert config.browser.headless is False
def test_load_from_env_headless_true(self, monkeypatch):
monkeypatch.setenv("HEADLESS", "true")
from linkedin_mcp_server.config.loaders import load_from_env
config = load_from_env(AppConfig())
assert config.browser.headless is True
def test_load_from_env_log_level(self, monkeypatch):
monkeypatch.setenv("LOG_LEVEL", "DEBUG")
from linkedin_mcp_server.config.loaders import load_from_env
config = load_from_env(AppConfig())
assert config.server.log_level == "DEBUG"
def test_load_from_env_defaults(self, monkeypatch):
# Clear env vars
for var in ["HEADLESS", "LOG_LEVEL"]:
monkeypatch.delenv(var, raising=False)
from linkedin_mcp_server.config.loaders import load_from_env
config = load_from_env(AppConfig())
assert config.browser.headless is True # default
def test_load_from_env_transport(self, monkeypatch):
monkeypatch.setenv("TRANSPORT", "streamable-http")
from linkedin_mcp_server.config.loaders import load_from_env
config = load_from_env(AppConfig())
assert config.server.transport == "streamable-http"
assert config.server.transport_explicitly_set is True
def test_load_from_env_invalid_transport(self, monkeypatch):
monkeypatch.setenv("TRANSPORT", "invalid")
from linkedin_mcp_server.config.loaders import load_from_env
with pytest.raises(ConfigurationError, match="Invalid TRANSPORT"):
load_from_env(AppConfig())
def test_load_from_env_timeout(self, monkeypatch):
monkeypatch.setenv("TIMEOUT", "10000")
from linkedin_mcp_server.config.loaders import load_from_env
config = load_from_env(AppConfig())
assert config.browser.default_timeout == 10000
def test_load_from_env_invalid_timeout(self, monkeypatch):
monkeypatch.setenv("TIMEOUT", "invalid")
from linkedin_mcp_server.config.loaders import load_from_env
with pytest.raises(ConfigurationError, match="Invalid TIMEOUT"):
load_from_env(AppConfig())
def test_load_from_env_port(self, monkeypatch):
monkeypatch.setenv("PORT", "9000")
from linkedin_mcp_server.config.loaders import load_from_env
config = load_from_env(AppConfig())
assert config.server.port == 9000
def test_load_from_env_slow_mo(self, monkeypatch):
monkeypatch.setenv("SLOW_MO", "100")
from linkedin_mcp_server.config.loaders import load_from_env
config = load_from_env(AppConfig())
assert config.browser.slow_mo == 100
def test_load_from_env_viewport(self, monkeypatch):
monkeypatch.setenv("VIEWPORT", "1920x1080")
from linkedin_mcp_server.config.loaders import load_from_env
config = load_from_env(AppConfig())
assert config.browser.viewport_width == 1920
assert config.browser.viewport_height == 1080
def test_load_from_env_invalid_viewport(self, monkeypatch):
monkeypatch.setenv("VIEWPORT", "invalid")
from linkedin_mcp_server.config.loaders import load_from_env
with pytest.raises(ConfigurationError, match="Invalid VIEWPORT"):
load_from_env(AppConfig())
def test_load_from_env_linkedin_cookie(self, monkeypatch):
monkeypatch.setenv("LINKEDIN_COOKIE", "test_cookie_value")
from linkedin_mcp_server.config.loaders import load_from_env
config = load_from_env(AppConfig())
assert config.server.linkedin_cookie == "test_cookie_value"