2026-10-15 23:08:47 -06:00
|
|
|
"""Fixtures for server tests. Real PostgreSQL tests run only when TEST_PG_SUPERUSER_URL is set."""
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import secrets
|
|
|
|
|
from collections.abc import Iterator
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
|
|
import pytest
|
2026-10-16 07:40:29 -06:00
|
|
|
from fakedir import FakeDirectory
|
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
|
from pshelpers import ORIGIN_HEADERS, PG_URL, fake_visual, make_settings
|
2026-10-15 23:08:47 -06:00
|
|
|
|
|
|
|
|
from packetstation.settings import Settings
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def dev_visual(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
|
|
|
from packetstation import guard
|
|
|
|
|
|
|
|
|
|
monkeypatch.setattr(guard, "load_visual_settings", lambda: fake_visual(False))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def pg_settings(tmp_path: Path) -> Iterator[Settings]:
|
|
|
|
|
"""A fresh database with ps_migrate/ps_app (passwords reset), migrated to head; dropped afterwards."""
|
|
|
|
|
import psycopg
|
|
|
|
|
from psycopg import sql
|
|
|
|
|
from psycopg.conninfo import conninfo_to_dict
|
|
|
|
|
|
|
|
|
|
from packetstation import db, migrate
|
|
|
|
|
|
|
|
|
|
assert PG_URL
|
|
|
|
|
info = conninfo_to_dict(PG_URL)
|
|
|
|
|
mig_pw, app_pw = secrets.token_urlsafe(18), secrets.token_urlsafe(18)
|
|
|
|
|
(tmp_path / "mig").write_text(mig_pw + "\n")
|
|
|
|
|
(tmp_path / "app").write_text(app_pw + "\r\n")
|
|
|
|
|
name = f"ps_test_{secrets.token_hex(4)}"
|
|
|
|
|
s = make_settings(
|
|
|
|
|
tmp_path,
|
|
|
|
|
pg_host=info.get("host", "localhost"),
|
|
|
|
|
pg_port=int(info.get("port", 5432)),
|
|
|
|
|
pg_database=name,
|
|
|
|
|
pg_migrate_password_file=tmp_path / "mig",
|
|
|
|
|
pg_app_password_file=tmp_path / "app",
|
|
|
|
|
pg_superuser_url=PG_URL,
|
|
|
|
|
)
|
|
|
|
|
migrate.bootstrap_roles(s)
|
|
|
|
|
with psycopg.connect(PG_URL, autocommit=True) as su:
|
|
|
|
|
for user, pw in (("ps_migrate", mig_pw), ("ps_app", app_pw)):
|
|
|
|
|
su.execute(sql.SQL("ALTER ROLE {} LOGIN PASSWORD {}").format(sql.Identifier(user), sql.Literal(pw)))
|
|
|
|
|
with db.connect_as("migrate", s, autocommit=True) as conn:
|
|
|
|
|
migrate.run(conn, db.MIGRATIONS_DIR)
|
|
|
|
|
try:
|
|
|
|
|
yield s
|
|
|
|
|
finally:
|
|
|
|
|
db.close_pool()
|
|
|
|
|
with psycopg.connect(PG_URL, autocommit=True) as su:
|
|
|
|
|
su.execute(sql.SQL("DROP DATABASE IF EXISTS {} WITH (FORCE)").format(sql.Identifier(name)))
|
2026-10-16 07:40:29 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def fake_dir() -> FakeDirectory:
|
|
|
|
|
return FakeDirectory()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def pg_client(pg_settings: Settings, fake_dir: FakeDirectory, dev_visual: None) -> Iterator[TestClient]:
|
|
|
|
|
"""The app on a fresh migrated database with the fake directory; Origin headers set on every call."""
|
|
|
|
|
from packetstation.main import create_app
|
|
|
|
|
|
|
|
|
|
with TestClient(create_app(pg_settings, directory=fake_dir), headers=ORIGIN_HEADERS) as client:
|
|
|
|
|
yield client
|