Files
language-llm/backend/tests/test_instructions.py
2026-02-12 18:45:10 +01:00

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