test: prepare connected chat checks for canonical and legacy Subject routes
This commit is contained in:
@@ -111,7 +111,7 @@ async fn chat_web_connected_busy_unknown_replay_and_authorization_use_real_runti
|
|||||||
.kill_on_drop(true)
|
.kill_on_drop(true)
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("explicit browser test requires Deno");
|
.expect("explicit browser test requires Deno");
|
||||||
let wire = serde_json::to_vec(&json!({"origin":f.url,"workspace_id":TEST_WORKSPACE_ID,"subject_path":format!("/w/{TEST_WORKSPACE_ID}/memory/{subject}"),"subject_name":"Web connected companion","conversation_id":c,"owner_token":f.owner,"foreign_token":foreign})).unwrap();
|
let wire = serde_json::to_vec(&json!({"origin":f.url,"workspace_id":TEST_WORKSPACE_ID,"subject_id":subject,"subject_name":"Web connected companion","conversation_id":c,"owner_token":f.owner,"foreign_token":foreign})).unwrap();
|
||||||
let mut stdin = child.stdin.take().unwrap();
|
let mut stdin = child.stdin.take().unwrap();
|
||||||
stdin.write_all(&wire).await.unwrap();
|
stdin.write_all(&wire).await.unwrap();
|
||||||
drop(stdin);
|
drop(stdin);
|
||||||
|
|||||||
@@ -3,11 +3,21 @@
|
|||||||
// deliberate lost transport acknowledgement are substituted. No live instance.
|
// deliberate lost transport acknowledgement are substituted. No live instance.
|
||||||
import { assert, assertEquals } from "@std/assert";
|
import { assert, assertEquals } from "@std/assert";
|
||||||
import { chromium } from "playwright";
|
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 input = JSON.parse(await new Response(Deno.stdin.readable).text());
|
||||||
const origin = new URL(input.origin);
|
const origin = new URL(input.origin);
|
||||||
assert(origin.hostname === "127.0.0.1" && origin.protocol === "http:");
|
assert(origin.hostname === "127.0.0.1" && origin.protocol === "http:");
|
||||||
const base = `/api/w/${encodeURIComponent(input.workspace_id)}/chat/conversations`;
|
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 });
|
const browser = await chromium.launch({ headless: true });
|
||||||
try {
|
try {
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
@@ -25,10 +35,39 @@ try {
|
|||||||
`${base}/${encodeURIComponent(input.conversation_id)}/messages`
|
`${base}/${encodeURIComponent(input.conversation_id)}/messages`
|
||||||
) posts.push(request.postDataJSON());
|
) 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);
|
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();
|
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}` });
|
const composer = page.getByRole("textbox", { name: `Message to ${input.subject_name}` });
|
||||||
await composer.fill("WEB_CONNECTED_FIRST_INPUT");
|
await composer.fill("WEB_CONNECTED_FIRST_INPUT");
|
||||||
await page.getByRole("button", { name: "Send message", exact: true }).click();
|
await page.getByRole("button", { name: "Send message", exact: true }).click();
|
||||||
@@ -59,6 +98,10 @@ try {
|
|||||||
{ data: { ...retry, text: "changed payload under original operation" } },
|
{ data: { ...retry, text: "changed payload under original operation" } },
|
||||||
);
|
);
|
||||||
assertEquals(conflict.status(), 409);
|
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.reload();
|
||||||
await page.getByText("Previous send outcome is unknown. Its original input is retained.")
|
await page.getByText("Previous send outcome is unknown. Its original input is retained.")
|
||||||
.waitFor();
|
.waitFor();
|
||||||
@@ -77,6 +120,13 @@ try {
|
|||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
assertEquals(await history.getByText("WEB_CONNECTED_BUSY_INPUT", { exact: true }).count(), 1);
|
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}/${
|
const deniedPath = `${origin.origin}${base}/${
|
||||||
encodeURIComponent(input.conversation_id)
|
encodeURIComponent(input.conversation_id)
|
||||||
}/messages`;
|
}/messages`;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"lock": true,
|
"lock": true,
|
||||||
"imports": {
|
"imports": {
|
||||||
|
"#lib/": "../../web/workspace/src/lib/",
|
||||||
"@std/assert": "jsr:@std/assert@1.0.19",
|
"@std/assert": "jsr:@std/assert@1.0.19",
|
||||||
"@std/path": "jsr:@std/path@1.1.4",
|
"@std/path": "jsr:@std/path@1.1.4",
|
||||||
"pixelmatch": "npm:pixelmatch@7.1.0",
|
"pixelmatch": "npm:pixelmatch@7.1.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user