Files
fin-tracker/backend/tests/test_web.py
T
Dmitry 3fc7a954b9 feat(api): FastAPI — auth, RFC 7807 и роуты фазы 1
Префикс /api/v1, operationId = "<tag>_<name>", чтобы Dart-клиент получил методы
вроде accountsList, а не list_accounts_api_v1_accounts_get. Ошибки —
application/problem+json. Auth: access-JWT на час + refresh на 30 дней, который
хранится хэшем и ротируется, логин ограничен по частоте в памяти.

Деньги в JSON — всегда позиционные строки (api/schemas/common.py): float в
проводе потерял бы копейки, которые NUMERIC(24,10) бережёт.

Тестовый harness поднимает свой Postgres через pg_ctl (pytest-postgresql),
мигрирует его один раз на сессию и усекает таблицы после каждого теста.
2026-09-18 13:43:49 +03:00

32 lines
1.3 KiB
Python

from pathlib import Path
import pytest
from httpx import ASGITransport, AsyncClient
@pytest.fixture
async def web_client(migrated: str, tmp_path: Path, monkeypatch):
(tmp_path / "index.html").write_text("<!doctype html><title>spa</title>")
(tmp_path / "main.dart.js").write_text("console.log(1)")
monkeypatch.setenv("WEB_DIR", str(tmp_path))
from fintracker.api.app import create_app
from fintracker.config import get_settings
from fintracker.db import reset_engine
get_settings.cache_clear()
app = create_app()
async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as c:
yield c
get_settings.cache_clear()
await reset_engine()
async def test_spa_fallback_and_api_precedence(web_client):
assert (await web_client.get("/")).text.startswith("<!doctype html>")
assert (await web_client.get("/login")).text.startswith("<!doctype html>") # deep link
assert (await web_client.get("/main.dart.js")).text == "console.log(1)"
assert (await web_client.get("/api/v1/health")).json()["status"] == "ok"
r = await web_client.get("/api/v1/nope")
assert r.status_code == 404 and r.headers["content-type"].startswith("application/problem+json")
assert (await web_client.get("/../etc/passwd")).text.startswith("<!doctype html>")