gendesign/tradein-mvp/backend/tests/test_version_api.py
lekss361 8423af5dd5
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-browser (push) Successful in 36s
Deploy Trade-In / build-frontend (push) Successful in 2m23s
Deploy Trade-In / test (push) Successful in 3m14s
Deploy Trade-In / build-backend (push) Successful in 4m19s
Deploy Trade-In / deploy (push) Successful in 1m44s
feat(tradein): версионирование продукта — единый источник, подвал, PDF, /versions (#2824)
2026-08-10 16:00:54 +00:00

99 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Tests for GET /api/v1/trade-in/version (build metadata) — app/core/version.py +
app/api/v1/version.py.
Isolated FastAPI app (no full app.main import, no DB) — same pattern as
tests/test_geocode_reverse_api.py: mount only the router under test.
"""
from __future__ import annotations
import importlib
import os
os.environ.setdefault("DATABASE_URL", "postgresql+psycopg://test:test@localhost:5432/test")
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from app.api.v1 import version as version_module
from app.core import version as version_core
@pytest.fixture
def app() -> FastAPI:
application = FastAPI()
application.include_router(version_module.router, prefix="/api/v1/trade-in")
return application
# ── GET /api/v1/trade-in/version ─────────────────────────────────────────────
def test_version_endpoint_shape(app: FastAPI) -> None:
client = TestClient(app)
r = client.get("/api/v1/trade-in/version")
assert r.status_code == 200
body = r.json()
assert set(body.keys()) == {"version", "sha", "built_at"}
assert isinstance(body["version"], str) and body["version"]
assert isinstance(body["sha"], str) and body["sha"]
assert isinstance(body["built_at"], str) and body["built_at"]
def test_version_endpoint_matches_core_constants(app: FastAPI) -> None:
client = TestClient(app)
body = client.get("/api/v1/trade-in/version").json()
assert body["version"] == version_core.APP_VERSION
assert body["sha"] == version_core.BUILD_SHA
assert body["built_at"] == version_core.BUILD_DATE
def test_version_path_is_public_no_auth_required() -> None:
"""rbac_guard must let this path through without X-Authenticated-User /
session — see app/core/rbac.py::_PUBLIC_PATHS. Not a secret, no DB call."""
from app.core.rbac import _PUBLIC_PATHS
assert "/api/v1/trade-in/version" in _PUBLIC_PATHS
# ── app/core/version.py — product_version_line / format_build_date_human ────
def test_product_version_line_format() -> None:
line = version_core.product_version_line("Мера")
assert line.startswith("Мера v")
parts = line.split(" · ")
assert len(parts) == 3, f"expected 'name vX.Y.Z · sha · date', got {line!r}"
def test_format_build_date_human_parses_iso_utc() -> None:
assert version_core.format_build_date_human("2026-08-10T12:00:00Z") == "10.08.2026"
def test_format_build_date_human_falls_back_on_garbage_without_raising() -> None:
assert version_core.format_build_date_human("not-a-date") == "not-a-date"
# ── Fallback when APP_VERSION/BUILD_SHA/BUILD_DATE env vars are absent ──────
# (local `uvicorn` run without a Docker build — see module docstring in
# app/core/version.py). Reloading the module re-executes its module-level
# env reads; nothing here may raise.
def test_module_import_falls_back_without_build_env(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("APP_VERSION", raising=False)
monkeypatch.delenv("BUILD_SHA", raising=False)
monkeypatch.delenv("BUILD_DATE", raising=False)
reloaded = importlib.reload(version_core)
assert reloaded.BUILD_SHA == "dev"
assert reloaded.APP_VERSION # non-empty: VERSION file content or "0.0.0" default
assert reloaded.BUILD_DATE.endswith("Z")
# format/product helpers must still work off the fallback values (no crash).
assert reloaded.product_version_line("Мера").startswith("Мера v")
# Reload once more so any test running later in this process sees a module
# state consistent with whatever env pytest was actually invoked under.
importlib.reload(version_core)