refactor: rewrite from Ruby/Sinatra to Python/FastAPI
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
"""Shared fixtures for the volumen test suite."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import tempfile
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from volumen import reset_login_attempts
|
||||
from volumen.config import Config
|
||||
from volumen.password import hash_password as hash_pw
|
||||
from volumen.store import Store
|
||||
from volumen.users import Users
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _reset_login_attempts() -> Generator[None, None, None]:
|
||||
"""Reset the global login-attempts tracker before every test."""
|
||||
reset_login_attempts()
|
||||
yield
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tmp_dir() -> Generator[Path, None, None]:
|
||||
"""Create a temporary directory that is cleaned up after the test."""
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
yield Path(d)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tmp_content_dir(tmp_path: Path) -> Path:
|
||||
"""Temporary content directory with sample posts."""
|
||||
content = tmp_path / "posts"
|
||||
content.mkdir()
|
||||
(content / "hello.md").write_text(
|
||||
'+++\ntitle = "Hello"\ntags = ["intro"]\n+++\n\nHello **world**.\n'
|
||||
)
|
||||
(content / "draft.md").write_text('+++\ntitle = "Draft"\ndraft = true\n+++\n\nSecret.\n')
|
||||
return content
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config(tmp_content_dir: Path) -> Config:
|
||||
"""Test Config instance pointing at a temp content directory."""
|
||||
return Config.load(
|
||||
path="/nonexistent/volumen.toml",
|
||||
overrides={"content": str(tmp_content_dir)},
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def store(tmp_content_dir: Path) -> Store:
|
||||
"""Test Store instance backed by a temp content directory."""
|
||||
return Store(str(tmp_content_dir), default_lang="en")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def users_path(tmp_path: Path) -> str:
|
||||
"""Path for a temporary users.toml file."""
|
||||
return str(tmp_path / "users.toml")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def bootstrap_hash() -> str:
|
||||
"""A pre-hashed password for bootstrap tests."""
|
||||
return hash_pw("secret")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def users(users_path: str, bootstrap_hash: str) -> Users:
|
||||
"""Test Users instance with bootstrap admin user."""
|
||||
return Users(path=users_path, bootstrap_hash=bootstrap_hash)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client(config: Config, store: Store) -> TestClient:
|
||||
"""FastAPI TestClient for public API tests."""
|
||||
from volumen.server import create_app
|
||||
|
||||
app = create_app(config, store)
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def admin_config_dir(tmp_path: Path) -> Path:
|
||||
"""Create a directory with config and posts for admin tests."""
|
||||
posts_dir = tmp_path / "posts"
|
||||
posts_dir.mkdir()
|
||||
users_path = tmp_path / "users.toml"
|
||||
config_path = tmp_path / "config.toml"
|
||||
pw_hash = hash_pw("secret")
|
||||
config_path.write_text(
|
||||
f'content_dir = "{posts_dir}"\n'
|
||||
f'users_file = "{users_path}"\n\n'
|
||||
"[admin]\n"
|
||||
f'password_hash = "{pw_hash}"\n'
|
||||
)
|
||||
return tmp_path
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def admin_client(admin_config_dir: Path) -> TestClient:
|
||||
"""FastAPI TestClient for admin tests with bootstrap admin."""
|
||||
from volumen.config import Config
|
||||
from volumen.server import create_app
|
||||
from volumen.store import Store
|
||||
|
||||
config = Config.load(path=str(admin_config_dir / "config.toml"))
|
||||
store = Store(config.content_dir, default_lang="en")
|
||||
app = create_app(config, store)
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sample_post_md() -> str:
|
||||
"""Sample post in Markdown with TOML frontmatter."""
|
||||
return (
|
||||
'+++\ntitle = "Test Post"\nslug = "test-post"\nlang = "en"\n'
|
||||
'tags = ["python", "blog"]\ndate = 2026-01-15\ndraft = false\n+++\n\n'
|
||||
"This is the **body** of the post.\n\nSecond paragraph."
|
||||
)
|
||||
Reference in New Issue
Block a user