Files
MajoorWaldi-ComfyUI-Majoor-…/ui/tests/execution_runtime_controller.vitest.ts
T
Ewald ALOEBOETOE d0ab7d594e Resolve remaining ComfyUI integration conflicts
- Move the read-only OpenAPI compat surface from /api/v2/assets to
  /mjr/am/compat/assets so it never squats ComfyUI core's /api namespace;
  the legacy alias is opt-in via MJR_AM_LEGACY_API_V2_ASSETS=1.
- Allow Python 3.14 (requires-python <3.15) and add 3.14 to CI and tox.
- Stop wrapping api.queuePrompt: progress tracking now resolves the
  running prompt from the core Jobs API (getJobDetail), then /queue and
  /history, driven by websocket events. Remove wrapHostQueuePrompt.
- Add opt-in Majoor.Integration.HideNativeAssetsTab setting that hides
  ComfyUI's native Assets sidebar tab through the official
  getSidebarTabs/unregisterSidebarTab API and restores it when disabled.
- Fix all 913 type errors in tsconfig.test.json and type-check tests in
  CI; drop a duplicated `stubs` key in asset_card_inner test; make
  addToastHistory's type argument optional for the object form.
- Update audit report, changelog, API reference and env var docs.
2026-11-03 21:16:34 +00:00

94 lines
3.1 KiB
TypeScript

import { describe, expect, it, vi, beforeEach, afterEach } from "vitest";
import { createExecutionRuntimeController } from "../features/stacks/executionRuntimeController.js";
describe("createExecutionRuntimeController", () => {
beforeEach(() => {
vi.useFakeTimers();
if (typeof globalThis.CustomEvent === "undefined") {
globalThis.CustomEvent = class CustomEvent {
constructor(type, init = {}) {
(this as any).type = type;
(this as any).detail = (init as any).detail;
}
} as any;
}
if (typeof globalThis.window === "undefined") {
globalThis.window = {
dispatchEvent: () => true,
} as any;
}
});
afterEach(() => {
vi.useRealTimers();
});
it("indexes the first executed output immediately and buffers the rest until execution end", async () => {
const post = vi.fn(async () => ({ ok: true, data: {} }));
const controller = createExecutionRuntimeController({
post,
ENDPOINTS: {
INDEX_FILES: "/index-files",
STACKS_AUTO_STACK: "/stacks/auto-stack",
SCAN: "/scan",
},
reportError: () => {},
extractOutputFiles: (output) => output,
ensureExecutionRuntime: () => ({ active_prompt_id: "job-1" }),
emitRuntimeStatus: () => {},
refreshGeneratedFeedHosts: () => {},
getActiveGridContainer: () => null,
});
controller.handleExecutionStart(
{ detail: { prompt_id: "job-1", timestamp: Date.now() } },
{
setCurrentJobId: () => {},
},
);
controller.handleExecutedEvent(
{
detail: {
prompt_id: "job-1",
output: [
{ filename: "first.png", subfolder: "out", type: "output" },
{ filename: "second.png", subfolder: "out", type: "output" },
],
},
},
{ appRef: {} },
);
expect(post).toHaveBeenCalledTimes(1);
expect(post).toHaveBeenNthCalledWith(
1,
"/index-files",
expect.objectContaining({
origin: "generation",
prompt_id: "job-1",
files: [expect.objectContaining({ filename: "first.png" })],
}),
);
controller.handleExecutionEnd(
{ type: "execution_success", detail: { prompt_id: "job-1" } },
{ setCurrentJobId: () => {} },
);
await vi.advanceTimersByTimeAsync(500);
expect(post).toHaveBeenCalledTimes(2);
expect(post).toHaveBeenNthCalledWith(
2,
"/index-files",
expect.objectContaining({
origin: "generation",
prompt_id: "job-1",
files: [expect.objectContaining({ filename: "second.png" })],
}),
);
});
});