Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
131 lines
4.1 KiB
TypeScript
131 lines
4.1 KiB
TypeScript
/**
|
|
* Activation checklist unit tests (node:test).
|
|
* Plan-gated optional store-connect + workspace cursor (no $lib / i18n).
|
|
*
|
|
* Run from apps/web:
|
|
* node --experimental-strip-types --test src/lib/activation.test.ts
|
|
*/
|
|
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
|
|
import {
|
|
activationIndexFromWorkspace,
|
|
visibleActivationSteps,
|
|
type ActivationStepRef
|
|
} from "./activation/workspace.ts";
|
|
|
|
const FULL_STEPS: ActivationStepRef[] = [
|
|
{ id: "enable-fields" },
|
|
{ id: "connect-source" },
|
|
{ id: "map" },
|
|
{ id: "sync-sample" },
|
|
{ id: "process" },
|
|
{ id: "store-connect", optional: true, feature: "stores.hub" },
|
|
{ id: "export" }
|
|
];
|
|
|
|
describe("visibleActivationSteps", () => {
|
|
it("includes store-connect when stores.hub is allowed", () => {
|
|
const steps = visibleActivationSteps(FULL_STEPS, () => true);
|
|
assert.ok(steps.some((s) => s.id === "store-connect"));
|
|
assert.equal(steps.find((s) => s.id === "store-connect")?.optional, true);
|
|
assert.equal(steps.find((s) => s.id === "store-connect")?.feature, "stores.hub");
|
|
});
|
|
|
|
it("hides store-connect when stores.hub is denied (A1-safe)", () => {
|
|
const steps = visibleActivationSteps(FULL_STEPS, (key) => key !== "stores.hub");
|
|
assert.equal(
|
|
steps.some((s) => s.id === "store-connect"),
|
|
false
|
|
);
|
|
assert.deepEqual(
|
|
steps.map((s) => s.id),
|
|
["enable-fields", "connect-source", "map", "sync-sample", "process", "export"]
|
|
);
|
|
});
|
|
|
|
it("places store-connect after process and before export", () => {
|
|
const ids = FULL_STEPS.map((s) => s.id);
|
|
assert.equal(ids.indexOf("store-connect"), ids.indexOf("process") + 1);
|
|
assert.equal(ids.indexOf("export"), ids.indexOf("store-connect") + 1);
|
|
});
|
|
});
|
|
|
|
describe("activationIndexFromWorkspace", () => {
|
|
const throughProcess = {
|
|
hasEnabledFields: true,
|
|
hasSource: true,
|
|
hasMapping: true,
|
|
hasSyncedSample: true,
|
|
hasProcessed: true
|
|
};
|
|
|
|
it("stops on optional store-connect when no store and no later required evidence", () => {
|
|
const steps = visibleActivationSteps(FULL_STEPS, () => true);
|
|
const count = activationIndexFromWorkspace(throughProcess, steps);
|
|
assert.equal(count, steps.findIndex((s) => s.id === "store-connect"));
|
|
});
|
|
|
|
it("does not block export when optional store is incomplete", () => {
|
|
const steps = visibleActivationSteps(FULL_STEPS, () => true);
|
|
const count = activationIndexFromWorkspace(
|
|
{ ...throughProcess, hasExport: true },
|
|
steps
|
|
);
|
|
assert.equal(count, steps.findIndex((s) => s.id === "export") + 1);
|
|
});
|
|
|
|
it("advances past store-connect when a store is connected", () => {
|
|
const steps = visibleActivationSteps(FULL_STEPS, () => true);
|
|
const count = activationIndexFromWorkspace(
|
|
{ ...throughProcess, hasStoreConnect: true },
|
|
steps
|
|
);
|
|
assert.equal(count, steps.findIndex((s) => s.id === "export"));
|
|
});
|
|
|
|
it("skips store evidence when step is gated out", () => {
|
|
const steps = visibleActivationSteps(FULL_STEPS, (key) => key !== "stores.hub");
|
|
const count = activationIndexFromWorkspace(
|
|
{ ...throughProcess, hasExport: true },
|
|
steps
|
|
);
|
|
assert.equal(count, steps.length);
|
|
});
|
|
});
|
|
|
|
|
|
describe("activation Continue destinations", () => {
|
|
/** Mirror of ACTIVATION_STEP_DEFS hrefs — keep in sync with activation/steps.ts. */
|
|
const CONTINUE_HREFS: Record<string, string> = {
|
|
"enable-fields": "/standard-fields",
|
|
"connect-source": "/feeds?add=1",
|
|
map: "/feeds?focus=map",
|
|
"sync-sample": "/feeds?focus=sync",
|
|
process: "/products?type=raw&status=unprocessed",
|
|
"store-connect": "/stores/wizard",
|
|
export: "/export-feeds"
|
|
};
|
|
|
|
it("keeps feed-first connect-source away from the stores wizard", () => {
|
|
assert.match(CONTINUE_HREFS["connect-source"], /^\/feeds/);
|
|
assert.doesNotMatch(CONTINUE_HREFS["connect-source"], /stores/);
|
|
assert.equal(CONTINUE_HREFS["store-connect"], "/stores/wizard");
|
|
});
|
|
|
|
it("matches the checklist sequence destinations", () => {
|
|
assert.deepEqual(
|
|
FULL_STEPS.map((s) => CONTINUE_HREFS[s.id]),
|
|
[
|
|
"/standard-fields",
|
|
"/feeds?add=1",
|
|
"/feeds?focus=map",
|
|
"/feeds?focus=sync",
|
|
"/products?type=raw&status=unprocessed",
|
|
"/stores/wizard",
|
|
"/export-feeds"
|
|
]
|
|
);
|
|
});
|
|
});
|