97 lines
3.8 KiB
JavaScript
97 lines
3.8 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import React from "react";
|
|
import { after, before, test } from "node:test";
|
|
import { createServer } from "vite";
|
|
|
|
let server;
|
|
let useObservatoryRecordedJobs;
|
|
let useObservatoryLaboratorySetups;
|
|
|
|
before(async () => {
|
|
server = await createServer({
|
|
appType: "custom", logLevel: "silent", server: { middlewareMode: true },
|
|
});
|
|
({ useObservatoryRecordedJobs } = await server.ssrLoadModule("/src/core/observatory/useObservatoryRecordedJobs.ts"));
|
|
({ useObservatoryLaboratorySetups } = await server.ssrLoadModule("/src/core/observatory/useObservatoryLaboratorySetups.ts"));
|
|
});
|
|
after(async () => { await server?.close(); });
|
|
|
|
// Deliberately inspect the render BEFORE effects/cleanup: stale state must already be hidden.
|
|
function renderBeforeEffects(hook, args, stateSlots) {
|
|
const internals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
|
|
const previous = internals.H;
|
|
let stateIndex = 0;
|
|
internals.H = {
|
|
useState: (initial) => [
|
|
stateIndex < stateSlots.length ? stateSlots[stateIndex++]
|
|
: typeof initial === "function" ? initial() : initial,
|
|
() => {},
|
|
],
|
|
useRef: (value) => ({ current: value }),
|
|
useMemo: (factory) => factory(),
|
|
useCallback: (fn) => fn,
|
|
useEffect: () => {},
|
|
};
|
|
try { return hook(...args); } finally { internals.H = previous; }
|
|
}
|
|
|
|
test("queue data and errors cannot survive a source/setup/version change for one render", () => {
|
|
const original = ["source-a", "profile-a", "a".repeat(64)];
|
|
const activeJob = { state: "running", publication: { state: "not-required" } };
|
|
const snapshot = {
|
|
selectionKey: JSON.stringify(original), jobs: [activeJob], state: "ready", error: "old error",
|
|
};
|
|
assert.equal(renderBeforeEffects(useObservatoryRecordedJobs, original, [snapshot]).activeJob, activeJob);
|
|
for (const next of [
|
|
["source-b", original[1], original[2]],
|
|
[original[0], "profile-b", original[2]],
|
|
[original[0], original[1], "b".repeat(64)],
|
|
["", "", ""],
|
|
]) {
|
|
const view = renderBeforeEffects(useObservatoryRecordedJobs, next, [snapshot]);
|
|
assert.deepEqual(view.jobs, []);
|
|
assert.equal(view.activeJob, null);
|
|
assert.equal(view.latestJob, null);
|
|
assert.equal(view.error, null);
|
|
assert.notEqual(view.state, "ready");
|
|
}
|
|
});
|
|
|
|
test("published, incompatible and previous-source profiles have no effective selection", () => {
|
|
const profile = {
|
|
setupId: "profile-a", origin: "portable-definition",
|
|
compatibility: { compatible: true },
|
|
runDefinition: { definitionSha256: "a".repeat(64) },
|
|
preflight: { outcome: "ready" },
|
|
};
|
|
function render(sourceId, setups) {
|
|
return renderBeforeEffects(useObservatoryLaboratorySetups, [sourceId], [
|
|
{ sourceSessionId: "source-a", setups }, "ready", null, "profile-a", 0, { kind: "idle" },
|
|
]);
|
|
}
|
|
assert.equal(render("source-a", [profile]).selectedSetupId, "profile-a");
|
|
for (const view of [
|
|
render("source-b", [profile]),
|
|
render("source-a", [{ ...profile, preflight: { outcome: "existing" } }]),
|
|
render("source-a", [{ ...profile, compatibility: { compatible: false } }]),
|
|
render("source-a", []),
|
|
]) {
|
|
assert.equal(view.selectedSetupId, "");
|
|
assert.equal(view.selectedSetup, null);
|
|
assert.deepEqual(view.selectableSetups, []);
|
|
}
|
|
});
|
|
|
|
test("historical failures are not presented as errors of a new operator action", () => {
|
|
const selection = ["source-a", "profile-a", "a".repeat(64)];
|
|
const snapshot = {
|
|
selectionKey: JSON.stringify(selection),
|
|
jobs: [{ jobId: "old-run", state: "failed", publication: { state: "not-required" } }],
|
|
state: "ready", error: null,
|
|
};
|
|
const view = renderBeforeEffects(useObservatoryRecordedJobs, selection, [snapshot]);
|
|
assert.equal(view.computationFailed, false);
|
|
assert.equal(view.error, null);
|
|
assert.equal(view.activeJob, null);
|
|
});
|