116 lines
3.8 KiB
Python
116 lines
3.8 KiB
Python
import os
|
|
import sys
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
sys.modules["psycopg2"] = MagicMock()
|
|
sys.modules["psycopg2.pool"] = MagicMock()
|
|
sys.modules["psycopg2.extras"] = MagicMock()
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
|
|
import pytest
|
|
|
|
import main
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_setting_returns_stored_value():
|
|
with patch.object(main, "db_query", new=AsyncMock(return_value={"value": "Custom GmbH"})) as mock_query:
|
|
value = await main.get_setting("company_name")
|
|
|
|
assert value == "Custom GmbH"
|
|
args, kwargs = mock_query.call_args
|
|
assert "SELECT value FROM settings" in args[0]
|
|
assert args[1] == ("company_name",)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_setting_falls_back_to_default_when_missing():
|
|
with patch.object(main, "db_query", new=AsyncMock(return_value=None)):
|
|
value = await main.get_setting("assistant_name")
|
|
|
|
assert value == "JARVIS"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_all_settings_merges_defaults_with_stored_overrides():
|
|
rows = [{"key": "assistant_name", "value": "FRIDAY"}]
|
|
with patch.object(main, "db_query", new=AsyncMock(return_value=rows)):
|
|
settings = await main.get_all_settings()
|
|
|
|
assert settings == {
|
|
"assistant_name": "FRIDAY",
|
|
"company_name": "MBO-Tech-IT",
|
|
"contact_email": "kontakt@mbo-tech-it.de",
|
|
}
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_all_settings_returns_defaults_when_table_empty():
|
|
with patch.object(main, "db_query", new=AsyncMock(return_value=[])):
|
|
settings = await main.get_all_settings()
|
|
|
|
assert settings == main.SETTINGS_DEFAULTS
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_set_setting_upserts_value():
|
|
with patch.object(main, "db_query", new=AsyncMock(return_value=None)) as mock_query:
|
|
await main.set_setting("company_name", "Neue Firma GmbH")
|
|
|
|
args, kwargs = mock_query.call_args
|
|
assert "INSERT INTO settings" in args[0]
|
|
assert "ON CONFLICT (key) DO UPDATE" in args[0]
|
|
assert args[1] == ("company_name", "Neue Firma GmbH")
|
|
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
main.API_KEY_ADMIN = "test-secret"
|
|
HEADERS = {"X-Admin-Key": "test-secret"}
|
|
|
|
|
|
@pytest.fixture()
|
|
def client():
|
|
with TestClient(main.app) as c:
|
|
yield c
|
|
|
|
|
|
def test_get_settings_endpoint_returns_merged_settings(client):
|
|
settings = {"assistant_name": "JARVIS", "company_name": "MBO-Tech-IT", "contact_email": "kontakt@mbo-tech-it.de"}
|
|
with patch.object(main, "get_all_settings", new=AsyncMock(return_value=settings)):
|
|
response = client.get("/api/v1/settings", headers=HEADERS)
|
|
|
|
assert response.status_code == 200
|
|
assert response.json() == settings
|
|
|
|
|
|
def test_get_settings_endpoint_requires_admin_key(client):
|
|
response = client.get("/api/v1/settings")
|
|
assert response.status_code == 401
|
|
|
|
|
|
def test_put_settings_endpoint_updates_and_returns_merged_settings(client):
|
|
updated = {"assistant_name": "FRIDAY", "company_name": "MBO-Tech-IT", "contact_email": "kontakt@mbo-tech-it.de"}
|
|
with patch.object(main, "set_setting", new=AsyncMock()) as mock_set, patch.object(
|
|
main, "get_all_settings", new=AsyncMock(return_value=updated)
|
|
):
|
|
response = client.put("/api/v1/settings", headers=HEADERS, json={"assistant_name": "FRIDAY"})
|
|
|
|
assert response.status_code == 200
|
|
assert response.json() == updated
|
|
mock_set.assert_called_once_with("assistant_name", "FRIDAY")
|
|
|
|
|
|
def test_put_settings_endpoint_rejects_unknown_key(client):
|
|
with patch.object(main, "set_setting", new=AsyncMock()) as mock_set:
|
|
response = client.put("/api/v1/settings", headers=HEADERS, json={"nonsense_key": "x"})
|
|
|
|
assert response.status_code == 400
|
|
mock_set.assert_not_called()
|
|
|
|
|
|
def test_put_settings_endpoint_requires_admin_key(client):
|
|
response = client.put("/api/v1/settings", json={"assistant_name": "X"})
|
|
assert response.status_code == 401
|