import { mkdir, writeFile } from "node:fs/promises"; import { test, expect, type Page } from "@playwright/test"; import { baseUrl } from "./baseUrl"; import { channelStage, generateReport, readJson, resetData, resolvePath, writeChannelConfig, writeSite, } from "./helpers"; // Renaming a channel's slug lives in the Danger zone and requires typing the // current slug to confirm (mirroring delete). On success it migrates slug-keyed // state (here: a site membership) and redirects to the new URL; the old URL 404s. const OLD = "test-youtube"; const NEW = "renamed-youtube"; test("rename requires the exact current slug and then moves the channel", async ({ page, }) => { await resetData("one-youtube-channel"); // A site that lists the channel — its membership must follow the rename. await writeSite("mysite", { channels: [{ slug: OLD }] }); // Deliberately NO generateReport here: it queues a refresh-report job, and // renaming refuses while any job for the channel is active. This test doesn't // need a report — the channel page renders fine without one (empty buckets // plus a banner), which is the whole point of not generating inside a GET. await page.goto(channelStage(OLD, "danger")); const newSlug = page.getByLabel("new slug"); const confirm = page.getByLabel("confirm current slug"); const submit = page.getByRole("button", { name: "Rename channel" }); // Wrong confirmation is rejected and stays put. await newSlug.fill(NEW); await confirm.fill("not-the-slug"); await submit.click(); await expect(page.getByText(/Type the channel slug/)).toBeVisible(); // Still on the old channel (a trailing ?site= query may be appended). await expect(page).toHaveURL(new RegExp(`/channels/${OLD}(\\?|$)`)); // Correct confirmation renames and redirects to the new URL. Refill both // fields — React 19 resets the