* feat(infra): backend cookiecutter template with fastapi tortoise * feat(infra): cli cookiecutter template with typer entry point * feat(infra): fullstack cookiecutter template with sveltekit frontend * test(infra): cookiecutter template tests and render fixes * style(infra): ruff cleanup for cookiecutter template tests * style(infra): ruff format cookiecutter template tests * fix(infra): handle use_db no use_auth no in cookiecutter --------- Co-authored-by: opencode-agent <agent@opencode.local>
57 lines
No EOL
2 KiB
Python
57 lines
No EOL
2 KiB
Python
"""Pytest configuration — fixtures shared across all tests."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import AsyncIterator
|
|
from typing import Any
|
|
|
|
import pytest
|
|
from httpx import ASGITransport, AsyncClient
|
|
|
|
from {{ cookiecutter.project_name }}.config.settings import settings
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def mock_settings(monkeypatch) -> None:
|
|
"""Override settings with safe test defaults (no real DB/SMTP/etc)."""
|
|
monkeypatch.setattr(settings, "environment", "dev")
|
|
monkeypatch.setattr(settings, "ip_whitelist", ["127.0.0.1", "::1"])
|
|
|
|
|
|
@pytest.fixture
|
|
async def client() -> AsyncIterator[AsyncClient]:
|
|
"""HTTPX AsyncClient bound to the FastAPI app (no network)."""
|
|
from main import app
|
|
|
|
transport = ASGITransport(app=app)
|
|
async with AsyncClient(transport=transport, base_url="http://test") as ac:
|
|
yield ac
|
|
|
|
|
|
{% if cookiecutter.use_auth == "yes" and cookiecutter.use_db == "yes" %}
|
|
@pytest.fixture
|
|
async def create_user() -> Any:
|
|
"""Factory: create a user in the test DB."""
|
|
from {{ cookiecutter.project_name }}.db.models.user import User
|
|
from {{ cookiecutter.project_name }}.services.auth_service import AuthService
|
|
|
|
async def _create(username: str = "tester", password: str = "password123") -> User:
|
|
hashed = AuthService.hash_password(password)
|
|
return await User.create(username=username, email=f"{username}@test.local", hashed_password=hashed)
|
|
|
|
return _create
|
|
|
|
|
|
@pytest.fixture
|
|
async def auth_client(create_user) -> AsyncIterator[AsyncClient]:
|
|
"""HTTPX client with a valid bearer token pre-set."""
|
|
from main import app
|
|
|
|
await create_user()
|
|
transport = ASGITransport(app=app)
|
|
async with AsyncClient(transport=transport, base_url="http://test") as ac:
|
|
resp = await ac.post("/api/v1/auth/login", json={"username": "tester", "password": "password123"})
|
|
token = resp.json()["access_token"]
|
|
ac.headers["Authorization"] = f"Bearer {token}"
|
|
yield ac
|
|
{% endif %} |