"""ghost — Q4.4 recipe-specific functional test (plan §4.3: "create the app's primary object — a post — and read it back"). Exercises Ghost's core publishing path end-to-end against the live per-run deploy, via the real Admin API: 1. Wait for the Admin API to answer (the recipe's own healthcheck hits /ghost/api/admin/site/). 2. Bootstrap the owner on a fresh deploy + establish an admin session (_ghost.GhostAdmin). 3. POST /ghost/api/admin/posts/ to create a published post carrying a unique marker (title + body). 4. GET /ghost/api/admin/posts// to read it back and assert the marker round-tripped intact. NOT health-only: a Ghost whose DB/Admin-API/publishing path is broken fails here even though `/` (themed front) and `/ghost/` (admin SPA shell) return 200. The marker is unique per run, so a stale or echoed response cannot pass. This closes the DEFERRED.md ghost "create-a-post round-trip" item. """ from __future__ import annotations import os import sys import uuid sys.path.insert(0, os.path.dirname(__file__)) sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", "..", "runner")) import _ghost # noqa: E402 from harness import http as harness_http # noqa: E402 def test_create_post_roundtrip(live_app): # 1) The Admin API (and its DB migrations) may settle slightly after the themed front is up — # poll the recipe's own admin healthcheck endpoint before authenticating. harness_http.retry_http_get( f"https://{live_app}/ghost/api/admin/site/", expect_status=200, max_wait=120, interval=10, ) admin = _ghost.GhostAdmin(live_app) admin.ensure_authenticated() # 2-3) Create a published post with a unique marker in both title and body. uniq = uuid.uuid4().hex[:10] title = f"ccci-marker-{uniq}" marker = f"ccci-body-marker-{uniq}-roundtrip" created = admin.create_post(title, f"

{marker}

") assert created.get("title") == title, ( f"created post title mismatch: sent {title!r}, got {created.get('title')!r}" ) # 4) Read it back by id and assert the post survived the round-trip (title always returned; # html returned because we requested ?formats=html). got = admin.get_post(created["id"]) assert got.get("title") == title, ( f"post title did not round-trip: sent {title!r}, got {got.get('title')!r}" ) html = got.get("html") or "" assert marker in html, ( f"post body did not round-trip: marker {marker!r} not in read-back html {html!r}" )