Files
TieMeasureFlow/server/tests/test_settings.py
Adriano dd2ebf863a feat: FASE 7 - Polish & Testing (security, i18n, test suite, docs)
Security hardening: CORS lockdown, rate limiting middleware con sliding
window e eviction IP stale, security headers (CSP, HSTS, X-Frame-Options),
session cookie hardening, filename sanitization upload.

i18n completion: internazionalizzati barcode.js e csv-export.js con bridge
window.BARCODE_I18N/CSV_I18N, aggiornati .po IT/EN con 27 nuove stringhe.

Tablet UX: touch target 44px per dispositivi coarse pointer.

Test suite: 101 test totali (76 server + 25 client), copertura completa
di tutti i router API, autenticazione, ruoli, CRUD, SPC, file upload,
security integration. Infrastruttura SQLite async in-memory con fixtures.

Fix critici: MissingGreenlet in recipe_service (selectinload eager),
route ordering tasks.py, auth_service bcrypt diretto, Measurement.id
Integer per SQLite.

Documentazione: API.md (riferimento completo 40+ endpoint),
DEPLOYMENT.md (guida produzione con Docker/Nginx/SSL),
USER_GUIDE.md (manuale utente per ruolo).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 17:10:24 +01:00

108 lines
3.2 KiB
Python

"""Tests for settings router (/api/settings)."""
import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession
from models.setting import SystemSetting
from models.user import User
from tests.conftest import auth_headers
class TestGetSettings:
"""GET /api/settings/ tests."""
async def test_get_settings(
self,
client: AsyncClient,
admin_user: User,
db_session: AsyncSession,
):
"""Authenticated user can retrieve settings."""
# Seed a setting
setting = SystemSetting(
setting_key="test_setting",
setting_value="test_value",
setting_type="string",
)
db_session.add(setting)
await db_session.flush()
resp = await client.get(
"/api/settings/", headers=auth_headers(admin_user)
)
assert resp.status_code == 200
data = resp.json()
assert isinstance(data, dict)
assert data.get("test_setting") == "test_value"
async def test_get_settings_empty(
self, client: AsyncClient, maker_user: User
):
"""Empty settings returns empty dict."""
resp = await client.get(
"/api/settings/", headers=auth_headers(maker_user)
)
assert resp.status_code == 200
assert resp.json() == {} or isinstance(resp.json(), dict)
async def test_get_setting_by_key(
self,
client: AsyncClient,
admin_user: User,
db_session: AsyncSession,
):
"""Settings dict contains specific key after creation."""
setting = SystemSetting(
setting_key="csv_delimiter",
setting_value=";",
setting_type="string",
)
db_session.add(setting)
await db_session.flush()
resp = await client.get(
"/api/settings/", headers=auth_headers(admin_user)
)
assert resp.status_code == 200
assert resp.json()["csv_delimiter"] == ";"
class TestUpdateSettings:
"""PUT /api/settings/ tests."""
async def test_update_settings(
self, client: AsyncClient, admin_user: User
):
"""Admin can update/create settings."""
resp = await client.put(
"/api/settings/",
headers=auth_headers(admin_user),
json={
"company_name": "Tielogic Srl",
"csv_delimiter": ",",
},
)
assert resp.status_code == 200
data = resp.json()
assert data["message"].startswith("Updated")
assert "company_name" in data["updated_keys"]
assert "csv_delimiter" in data["updated_keys"]
# Verify persistence
get_resp = await client.get(
"/api/settings/", headers=auth_headers(admin_user)
)
settings = get_resp.json()
assert settings["company_name"] == "Tielogic Srl"
async def test_settings_require_admin(
self, client: AsyncClient, maker_user: User
):
"""Non-admin user cannot update settings."""
resp = await client.put(
"/api/settings/",
headers=auth_headers(maker_user),
json={"some_key": "some_value"},
)
assert resp.status_code == 403