Files
intotheeast-com/tests/ui/post/edit-mode.spec.js
m038andClaude Opus 4.8 d576487886 test(post): share createPhotoEntry helper and fix cleanup leak
Hoist the duplicated per-spec createEntry photo-fixture into a single
createPhotoEntry() in helpers.js (used by delete-flow, edit-mode, and the
anon-view draft). Register the tag for cleanup BEFORE the awaited 15s
success-toast assertion, so a create that lands on disk but whose toast
assertion times out no longer leaks an untracked entry. Add AE3b covering the
disclosure deviation branch (a non-default toggle auto-expands More options).

Code review F2 (leak), F3 (duplication), F6 (coverage).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Mpdu3Dt1iVoozHwAMyjrbn
2026-07-07 08:32:09 +02:00

83 lines
4.0 KiB
JavaScript
Raw Permalink 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.
// @ts-check
// Tests: ES1ES3 — edit mode field SAVE round-trip + prefill error states.
//
// Complements photo-editor.spec.js (which covers the live photo add/delete/
// reorder inside edit mode). Here we cover the *text* side of edit mode:
// - ES1 drives a real end-to-end save: create → open the feed card's Edit link
// → change title + body → Save → assert the new values land back on disk.
// - ES2/ES3 mock the prefill fetch to force the two D7 failure branches
// (404 "no longer exists" vs a transient "couldn't be loaded") — the copy
// that tells the owner whether a retry is worthwhile. These had zero coverage.
const { test, expect } = require('@playwright/test');
const {
fillEditor, createPhotoEntry, cleanupEntry, findEntry, readEntryMd, ACTIVE_TRIP_URL,
} = require('../helpers');
// Synthetic route for the mocked error tests — never has to exist on disk.
const MISSING_ROUTE = '/trips/italy-2026-demo/dailies/does-not-exist';
const created = [];
test.afterAll(() => created.forEach(cleanupEntry));
// ── ES1: edit-mode save writes the changed title + body back to disk ──────────
test('ES1: editing an entry saves the changed title and body back in place', async ({ page }) => {
const tag = `es1-${Date.now()}`;
await createPhotoEntry(page, tag, { created });
// Reach edit mode the way the owner does: via the feed card's Edit link.
await page.goto(ACTIVE_TRIP_URL);
const card = page.locator('.journal-post', { hasText: tag });
await expect(card).toHaveCount(1);
const editHref = await card.locator('.entry-action--edit').getAttribute('href');
expect(editHref).toContain('/post?edit=');
await page.goto(editHref);
// Prefill is async (GET /api/v1/pages{route}); wait until it populates.
await expect(page.locator('input[name="data[title]"]'))
.toHaveValue(`UI Test ${tag}`, { timeout: 15_000 });
await page.fill('input[name="data[title]"]', `UI Test ${tag} EDITED`);
await fillEditor(page, `Edited body for ${tag}.`);
await page.locator('.btn-post').evaluate(el => el.click());
// overwrite_mode:edit writes back in place — assert both changes on disk.
await expect.poll(() => {
const dir = findEntry(tag);
return dir ? (readEntryMd(dir) || '') : '';
}, { timeout: 15_000 }).toContain('EDITED');
const md = readEntryMd(findEntry(tag));
expect(md, 'edited body should persist').toContain(`Edited body for ${tag}.`);
});
// ── ES2: prefill 404 → the "no longer exists" (deleted) branch ────────────────
test('ES2: opening a deleted entry for editing shows the "no longer exists" notice', async ({ page }) => {
await page.route('**/api/v1/pages/**', (route) => {
if (route.request().method() === 'GET') return route.fulfill({ status: 404, body: '' });
return route.continue();
});
await page.goto('/post?edit=' + encodeURIComponent(MISSING_ROUTE));
const banner = page.locator('.post-edit-error');
await expect(banner).toContainText('no longer exists', { timeout: 15_000 });
await expect(banner).toHaveAttribute('role', 'alert');
// D7: the form is left empty rather than half-filled.
await expect(page.locator('input[name="data[title]"]')).toHaveValue('');
});
// ── ES3: prefill 500 → the transient "couldn't be loaded" (retry) branch ──────
test('ES3: a transient prefill failure shows the retry-able "be loaded" notice', async ({ page }) => {
await page.route('**/api/v1/pages/**', (route) => {
if (route.request().method() === 'GET') return route.fulfill({ status: 500, body: '' });
return route.continue();
});
await page.goto('/post?edit=' + encodeURIComponent(MISSING_ROUTE));
// Copy differs from the 404 case so the owner knows a retry is worthwhile.
await expect(page.locator('.post-edit-error'))
.toContainText('be loaded for editing', { timeout: 15_000 });
await expect(page.locator('input[name="data[title]"]')).toHaveValue('');
});