Files
olivv-cs-ComfyUI-FunPack/app/ui/shell/tests/client.test.js
T

200 lines
7.6 KiB
JavaScript

// Reattaching to a run that outlived the page.
import test from "node:test";
import assert from "node:assert/strict";
import { queuedFor, finishedFor } from "../client.js";
const answering = (body, ok = true) => async () => ({
ok, status: ok ? 200 : 500, json: async () => body,
});
test("the run this browser queued is found by its client id", async () => {
const found = await queuedFor("me", {
fetch: answering({
queue_running: [
[1, "someone-elses", {}, { client_id: "them" }, []],
[2, "mine", {}, { client_id: "me" }, []],
],
queue_pending: [],
}),
});
assert.deepEqual(found, { promptId: "mine", running: true, sceneId: null, sceneIds: [], projectId: null });
});
test("another browser's run is not adopted", async () => {
const promptId = await queuedFor("me", {
fetch: answering({
queue_running: [[1, "theirs", {}, { client_id: "them" }, []]],
queue_pending: [[2, "also-theirs", {}, { client_id: "them" }, []]],
}),
});
assert.equal(promptId, null);
});
test("nothing running means nothing to reattach to", async () => {
assert.equal(await queuedFor("me", {
fetch: answering({ queue_running: [], queue_pending: [] }),
}), null);
});
test("a queue that cannot be reached is not an error the app has to show", async () => {
// The dev server has no queue behind it, which is the ordinary case while
// working on the UI.
const promptId = await queuedFor("me", {
fetch: async () => { throw new TypeError("Failed to fetch"); },
});
assert.equal(promptId, null);
});
test("a malformed queue entry is skipped rather than crashing the load", async () => {
const found = await queuedFor("me", {
fetch: answering({
queue_running: [null, "nonsense", [1], [2, "mine", {}, { client_id: "me" }, []]],
queue_pending: [undefined, {}, [3, null, {}, { client_id: "me" }, []]],
}),
});
assert.deepEqual(found, { promptId: "mine", running: true, sceneId: null, sceneIds: [], projectId: null });
});
test("where a run belongs travels with it, when it said so at queue time", async () => {
const found = await queuedFor("me", {
fetch: answering({
queue_running: [[1, "mine", {}, { client_id: "me", funpack_scene_id: "s1",
funpack_project_id: "p1" }, []]],
queue_pending: [],
}),
});
assert.deepEqual(found, { promptId: "mine", running: true, sceneId: "s1", sceneIds: [], projectId: "p1" });
});
test("a run covering more than one scene carries the whole list, not just the first", async () => {
// No chain sampler to split a multi-scene selection into several /prompt
// calls, so one run can cover several scenes at once -- reattach needs
// every one of them, or a reload only ever recovers the first (see this
// field's own comment in client.js for why sceneId alone is not enough).
const found = await queuedFor("me", {
fetch: answering({
queue_running: [[1, "mine", {}, { client_id: "me", funpack_scene_id: "s1",
funpack_scene_ids: ["s1", "s2", "s3"],
funpack_project_id: "p1" }, []]],
queue_pending: [],
}),
});
assert.deepEqual(found, {
promptId: "mine", running: true, sceneId: "s1", sceneIds: ["s1", "s2", "s3"], projectId: "p1",
});
});
test("a run queued before this existed has nowhere it said it belongs, and says so with null", async () => {
const found = await queuedFor("me", {
fetch: answering({
queue_running: [[1, "mine", {}, { client_id: "me" }, []]],
queue_pending: [],
}),
});
assert.equal(found.sceneId, null);
assert.equal(found.projectId, null);
});
test("a finished run is recognised as this browser's from its history entry", async () => {
const asked = [];
const promptId = await finishedFor("me", ["theirs", "mine"], {
fetch: async (url) => {
asked.push(url);
const id = url.split("/").pop();
const owner = id === "mine" ? "me" : "them";
return { ok: true, status: 200, json: async () => ({
[id]: { prompt: [1, id, {}, { client_id: owner }, []], outputs: {}, status: {} },
}) };
},
});
assert.equal(promptId, "mine");
// Newest first: the run that just ended is the one being looked for.
assert.equal(asked[0], "/history/mine");
});
test("onFound hands back the extra_data of a match, without changing what this returns", async () => {
const found = [];
const promptId = await finishedFor("me", ["mine"], {
fetch: async () => ({ ok: true, status: 200, json: async () => ({
mine: { prompt: [1, "mine", {}, { client_id: "me", funpack_scene_id: "s1",
funpack_project_id: "p1" }, []] },
}) }),
onFound: (extra) => found.push(extra),
});
assert.equal(promptId, "mine");
assert.deepEqual(found, [{ client_id: "me", funpack_scene_id: "s1", funpack_project_id: "p1" }]);
});
test("onFound is never called when nothing matches", async () => {
let called = false;
await finishedFor("me", ["theirs"], {
fetch: async () => ({ ok: true, status: 200, json: async () => ({
theirs: { prompt: [1, "theirs", {}, { client_id: "them" }, []] },
}) }),
onFound: () => { called = true; },
});
assert.equal(called, false);
});
test("a finished run belonging to someone else is not adopted", async () => {
const promptId = await finishedFor("me", ["theirs"], {
fetch: async (url) => ({ ok: true, status: 200, json: async () => ({
theirs: { prompt: [1, "theirs", {}, { client_id: "them" }, []] },
}) }),
});
assert.equal(promptId, null);
});
test("a history entry with nothing in it is skipped, not trusted", async () => {
for (const body of [{}, { mine: {} }, { mine: { prompt: [] } }, { mine: { prompt: [1, "mine", {}] } }]) {
const promptId = await finishedFor("me", ["mine"], {
fetch: async () => ({ ok: true, status: 200, json: async () => body }),
});
assert.equal(promptId, null, JSON.stringify(body));
}
});
test("no history to ask is not an error", async () => {
const promptId = await finishedFor("me", ["mine"], {
fetch: async () => { throw new TypeError("Failed to fetch"); },
});
assert.equal(promptId, null);
});
test("a run still waiting its turn is found too", async () => {
// /queue answers with both halves, and a job sits in the pending one from the
// moment /prompt returns until the worker picks it up -- always briefly, and
// for as long as it takes whenever something is running ahead of it. A reload
// in that window found nothing and let the same job be queued twice.
const promptId = await queuedFor("me", {
fetch: answering({
queue_running: [[1, "theirs", {}, { client_id: "them" }, []]],
queue_pending: [[2, "mine", {}, { client_id: "me" }, []]],
}),
});
assert.deepEqual(promptId, { promptId: "mine", running: false, sceneId: null, sceneIds: [], projectId: null },
"a job waiting its turn was reported as one already under way");
});
test("a run under way is preferred over one still waiting", async () => {
const promptId = await queuedFor("me", {
fetch: answering({
queue_running: [[1, "under-way", {}, { client_id: "me" }, []]],
queue_pending: [[2, "waiting", {}, { client_id: "me" }, []]],
}),
});
assert.deepEqual(promptId, { promptId: "under-way", running: true, sceneId: null, sceneIds: [], projectId: null });
});
test("somebody else's pending run is not adopted either", async () => {
const promptId = await queuedFor("me", {
fetch: answering({
queue_running: [],
queue_pending: [[1, "theirs", {}, { client_id: "them" }, []]],
}),
});
assert.equal(promptId, null);
});