flask_template_codex/tests/admin/test_admin.py
2026-08-08 04:14:25 +02:00

149 lines
4.3 KiB
Python

from uuid import uuid4
import pytest
from sqlalchemy.exc import IntegrityError
from app import create_app
from app.auth.models import User
from app.auth.services import create_user
from app.extensions import db as database
from app.tasks.services import add_subtask, configure_focus, create_task
@pytest.fixture()
def admin_app():
application = create_app("testing", {"FEATURE_ADMIN": True})
with application.app_context():
database.create_all()
yield application
database.session.remove()
database.drop_all()
@pytest.fixture()
def admin_client(admin_app):
return admin_app.test_client()
def login(client, email: str) -> None:
client.post(
"/auth/login",
data={"email": email, "password": "secure password"},
)
def user_with_role(username: str, role: str) -> User:
user = create_user(
username,
f"{username}@example.com",
"secure password",
)
user.role = role
database.session.commit()
return user
def test_admin_feature_is_absent_by_default(app, client):
endpoints = {rule.endpoint for rule in app.url_map.iter_rules()}
assert "admin.index" not in endpoints
assert client.get("/admin/").status_code == 404
def test_enabled_admin_redirects_anonymous_users(admin_client):
response = admin_client.get("/admin/")
assert response.status_code == 302
assert "/auth/login" in response.headers["Location"]
@pytest.mark.parametrize("role", ["user", "viewer", "coach"])
def test_non_admin_roles_receive_calm_forbidden_page(admin_client, role):
user = user_with_role(f"non_admin_{role}", role)
login(admin_client, user.email)
response = admin_client.get("/admin/")
assert response.status_code == 403
assert b"not available for your role" in response.data
def test_admin_can_open_data_free_placeholder(admin_client):
user = user_with_role("admin_user", "admin")
login(admin_client, user.email)
response = admin_client.get("/admin/")
assert response.status_code == 200
assert b"User management" in response.data
assert b"Analytics" in response.data
assert response.data.count(b"Not implemented") == 2
assert b'href="/admin/"' in response.data
def test_database_rejects_unknown_roles(admin_app):
user = User(
username="invalid_role",
email="invalid-role@example.com",
role="superuser",
)
user.set_password("secure password")
database.session.add(user)
with pytest.raises(IntegrityError):
database.session.commit()
database.session.rollback()
def test_viewer_can_read_but_every_task_mutation_is_forbidden(client, db):
viewer = user_with_role("readonly_user", "viewer")
task = create_task(
viewer.id,
title="Readable task",
description=None,
status="not_started",
priority="normal",
due_date=None,
)
subtask = add_subtask(task, "Readable step")
configure_focus(task, timer_minutes=5, context=None, chunk_minutes=[5])
login(client, viewer.email)
assert client.get("/tasks/").status_code == 200
assert client.get(f"/tasks/{task.id}").status_code == 200
assert client.get("/tasks/export/json").status_code == 200
operations = [
("get", "/tasks/new"),
("get", f"/tasks/{task.id}/edit"),
("post", f"/tasks/{task.id}/delete"),
("post", f"/tasks/{task.id}/subtasks"),
("post", f"/tasks/{task.id}/subtasks/{subtask.id}/toggle"),
("post", f"/tasks/{task.id}/focus-settings"),
("post", f"/tasks/{task.id}/chunks/0/toggle"),
("post", f"/tasks/{task.id}/complete"),
("post", "/tasks/import/markdown"),
("post", "/tasks/import/json"),
("post", "/tasks/completed/clear"),
("post", f"/tasks/completed/undo/{uuid4()}"),
]
for method, path in operations:
response = getattr(client, method)(path)
assert response.status_code == 403, path
def test_coach_retains_owned_task_write_access(client, db):
coach = user_with_role("coach_user", "coach")
login(client, coach.email)
response = client.post(
"/tasks/new",
data={
"title": "Coach-owned task",
"status": "not_started",
"priority": "normal",
"due_date": "",
},
)
assert response.status_code == 302