import assert from "node:assert/strict" import { readFile } from "node:fs/promises" import test from "node:test" import vm from "node:vm" import ts from "typescript" async function compile(path, imports) { const source = await readFile(new URL(path, import.meta.url), "utf8") const compiled = ts.transpileModule(source, { compilerOptions: { target: ts.ScriptTarget.ES2020, module: ts.ModuleKind.CommonJS, jsx: ts.JsxEmit.ReactJSX } }) const loaded = { exports: {} } vm.runInNewContext(compiled.outputText, { exports: loaded.exports, module: loaded, Intl, Date, Set, AbortController, setTimeout, clearTimeout, require: name => { assert.ok(name in imports, `unexpected import ${name}`); return imports[name] } }) return loaded.exports } const helpers = await compile("../../lib/support-availability.ts", {}) const enums = await compile("../../lib/generated/enums.ts", {}) const mappings = await compile("../../lib/support-availability-i18n.ts", { "@/lib/generated/enums": enums }) const guard = await compile("../../lib/session-request-guard.ts", {}) const sessionA = { user: { id: 1 }, accessToken: "fixture-a" } const sessionB = { user: { id: 2 }, accessToken: "fixture-b" } const calendar = { teamId: 5, mode: "recurring", timezone: "UTC", effectiveTimezone: "UTC", deploymentTimezone: "UTC", weekly: [], exceptions: [] } const operator = { userId: 1, serviceStatus: 1, effectiveServiceStatus: 1, returnServiceStatus: 0, reason: "busy", online: true, calendar } function deferred() { let resolve; const promise = new Promise(r => { resolve = r }); return { promise, resolve } } function find(node, predicate) { if (!node || typeof node !== "object") return null if (predicate(node)) return node for (const value of Object.values(node.props ?? {})) { for (const child of Array.isArray(value) ? value.flat(Infinity) : [value]) { const found = find(child, predicate) if (found) return found } } return null } async function harness(kind, options = {}) { let session = sessionA, stateIndex = 0 const effects = [], calls = [], saved = [] const apiResult = options.apiResult ?? Promise.resolve(operator) const formValues = options.formValues ?? { serviceStatus: "1", start: "", end: "", startOccurrence: "", endOccurrence: "" } const jsx = (type, props, key) => ({ type, props, key }) const controls = new Proxy({}, { get: (_target, name) => name }) const imports = { "react/jsx-runtime": { jsx, jsxs: jsx, Fragment: "Fragment" }, react: { useRef: value => ({ current: value }), useState: value => { const current = stateIndex++; return [current === 0 && options.editing ? true : typeof value === "function" ? value() : value, () => {}] }, useEffect: fn => { effects.push(fn) }, useCallback: fn => fn }, "react-hook-form": { Controller: "Controller", useFieldArray: () => ({ fields: [] }), useForm: () => ({ control: {}, register: () => ({}), handleSubmit: fn => fn, watch: key => key ? formValues[key] : calendar, setError: () => {}, clearErrors: () => {}, reset: () => {}, formState: { errors: {}, isDirty: true } }) }, "lucide-react": controls, "next/link": { default: "Link" }, sonner: { toast: { success: () => {} } }, "@/components/auth-provider": { useAuth: () => ({ session }) }, "@/components/confirm-provider": { useConfirm: () => options.confirm ?? (async () => true) }, "@/components/option-combobox": controls, "@/components/project-dialog": controls, "@/components/ui/badge": controls, "@/components/ui/button": controls, "@/components/ui/field": controls, "@/components/ui/input": controls, "@/components/ui/switch": controls, "@/i18n/provider": { useI18n: () => key => key, useAppLocale: () => ({ locale: "en-US" }) }, "@/lib/auth": { readSession: () => session }, "@/lib/session-request-guard": guard, "@/lib/generated/enums": enums, "@/lib/support-availability-i18n": mappings, "@/lib/support-availability": helpers, "@/components/support-availability/operator-status": { notifyAvailabilityUpdated: () => {} }, "@/lib/api/support-availability": { updateMyAvailability: payload => { calls.push(payload); return apiResult }, updateAgentAvailability: (id, payload) => { calls.push({ id, payload }); return apiResult }, updateSupportCalendar: payload => { calls.push(payload); return options.apiResult ?? Promise.resolve(calendar) } }, } const file = kind === "operator" ? "./operator-status.tsx" : "../../app/(dashboard)/dashboard/support-availability/_components/calendar-editor.tsx" const loaded = await compile(file, imports) const root = kind === "operator" ? loaded.OperatorStatusDialog({ value: operator, onClose() {}, onSaved: value => saved.push(value) }) : loaded.CalendarEditor({ initial: calendar, writable: options.writable ?? true, onDirtyChange() {}, onSaved: value => saved.push(value) }) // Execute only lifetime effects: calendar also registers browser navigation listeners. const lifetime = effects.filter(fn => fn.toString().includes("mounted.current = true")) assert.equal(lifetime.length, 1) const setup = () => lifetime[0]() const submit = find(root, node => node.type === "form").props.onSubmit return { calls, saved, setup, submit: () => submit(kind === "operator" ? formValues : calendar), switchSession: () => { session = sessionB } } } test("operator save still completes after StrictMode setup-cleanup-setup", async () => { const h = await harness("operator") h.setup()(); h.setup() await h.submit() assert.equal(h.calls.length, 1) assert.equal(h.saved.length, 1) }) test("operator save is single-flight and a late prior-session result is ignored", async () => { const pending = deferred() const h = await harness("operator", { apiResult: pending.promise }) h.setup() const first = h.submit(), second = h.submit() h.switchSession(); pending.resolve(operator) await Promise.all([first, second]) assert.equal(h.calls.length, 1) assert.equal(h.saved.length, 0) }) test("operator controls from a stale session cannot submit a mutation", async () => { const h = await harness("operator") h.setup(); h.switchSession(); await h.submit() assert.equal(h.calls.length, 0) }) test("read-only calendar or preview Enter cannot save even when form appears dirty", async () => { for (const writable of [false, true]) { const h = await harness("calendar", { writable }) h.setup(); await h.submit() assert.equal(h.calls.length, 0) } }) test("calendar confirmation cannot cross session or unmount boundaries", async () => { for (const action of ["session", "unmount"]) { const approval = deferred() const h = await harness("calendar", { editing: true, confirm: () => approval.promise }) const cleanup = h.setup() const submit = h.submit() if (action === "session") h.switchSession(); else cleanup() approval.resolve(true); await submit assert.equal(h.calls.length, 0) } }) test("calendar save completes after StrictMode restart and explicit confirmation", async () => { const h = await harness("calendar", { editing: true }) h.setup()(); h.setup(); await h.submit() assert.equal(h.calls.length, 1) assert.equal(h.saved.length, 1) })