"""Tests for :class:`app.services.admin_pages.AdminPagesService`.""" from __future__ import annotations from pathlib import Path from typing import Iterator import pytest from sqlalchemy import Engine from app.db import build_engine, run_migrations from app.models.seed import run_seed from app.services.admin_pages import AdminPagesService from app.services.audit import AuditService from app.services.markdown import MarkdownService from app.services.pages import PageService from app.services.posts import PostService @pytest.fixture def engine(tmp_path: Path) -> Iterator[Engine]: """Return an isolated migrated + seeded engine.""" db_path = tmp_path / "phase4_pages.db" eng = build_engine(f"sqlite:///{db_path}") run_migrations(eng) run_seed(eng) yield eng eng.dispose() @pytest.fixture def service(engine: Engine) -> AdminPagesService: """Return a fully-wired :class:`AdminPagesService`.""" return AdminPagesService( engine=engine, markdown=MarkdownService(), page_service=PageService(engine), post_service=PostService(engine), audit=AuditService(engine), ) def test_get_about_returns_seeded_page(service: AdminPagesService) -> None: """The seeded About page loads.""" page = service.get_about() assert page is not None assert page.slug == "about" assert page.title == "About the Farm" def test_update_about_rewrites_html_cache( service: AdminPagesService, ) -> None: """Update regenerates the sanitized HTML and bumps ``updated_at``.""" before = service.get_about() assert before is not None updated = service.update_about( title="New About Title", body_md="Some **bold** copy.", actor_user_id=1, ) assert updated is not None assert updated.slug == "about" # slug immutable assert updated.title == "New About Title" assert "bold" in updated.body_html_cached # updated_at should bump (or at least not go backwards). assert updated.updated_at >= before.updated_at def test_update_about_invalidates_public_page_cache(engine: Engine) -> None: """After an update the public :class:`PageService` cache returns fresh copy.""" md = MarkdownService() pages = PageService(engine) posts = PostService(engine) audit = AuditService(engine) service = AdminPagesService( engine=engine, markdown=md, page_service=pages, post_service=posts, audit=audit, ) primed = pages.get_by_slug("about") # Cache hit confirmation: assert pages.get_by_slug("about") is primed service.update_about( title="After", body_md="updated copy", actor_user_id=1, ) after = pages.get_by_slug("about") assert after is not None assert after is not primed assert after.title == "After"