test: prepare connected chat checks for canonical and legacy Subject routes

This commit is contained in:
2026-10-31 14:40:53 +09:00
parent 9e7392256b
commit 7a2d132c16
3 changed files with 54 additions and 3 deletions
@@ -3,11 +3,21 @@
// deliberate lost transport acknowledgement are substituted. No live instance.
import { assert, assertEquals } from "@std/assert";
import { chromium } from "playwright";
import {
subjectChatHref,
subjectHref,
} from "../../../web/workspace/src/lib/workspace/subjektiv/routes.ts";
const input = JSON.parse(await new Response(Deno.stdin.readable).text());
const origin = new URL(input.origin);
assert(origin.hostname === "127.0.0.1" && origin.protocol === "http:");
const base = `/api/w/${encodeURIComponent(input.workspace_id)}/chat/conversations`;
const detail = subjectHref(input.workspace_id, input.subject_id);
const chat = subjectChatHref(input.workspace_id, input.subject_id);
const legacy = `/w/${encodeURIComponent(input.workspace_id)}/memory/${
encodeURIComponent(input.subject_id)
}`;
const suffix = "?from=legacy&encoded=%2Fkeep%20exact#subject-heading";
const browser = await chromium.launch({ headless: true });
try {
const context = await browser.newContext({
@@ -25,10 +35,39 @@ try {
`${base}/${encodeURIComponent(input.conversation_id)}/messages`
) posts.push(request.postDataJSON());
});
const response = await page.goto(`${origin.origin}${input.subject_path}`);
const response = await page.goto(`${origin.origin}${legacy}${suffix}`);
assertEquals(response?.status(), 200);
await page.getByRole("link", { name: "Open conversation" }).click();
await page.waitForURL(`${origin.origin}${detail}${suffix}`);
const open = page.getByRole("link", { name: "Open conversation" });
assertEquals(await open.getAttribute("href"), chat);
await open.click();
await page.waitForURL(`${origin.origin}${chat}`);
await page.getByText("No public messages yet.").waitFor();
for (const alias of ["conversation", "chat"]) {
const response = await page.goto(`${origin.origin}${legacy}/${alias}${suffix}`);
assertEquals(response?.status(), 200);
await page.waitForURL(`${origin.origin}${chat}${suffix}`);
await page.getByText("No public messages yet.").waitFor();
assertEquals(
await page.getByRole("link", { name: "← Subject details" }).getAttribute("href"),
detail,
);
}
const direct = await context.newPage();
try {
const response = await direct.goto(`${origin.origin}${chat}?from=direct#saved-messages`);
assertEquals(response?.status(), 200);
await direct.getByText("No public messages yet.").waitFor();
await direct.reload();
await direct.getByText("No public messages yet.").waitFor();
assertEquals(
new URL(direct.url()).pathname + new URL(direct.url()).search + new URL(direct.url()).hash,
`${chat}?from=direct#saved-messages`,
);
} finally {
await direct.close();
}
assertEquals(posts.length, 0, "route redirects and direct loads must not submit input");
const composer = page.getByRole("textbox", { name: `Message to ${input.subject_name}` });
await composer.fill("WEB_CONNECTED_FIRST_INPUT");
await page.getByRole("button", { name: "Send message", exact: true }).click();
@@ -59,6 +98,10 @@ try {
{ data: { ...retry, text: "changed payload under original operation" } },
);
assertEquals(conflict.status(), 409);
await page.goto(`${origin.origin}${legacy}/conversation${suffix}`);
await page.waitForURL(`${origin.origin}${chat}${suffix}`);
await page.getByText("Previous send outcome is unknown. Its original input is retained.")
.waitFor();
await page.reload();
await page.getByText("Previous send outcome is unknown. Its original input is retained.")
.waitFor();
@@ -77,6 +120,13 @@ try {
0,
);
assertEquals(await history.getByText("WEB_CONNECTED_BUSY_INPUT", { exact: true }).count(), 1);
for (const entry of [chat, `${legacy}/conversation`, `${legacy}/chat`]) {
const response = await page.goto(`${origin.origin}${entry}${suffix}`);
assertEquals(response?.status(), 200);
await page.waitForURL(`${origin.origin}${chat}${suffix}`);
await page.getByText("public reply 3", { exact: true }).waitFor();
assertEquals(await history.getByRole("listitem").count(), 4);
}
const deniedPath = `${origin.origin}${base}/${
encodeURIComponent(input.conversation_id)
}/messages`;