118 lines
3.9 KiB
Python
118 lines
3.9 KiB
Python
"""FluentGerman.ai — Instruction management tests."""
|
|
|
|
import pytest
|
|
from httpx import AsyncClient
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_global_instruction(client: AsyncClient, admin_token: str):
|
|
"""Admin can create a global instruction."""
|
|
headers = {"Authorization": f"Bearer {admin_token}"}
|
|
resp = await client.post(
|
|
"/api/instructions/",
|
|
json={"title": "Teaching Method", "content": "Use immersive conversation", "type": "global"},
|
|
headers=headers,
|
|
)
|
|
assert resp.status_code == 201
|
|
data = resp.json()
|
|
assert data["title"] == "Teaching Method"
|
|
assert data["type"] == "global"
|
|
assert data["user_id"] is None
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_create_personal_instruction(client: AsyncClient, admin_token: str, user_token: str):
|
|
"""Admin can create a personal instruction for a user."""
|
|
headers = {"Authorization": f"Bearer {admin_token}"}
|
|
|
|
# Get user id
|
|
users_resp = await client.get("/api/users/", headers=headers)
|
|
user_id = users_resp.json()[0]["id"]
|
|
|
|
resp = await client.post(
|
|
"/api/instructions/",
|
|
json={
|
|
"title": "Focus on verbs",
|
|
"content": "This student needs extra practice with irregular verbs.",
|
|
"type": "personal",
|
|
"user_id": user_id,
|
|
},
|
|
headers=headers,
|
|
)
|
|
assert resp.status_code == 201
|
|
assert resp.json()["user_id"] == user_id
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_list_instructions_by_user(client: AsyncClient, admin_token: str, user_token: str):
|
|
"""Filtering instructions by user returns personal + global."""
|
|
headers = {"Authorization": f"Bearer {admin_token}"}
|
|
|
|
users_resp = await client.get("/api/users/", headers=headers)
|
|
user_id = users_resp.json()[0]["id"]
|
|
|
|
# Create global
|
|
await client.post(
|
|
"/api/instructions/",
|
|
json={"title": "Global Rule", "content": "Always respond in German", "type": "global"},
|
|
headers=headers,
|
|
)
|
|
# Create personal
|
|
await client.post(
|
|
"/api/instructions/",
|
|
json={"title": "Personal", "content": "Focus on A1", "type": "personal", "user_id": user_id},
|
|
headers=headers,
|
|
)
|
|
|
|
resp = await client.get(f"/api/instructions/?user_id={user_id}", headers=headers)
|
|
assert resp.status_code == 200
|
|
instructions = resp.json()
|
|
types = [i["type"] for i in instructions]
|
|
assert "global" in types
|
|
assert "personal" in types
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_update_instruction(client: AsyncClient, admin_token: str):
|
|
"""Admin can update an instruction."""
|
|
headers = {"Authorization": f"Bearer {admin_token}"}
|
|
|
|
create_resp = await client.post(
|
|
"/api/instructions/",
|
|
json={"title": "Old Title", "content": "Old content", "type": "global"},
|
|
headers=headers,
|
|
)
|
|
inst_id = create_resp.json()["id"]
|
|
|
|
resp = await client.put(
|
|
f"/api/instructions/{inst_id}",
|
|
json={"title": "New Title", "content": "Updated content"},
|
|
headers=headers,
|
|
)
|
|
assert resp.status_code == 200
|
|
assert resp.json()["title"] == "New Title"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_delete_instruction(client: AsyncClient, admin_token: str):
|
|
"""Admin can delete an instruction."""
|
|
headers = {"Authorization": f"Bearer {admin_token}"}
|
|
|
|
create_resp = await client.post(
|
|
"/api/instructions/",
|
|
json={"title": "Delete me", "content": "Temp", "type": "global"},
|
|
headers=headers,
|
|
)
|
|
inst_id = create_resp.json()["id"]
|
|
|
|
resp = await client.delete(f"/api/instructions/{inst_id}", headers=headers)
|
|
assert resp.status_code == 204
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_non_admin_cannot_manage_instructions(client: AsyncClient, user_token: str):
|
|
"""Regular user cannot access instruction endpoints."""
|
|
headers = {"Authorization": f"Bearer {user_token}"}
|
|
resp = await client.get("/api/instructions/", headers=headers)
|
|
assert resp.status_code == 403
|