import importlib import pytest from fastapi.testclient import TestClient def _reload_app(tmp_path, monkeypatch, **env): import editor_app.config as config import editor_app.db.session as db_sess import editor_app.main as main monkeypatch.setenv("WORKSPACE_ROOT", str(tmp_path)) monkeypatch.setenv("AUTH_DATABASE_PATH", str(tmp_path / "auth.db")) monkeypatch.delenv("EDITOR_API_KEY", raising=False) monkeypatch.delenv("BOOTSTRAP_ADMIN_USERNAME", raising=False) monkeypatch.delenv("BOOTSTRAP_ADMIN_PASSWORD", raising=False) for k, v in env.items(): monkeypatch.setenv(k, v) config.WORKSPACE_ROOT = tmp_path db_sess.reset_engine() importlib.reload(main) return main.app def test_auth_status_public(tmp_path, monkeypatch): with TestClient(_reload_app(tmp_path, monkeypatch, AUTH_ENABLED="false")) as client: r = client.get("/api/auth/status") assert r.status_code == 200 assert r.json() == {"auth_enabled": False, "register_open": True} def test_register_login_and_api_access(tmp_path, monkeypatch): with TestClient( _reload_app(tmp_path, monkeypatch, AUTH_ENABLED="true", AUTH_REGISTER_OPEN="true") ) as client: assert client.get("/api/files").status_code == 401 reg = client.post("/api/auth/register", json={"username": "alice", "password": "hunter2000"}) assert reg.status_code == 200 body = reg.json() assert body["username"] == "alice" assert body["is_superuser"] is True login = client.post("/api/auth/login", json={"username": "alice", "password": "hunter2000"}) assert login.status_code == 200 ok = client.get("/api/files") assert ok.status_code == 200 me = client.get("/api/auth/me") assert me.status_code == 200 assert me.json()["user"]["username"] == "alice" out = client.post("/api/auth/logout") assert out.status_code == 200 assert client.get("/api/files").status_code == 401 def test_second_user_not_superuser(tmp_path, monkeypatch): with TestClient( _reload_app(tmp_path, monkeypatch, AUTH_ENABLED="true", AUTH_REGISTER_OPEN="true") ) as client: r1 = client.post("/api/auth/register", json={"username": "usr1", "password": "password99"}) assert r1.status_code == 200 assert r1.json()["is_superuser"] is True r2 = client.post("/api/auth/register", json={"username": "usr2", "password": "password99"}) assert r2.status_code == 200 assert r2.json()["is_superuser"] is False def test_register_duplicate_username(tmp_path, monkeypatch): with TestClient( _reload_app(tmp_path, monkeypatch, AUTH_ENABLED="true", AUTH_REGISTER_OPEN="true") ) as client: assert client.post("/api/auth/register", json={"username": "dupuser", "password": "password99"}).status_code == 200 dup = client.post("/api/auth/register", json={"username": "dupuser", "password": "otherpass1"}) assert dup.status_code == 409 def test_register_closed(tmp_path, monkeypatch): with TestClient( _reload_app(tmp_path, monkeypatch, AUTH_ENABLED="true", AUTH_REGISTER_OPEN="false") ) as client: r = client.post("/api/auth/register", json={"username": "bob", "password": "password99"}) assert r.status_code == 403 def test_superuser_lists_and_creates_users(tmp_path, monkeypatch): with TestClient( _reload_app(tmp_path, monkeypatch, AUTH_ENABLED="true", AUTH_REGISTER_OPEN="true") ) as client: client.post("/api/auth/register", json={"username": "admin", "password": "password99"}) client.post("/api/auth/login", json={"username": "admin", "password": "password99"}) listed = client.get("/api/users") assert listed.status_code == 200 assert len(listed.json()) == 1 created = client.post( "/api/users", json={"username": "sub", "password": "password99", "is_superuser": False}, ) assert created.status_code == 200 assert created.json()["username"] == "sub" assert created.json()["is_superuser"] is False names = {u["username"] for u in client.get("/api/users").json()} assert names == {"admin", "sub"} def test_non_superuser_cannot_list_users(tmp_path, monkeypatch): with TestClient( _reload_app(tmp_path, monkeypatch, AUTH_ENABLED="true", AUTH_REGISTER_OPEN="true") ) as client: client.post("/api/auth/register", json={"username": "boss", "password": "password99"}) client.post("/api/auth/login", json={"username": "boss", "password": "password99"}) client.post("/api/auth/logout") client.post("/api/auth/register", json={"username": "peon", "password": "password99"}) client.post("/api/auth/login", json={"username": "peon", "password": "password99"}) denied = client.get("/api/users") assert denied.status_code == 403 def test_login_serves_page(client): r = client.get("/login") assert r.status_code == 200 assert "Sign in" in r.text def test_register_serves_page(client): r = client.get("/register") assert r.status_code == 200 assert "Create account" in r.text