feat: 导入 MemRelay 初始源码
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
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"]
|
||||
Reference in New Issue
Block a user