File size: 4,157 Bytes
4d7e198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
"""
Tests HTTP de l'endpoint GET /api/v1/profiles (Sprint 1 — régression Docker).

Pourquoi ces tests existent :
  GET /api/v1/profiles retournait [] en production (HuggingFace) alors qu'il
  fonctionnait en local. Cause : chemin relatif vers profiles/ non résolu dans
  le container Docker. Ces tests vérifient l'endpoint HTTP complet (pas seulement
  le schéma Pydantic) pour détecter toute régression de chemin en CI.

Stratégie :
  - Utilise le dossier profiles/ réel du dépôt via settings.profiles_dir
    (déjà résolu correctement en local par config.py via Path(__file__).resolve())
  - Teste le cas de régression : retourne [] si profiles_dir est manquant
"""
# 1. stdlib
from pathlib import Path

# 2. third-party
import pytest

# 3. local
import app.config as config_mod
from tests.conftest_api import async_client, db_session  # noqa: F401


# ── Tests "happy path" — utilise le vrai dossier profiles/ ────────────────────

@pytest.mark.asyncio
async def test_list_profiles_returns_nonempty_list(async_client):
    """L'endpoint retourne une liste non vide — régression Docker principale."""
    resp = await async_client.get("/api/v1/profiles")
    assert resp.status_code == 200
    data = resp.json()
    assert isinstance(data, list)
    assert len(data) > 0, (
        f"profiles_dir={config_mod.settings.profiles_dir} "
        f"(exists={config_mod.settings.profiles_dir.is_dir()}) — "
        "l'endpoint retourne [] alors qu'il devrait retourner les 4 profils"
    )


@pytest.mark.asyncio
async def test_list_profiles_returns_all_four_profiles(async_client):
    """Les 4 profils du dépôt sont tous retournés."""
    resp = await async_client.get("/api/v1/profiles")
    assert resp.status_code == 200
    ids = {p["profile_id"] for p in resp.json()}
    expected = {
        "medieval-illuminated",
        "medieval-textual",
        "early-modern-print",
        "modern-handwritten",
    }
    assert ids == expected


@pytest.mark.asyncio
async def test_list_profiles_each_has_required_fields(async_client):
    """Chaque profil expose les champs obligatoires de CorpusProfile."""
    resp = await async_client.get("/api/v1/profiles")
    assert resp.status_code == 200
    for profile in resp.json():
        assert "profile_id" in profile
        assert "label" in profile
        assert "active_layers" in profile
        assert "prompt_templates" in profile
        assert "script_type" in profile
        assert "language_hints" in profile


@pytest.mark.asyncio
async def test_get_profile_by_id(async_client):
    """GET /api/v1/profiles/{id} retourne le profil correspondant."""
    resp = await async_client.get("/api/v1/profiles/medieval-illuminated")
    assert resp.status_code == 200
    data = resp.json()
    assert data["profile_id"] == "medieval-illuminated"
    assert data["script_type"] == "caroline"


@pytest.mark.asyncio
async def test_get_profile_by_id_not_found(async_client):
    """GET /api/v1/profiles/{id} retourne 404 pour un identifiant inconnu."""
    resp = await async_client.get("/api/v1/profiles/nonexistent-xyz")
    assert resp.status_code == 404


# ── Test de régression Docker — simule un profiles_dir manquant ───────────────

@pytest.mark.asyncio
async def test_list_profiles_empty_when_dir_missing(async_client):
    """Retourne [] si profiles_dir n'existe pas (régression Docker).

    Ce test reproduit exactement la condition du bug de production :
    settings.profiles_dir pointe vers un répertoire qui n'existe pas dans
    le container (mauvais chemin résolu). L'endpoint doit retourner [] sans
    erreur 500, mais le test vérifie aussi que le cas ne se produit pas en
    conditions normales (voir test_list_profiles_returns_nonempty_list).
    """
    original = config_mod.settings.profiles_dir
    config_mod.settings.profiles_dir = Path("/nonexistent/path/profiles")
    try:
        resp = await async_client.get("/api/v1/profiles")
    finally:
        config_mod.settings.profiles_dir = original

    assert resp.status_code == 200
    assert resp.json() == []