File size: 7,300 Bytes
bd09498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
"""
Tests des endpoints CRUD /api/v1/corpora (Sprint 4 — Session A).

Vérifie :
- GET  /api/v1/corpora → liste vide puis liste peuplée
- POST /api/v1/corpora → 201 + corps de réponse complet
- POST /api/v1/corpora (slug dupliqué) → 409
- GET  /api/v1/corpora/{id} → 200 ou 404
- DELETE /api/v1/corpora/{id} → 204 ou 404
- Champs manquants dans le POST body → 422 automatique Pydantic
"""
# 1. stdlib
import pytest

# 3. local
from tests.conftest_api import async_client, db_session  # noqa: F401

_CORPUS_PAYLOAD = {
    "slug": "beatus-lat8878",
    "title": "Beatus de Saint-Sever",
    "profile_id": "medieval-illuminated",
}


# ---------------------------------------------------------------------------
# GET /api/v1/corpora
# ---------------------------------------------------------------------------

@pytest.mark.asyncio
async def test_list_corpora_empty(async_client):
    response = await async_client.get("/api/v1/corpora")
    assert response.status_code == 200
    assert response.json() == []


@pytest.mark.asyncio
async def test_list_corpora_after_create(async_client):
    await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    response = await async_client.get("/api/v1/corpora")
    assert response.status_code == 200
    corpora = response.json()
    assert len(corpora) == 1
    assert corpora[0]["slug"] == "beatus-lat8878"


@pytest.mark.asyncio
async def test_list_corpora_multiple(async_client):
    await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    await async_client.post(
        "/api/v1/corpora",
        json={"slug": "grandes-chroniques", "title": "Grandes Chroniques", "profile_id": "medieval-textual"},
    )
    response = await async_client.get("/api/v1/corpora")
    assert len(response.json()) == 2


# ---------------------------------------------------------------------------
# POST /api/v1/corpora
# ---------------------------------------------------------------------------

@pytest.mark.asyncio
async def test_create_corpus_status_201(async_client):
    response = await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    assert response.status_code == 201


@pytest.mark.asyncio
async def test_create_corpus_response_fields(async_client):
    response = await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    data = response.json()
    assert "id" in data
    assert data["slug"] == "beatus-lat8878"
    assert data["title"] == "Beatus de Saint-Sever"
    assert data["profile_id"] == "medieval-illuminated"
    assert "created_at" in data
    assert "updated_at" in data


@pytest.mark.asyncio
async def test_create_corpus_id_is_uuid(async_client):
    response = await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    corpus_id = response.json()["id"]
    # UUID v4 — 36 caractères avec tirets
    assert len(corpus_id) == 36
    assert corpus_id.count("-") == 4


@pytest.mark.asyncio
async def test_create_corpus_duplicate_slug_409(async_client):
    await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    response = await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    assert response.status_code == 409


@pytest.mark.asyncio
async def test_create_corpus_missing_slug_422(async_client):
    response = await async_client.post(
        "/api/v1/corpora", json={"title": "X", "profile_id": "medieval-illuminated"}
    )
    assert response.status_code == 422


@pytest.mark.asyncio
async def test_create_corpus_missing_title_422(async_client):
    response = await async_client.post(
        "/api/v1/corpora", json={"slug": "x", "profile_id": "medieval-illuminated"}
    )
    assert response.status_code == 422


@pytest.mark.asyncio
async def test_create_corpus_missing_profile_id_422(async_client):
    response = await async_client.post(
        "/api/v1/corpora", json={"slug": "x", "title": "X"}
    )
    assert response.status_code == 422


# ---------------------------------------------------------------------------
# GET /api/v1/corpora/{id}
# ---------------------------------------------------------------------------

@pytest.mark.asyncio
async def test_get_corpus_ok(async_client):
    create_resp = await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    corpus_id = create_resp.json()["id"]

    response = await async_client.get(f"/api/v1/corpora/{corpus_id}")
    assert response.status_code == 200
    assert response.json()["id"] == corpus_id


@pytest.mark.asyncio
async def test_get_corpus_fields(async_client):
    create_resp = await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    corpus_id = create_resp.json()["id"]
    data = (await async_client.get(f"/api/v1/corpora/{corpus_id}")).json()

    assert data["slug"] == "beatus-lat8878"
    assert data["title"] == "Beatus de Saint-Sever"
    assert data["profile_id"] == "medieval-illuminated"


@pytest.mark.asyncio
async def test_get_corpus_not_found(async_client):
    response = await async_client.get("/api/v1/corpora/nonexistent-id")
    assert response.status_code == 404


@pytest.mark.asyncio
async def test_get_corpus_not_found_detail(async_client):
    response = await async_client.get("/api/v1/corpora/unknown")
    assert "introuvable" in response.json()["detail"].lower()


# ---------------------------------------------------------------------------
# DELETE /api/v1/corpora/{id}
# ---------------------------------------------------------------------------

@pytest.mark.asyncio
async def test_delete_corpus_204(async_client):
    create_resp = await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    corpus_id = create_resp.json()["id"]

    response = await async_client.delete(f"/api/v1/corpora/{corpus_id}")
    assert response.status_code == 204


@pytest.mark.asyncio
async def test_delete_corpus_disappears_from_list(async_client):
    create_resp = await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    corpus_id = create_resp.json()["id"]

    await async_client.delete(f"/api/v1/corpora/{corpus_id}")
    list_resp = await async_client.get("/api/v1/corpora")
    assert list_resp.json() == []


@pytest.mark.asyncio
async def test_delete_corpus_makes_get_404(async_client):
    create_resp = await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    corpus_id = create_resp.json()["id"]

    await async_client.delete(f"/api/v1/corpora/{corpus_id}")
    get_resp = await async_client.get(f"/api/v1/corpora/{corpus_id}")
    assert get_resp.status_code == 404


@pytest.mark.asyncio
async def test_delete_corpus_not_found(async_client):
    response = await async_client.delete("/api/v1/corpora/nonexistent")
    assert response.status_code == 404


@pytest.mark.asyncio
async def test_delete_only_target_corpus(async_client):
    """Supprimer un corpus ne supprime pas les autres."""
    r1 = await async_client.post("/api/v1/corpora", json=_CORPUS_PAYLOAD)
    r2 = await async_client.post(
        "/api/v1/corpora",
        json={"slug": "other", "title": "Other", "profile_id": "medieval-textual"},
    )
    await async_client.delete(f"/api/v1/corpora/{r1.json()['id']}")

    list_resp = await async_client.get("/api/v1/corpora")
    remaining = list_resp.json()
    assert len(remaining) == 1
    assert remaining[0]["id"] == r2.json()["id"]