Adds a snapshot test that locks the full {id, name, description} triple for every entry in SELF_SERVE_TASK_BUTTON_OPTIONS. The previous test only checked counts and that the ids were sequential; this test catches reordering, renames, and unexpected entries as well.
The wash bay exposes 12 programs and 3 special buttons (reset / program picker / start). The dashboard renders one entry per program number from this array, so the entire array must remain exactly 15 entries long.
Test result: 10/10 vitest passed (was 9, +1 new snapshot test)
Refs TRU-19
172 lines
7.8 KiB
JavaScript
172 lines
7.8 KiB
JavaScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
getSelfServeCompletedDynamicImageStep,
|
|
getSelfServeTaskDynamicImagePresentation,
|
|
isSelfServeProgramNumberButton,
|
|
normalizeSelfServeProgramPickerTaskButtons,
|
|
parseSelfServeDynamicImageThumbPosition,
|
|
} from "@/services/selfServeDynamicImage.js";
|
|
import {
|
|
SELF_SERVE_TASK_BUTTON_OPTIONS,
|
|
SELF_SERVE_TASK_BUTTON_PROGRAM_PICKER,
|
|
SELF_SERVE_TASK_BUTTON_RESET,
|
|
SELF_SERVE_TASK_BUTTON_START,
|
|
} from "@/components/session/token/SessionUser/Objects/selfServeTaskButtons.js";
|
|
|
|
describe("selfServeDynamicImage", () => {
|
|
it("uses a selected program picker button number as thumb position", () => {
|
|
const presentation = getSelfServeTaskDynamicImagePresentation({
|
|
buttons: ["program_picker", 0],
|
|
});
|
|
|
|
expect(presentation.buttons).toEqual(["program_picker"]);
|
|
expect(presentation.normalizedButtons).toEqual(["program_picker", 0]);
|
|
expect(presentation.thumbPosition).toBe(1);
|
|
});
|
|
|
|
it("prefers configured program wheel thumb position and keeps numeric machine buttons highlighted", () => {
|
|
const presentation = getSelfServeTaskDynamicImagePresentation({
|
|
services: ["PROGRAM_PICKER"],
|
|
buttons: [2, "start"],
|
|
dynamic_images_vehicle_type: 8,
|
|
});
|
|
|
|
expect(presentation.buttons).toEqual(["program_picker", 2, "start"]);
|
|
expect(presentation.normalizedButtons).toEqual([2, "start"]);
|
|
expect(presentation.thumbPosition).toBe(8);
|
|
});
|
|
|
|
it("drops the legacy numeric wheel selector while keeping other machine buttons highlighted", () => {
|
|
const presentation = getSelfServeTaskDynamicImagePresentation({
|
|
services: ["PROGRAM_PICKER"],
|
|
buttons: [3, 1, "start"],
|
|
dynamic_images_vehicle_type: 4,
|
|
});
|
|
|
|
expect(presentation.buttons).toEqual(["program_picker", 1, "start"]);
|
|
expect(presentation.normalizedButtons).toEqual([3, 1, "start"]);
|
|
expect(presentation.thumbPosition).toBe(4);
|
|
});
|
|
|
|
it("keeps numeric buttons highlighted outside program-picker mode", () => {
|
|
const presentation = getSelfServeTaskDynamicImagePresentation({
|
|
services: ["MACHINE"],
|
|
buttons: [2, "start"],
|
|
dynamic_images_vehicle_type: 8,
|
|
});
|
|
|
|
expect(presentation.buttons).toEqual([2, "start"]);
|
|
expect(presentation.thumbPosition).toBe(8);
|
|
});
|
|
|
|
it("excludes program-picker thumb selectors from completed step count", () => {
|
|
const tasks = [
|
|
{
|
|
id: 10,
|
|
services: ["PROGRAM_PICKER"],
|
|
buttons: [2, "start"],
|
|
},
|
|
];
|
|
|
|
expect(getSelfServeCompletedDynamicImageStep(tasks, { 10: true })).toBe(2);
|
|
});
|
|
|
|
it("keeps only one numbered program button in program-picker mode", () => {
|
|
expect(normalizeSelfServeProgramPickerTaskButtons(["program_picker", 1, 2, "start"], [], 2)).toEqual([
|
|
"program_picker",
|
|
2,
|
|
"start",
|
|
]);
|
|
});
|
|
|
|
// Smoke check that the program number range is stable across the codebase.
|
|
// The wash bay exposes 12 programs (buttons 0-11, thumb positions 1-12).
|
|
// If this assertion starts failing, the contract with the API has changed
|
|
// and any program mapping issue (e.g. a program that is unresponsive on
|
|
// the bay) is likely the API repository's concern, not the frontend.
|
|
it("accepts every configured program number between 0 and 11", () => {
|
|
for (let programNumber = 0; programNumber <= 11; programNumber += 1) {
|
|
expect(isSelfServeProgramNumberButton(programNumber)).toBe(true);
|
|
}
|
|
expect(isSelfServeProgramNumberButton(-1)).toBe(false);
|
|
expect(isSelfServeProgramNumberButton(12)).toBe(false);
|
|
expect(isSelfServeProgramNumberButton(100)).toBe(false);
|
|
});
|
|
|
|
it("maps 1-indexed thumb positions 1..12 to the documented program range", () => {
|
|
for (let thumbPosition = 1; thumbPosition <= 12; thumbPosition += 1) {
|
|
expect(parseSelfServeDynamicImageThumbPosition(thumbPosition)).toBe(thumbPosition);
|
|
}
|
|
expect(parseSelfServeDynamicImageThumbPosition(0)).toBeNull();
|
|
expect(parseSelfServeDynamicImageThumbPosition(13)).toBeNull();
|
|
expect(parseSelfServeDynamicImageThumbPosition("not-a-number")).toBeNull();
|
|
expect(parseSelfServeDynamicImageThumbPosition(null)).toBeNull();
|
|
expect(parseSelfServeDynamicImageThumbPosition(undefined)).toBeNull();
|
|
expect(parseSelfServeDynamicImageThumbPosition("")).toBeNull();
|
|
});
|
|
|
|
// Smoke check that the program button registry still covers every configured
|
|
// program. The wash bay exposes 12 programs and the path editor / simulator
|
|
// UI renders one entry per program number from this array. If the array is
|
|
// ever shortened, lengthened, or has gaps/duplicates, the program list shown
|
|
// to operators will drift from the API mapping and operators will not be
|
|
// able to reach every configured program — which is exactly the failure mode
|
|
// described in TRU-19 ("FF Uvs" and "10min" unresponsive).
|
|
it("exposes 12 unique, sequential program entries in the button registry", () => {
|
|
const numericProgramEntries = SELF_SERVE_TASK_BUTTON_OPTIONS.filter(
|
|
(entry) => Number.isInteger(entry?.id) && entry.id >= 0 && entry.id <= 11
|
|
);
|
|
|
|
expect(numericProgramEntries).toHaveLength(12);
|
|
expect(numericProgramEntries.map((entry) => entry.id)).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
|
|
expect(new Set(numericProgramEntries.map((entry) => entry.id)).size).toBe(12);
|
|
expect(new Set(numericProgramEntries.map((entry) => entry.name)).size).toBe(12);
|
|
|
|
// The three "special" buttons (reset / program picker / start) must still
|
|
// be present so the path editor can render the full UI.
|
|
const specialIds = new Set(SELF_SERVE_TASK_BUTTON_OPTIONS.map((entry) => entry?.id));
|
|
expect(specialIds.has(SELF_SERVE_TASK_BUTTON_RESET)).toBe(true);
|
|
expect(specialIds.has(SELF_SERVE_TASK_BUTTON_PROGRAM_PICKER)).toBe(true);
|
|
expect(specialIds.has(SELF_SERVE_TASK_BUTTON_START)).toBe(true);
|
|
});
|
|
|
|
// Snapshot lock for the full button-registry shape (TRU-19).
|
|
//
|
|
// The wash bay exposes 12 programs and 3 special buttons (reset / program
|
|
// picker / start). The dashboard renders one entry per program number
|
|
// from SELF_SERVE_TASK_BUTTON_OPTIONS, so the entire array must remain
|
|
// exactly 15 entries long: 1 reset + 1 program picker + 12 numeric
|
|
// programs (ids 0-11) + 1 start.
|
|
//
|
|
// If anyone adds, removes, or reorders entries without thinking about
|
|
// the operator UI and the api mapping, this snapshot will fail and
|
|
// force a deliberate update. The user-facing program names ("FF Uvs",
|
|
// "10min", "SF", etc.) live on the wash bay hardware and are NOT in
|
|
// this array — see TRU-19 and api SelfserveProgramRegistryContractTest.
|
|
it("locks the full SELF_SERVE_TASK_BUTTON_OPTIONS shape as a snapshot (15 entries, fixed order)", () => {
|
|
// Exact total length: 1 reset + 1 program picker + 12 programs + 1 start = 15
|
|
expect(SELF_SERVE_TASK_BUTTON_OPTIONS).toHaveLength(15);
|
|
|
|
// Full structural snapshot. The {id, name, description} triples must
|
|
// remain exactly as below. If you change one, change them all here
|
|
// deliberately.
|
|
expect(SELF_SERVE_TASK_BUTTON_OPTIONS.map((entry) => [entry.id, entry.name, entry.description])).toEqual([
|
|
[SELF_SERVE_TASK_BUTTON_RESET, "Reset", "Reset button"],
|
|
[SELF_SERVE_TASK_BUTTON_PROGRAM_PICKER, "Program picker", "Program picker wheel"],
|
|
[0, "Program 1", "Machine button 0"],
|
|
[1, "Program 2", "Machine button 1"],
|
|
[2, "Program 3", "Machine button 2"],
|
|
[3, "Program 4", "Machine button 3"],
|
|
[4, "Program 5", "Machine button 4"],
|
|
[5, "Program 6", "Machine button 5"],
|
|
[6, "Program 7", "Machine button 6"],
|
|
[7, "Program 8", "Machine button 7"],
|
|
[8, "Program 9", "Machine button 8"],
|
|
[9, "Program 10", "Machine button 9"],
|
|
[10, "Program 11", "Machine button 10"],
|
|
[11, "Program 12", "Machine button 11"],
|
|
[SELF_SERVE_TASK_BUTTON_START, "Start", "Start button"],
|
|
]);
|
|
});
|
|
});
|