from pathlib import Path from fastapi.testclient import TestClient from memrelay.app import create_app from memrelay.config import Settings from tests.conftest import csrf_headers from tests.fakes import FakeBasicMemory def test_default_administrator_is_created_once(tmp_path: Path) -> None: settings = Settings(data_dir=tmp_path / "data", public_url="http://testserver") with TestClient(create_app(settings)) as client: assert client.get("/api/v1/auth/status").json() == {"initialized": True} response = client.post( "/api/v1/auth/login", json={"username": "admin", "password": "242520"} ) assert response.status_code == 200 restarted = Settings( data_dir=tmp_path / "data", public_url="http://testserver", initial_admin_password="different-password", ) with TestClient(create_app(restarted)) as client: assert ( client.post( "/api/v1/auth/login", json={"username": "admin", "password": "242520"}, ).status_code == 200 ) def test_session_cookie_security_follows_request_scheme(tmp_path: Path) -> None: http_settings = Settings( data_dir=tmp_path / "http-data", public_url="https://mr.example.com", ) with TestClient(create_app(http_settings), base_url="http://192.168.1.10") as client: response = client.post( "/api/v1/auth/login", json={"username": "admin", "password": "242520"} ) assert response.status_code == 200 assert all("Secure" not in value for value in response.headers.get_list("set-cookie")) https_settings = Settings( data_dir=tmp_path / "https-data", public_url="https://mr.example.com", ) with TestClient(create_app(https_settings), base_url="https://mr.example.com") as client: response = client.post( "/api/v1/auth/login", json={"username": "admin", "password": "242520"} ) assert response.status_code == 200 assert all("Secure" in value for value in response.headers.get_list("set-cookie")) def test_initialize_login_and_logout(client: TestClient) -> None: assert client.get("/api/v1/auth/status").json() == {"initialized": False} response = client.post( "/api/v1/auth/initialize", json={"username": "admin", "password": "strong-test-password"}, ) assert response.status_code == 201 assert response.json()["username"] == "admin" assert client.cookies.get("memrelay_session") assert client.cookies.get("memrelay_csrf") assert client.get("/api/v1/auth/status").json() == {"initialized": True} assert ( client.post( "/api/v1/auth/initialize", json={"username": "other", "password": "another-password"}, ).status_code == 409 ) assert client.post("/api/v1/auth/logout").status_code == 403 assert client.post("/api/v1/auth/logout", headers=csrf_headers(client)).status_code == 204 assert client.get("/api/v1/auth/me").status_code == 401 assert ( client.post( "/api/v1/auth/login", json={"username": "admin", "password": "wrong-password"} ).status_code == 401 ) assert ( client.post( "/api/v1/auth/login", json={"username": "admin", "password": "strong-test-password"}, ).status_code == 200 ) def test_health_and_database_readiness(client: TestClient) -> None: assert client.get("/api/v1/health/live").json() == {"status": "ok"} assert client.get("/api/v1/health/ready").json() == {"status": "ok"} status = client.get("/api/v1/status") assert status.status_code == 200 assert status.json()["status"] == "ok" database = status.json()["database"] assert database["status"] == "ok" assert database["integrity"] == "ok" assert database["journal_mode"] == "wal" assert database["busy_timeout_ms"] == 5000 assert database["wal_autocheckpoint_pages"] == 1000 assert database["database_bytes"] > 0 assert database["check_latency_ms"] >= 0 def test_web_session_can_select_usage_profile_for_default_memory_scope( initialized_client: TestClient, ) -> None: client = initialized_client fake = FakeBasicMemory() client.app.state.basic_memory = fake client.app.state.curation.basic_memory = fake shared = client.get("/api/v1/curation/profiles").json()[0] profile_response = client.put( "/api/v1/curation/profiles", json={"name": "Focused profile", "enabled": True}, headers=csrf_headers(client), ) assert profile_response.status_code == 200 profile = profile_response.json() selected = client.patch( "/api/v1/auth/profile", json={"usage_profile_id": profile["id"]}, headers=csrf_headers(client), ) assert selected.status_code == 200 assert selected.json()["usage_profile_id"] == profile["id"] assert client.get("/api/v1/auth/me").json()["usage_profile_id"] == profile["id"] saved = client.post( "/api/v1/memories", json={ "request_id": "profile-default-memory", "scope": "global", "memory_type": "preference", "title": "Profile preference", "content": "This memory follows the selected Web usage profile.", }, headers=csrf_headers(client), ) assert saved.status_code == 201 assert saved.json()["usage_profile_id"] == profile["id"] reset = client.patch( "/api/v1/auth/profile", json={"usage_profile_id": None}, headers=csrf_headers(client), ) assert reset.status_code == 200 assert reset.json()["usage_profile_id"] == shared["id"]