Files
pleno-vue/tests/unit/use-wash-flow-state-production.spec.js
T

106 lines
4.1 KiB
JavaScript

import { describe, expect, it, vi } from "vitest";
import { ref } from "vue";
import { useWashFlowState, WASH_STEPS } from "@/composables/useWashFlowState.js";
function createFlow(overrides = {}) {
const state = {
currentStep: ref(WASH_STEPS.VEHICLE),
washInProgress: ref(false),
customerNumberInput: ref("12345679"),
licensePlateInput: ref("AB12345"),
vehicleTypeSelect: ref(2),
availableProductIds: ref([2]),
radioLaneOption: ref(7),
radioWashType: ref("Manual"),
nearestDepartment: ref({ lanes: [{ id: 7, status: "AVAILABLE", machine_available: true }] }),
allVisibleQuestionsAnswered: ref(true),
isLoadingSelfServeData: ref(false),
activeTasks: ref([]),
completedTasks: ref({}),
editAnswers: ref(true),
isLaneAvailable: vi.fn((lane) => lane.status === "AVAILABLE"),
isMachineAvailable: vi.fn(() => true),
onStartWash: vi.fn(async () => true),
updateLaneAllowedServices: vi.fn(async () => true),
...overrides,
};
return { state, flow: useWashFlowState(state) };
}
describe("useWashFlowState production transitions", () => {
it("gates vehicle, question, lane, task, in-progress, and completed transitions", async () => {
const { state, flow } = createFlow({ activeTasks: ref([{ id: 91 }]) });
state.vehicleTypeSelect.value = null;
expect(flow.clickableSteps[WASH_STEPS.VEHICLE]()).toBe(false);
expect(flow.isNextButtonDisabled()).toBe(true);
state.vehicleTypeSelect.value = 2;
expect(flow.clickableSteps[WASH_STEPS.VEHICLE]()).toBe(true);
expect(flow.clickableSteps[WASH_STEPS.QUESTIONS]()).toBe(true);
state.currentStep.value = WASH_STEPS.QUESTIONS;
state.allVisibleQuestionsAnswered.value = false;
expect(flow.isNextButtonDisabled()).toBe(true);
state.allVisibleQuestionsAnswered.value = true;
await flow.handleConfirmNext();
expect(state.editAnswers.value).toBe(false);
expect(state.currentStep.value).toBe(WASH_STEPS.SELECT_LANE);
expect(state.updateLaneAllowedServices).toHaveBeenCalledWith(7);
expect(flow.clickableSteps[WASH_STEPS.SELECT_LANE]()).toBe(true);
state.currentStep.value = WASH_STEPS.SELECT_LANE;
await flow.handleConfirmNext();
expect(state.onStartWash).toHaveBeenCalledWith(7, "AB12345", "12345679", WASH_STEPS.TASKS);
state.currentStep.value = WASH_STEPS.TASKS;
expect(flow.clickableSteps[WASH_STEPS.TASKS]()).toBe(true);
await flow.handleConfirmNext();
expect(state.currentStep.value).toBe(WASH_STEPS.WASH_IN_PROGRESS);
state.washInProgress.value = true;
expect(flow.clickableSteps[WASH_STEPS.WASH_IN_PROGRESS]()).toBe(true);
expect(flow.clickableSteps[WASH_STEPS.QUESTIONS]()).toBe(true);
expect(flow.clickableSteps[WASH_STEPS.TASKS]()).toBe(true);
expect(flow.clickableSteps[WASH_STEPS.COMPLETED]).toBeUndefined();
});
it("blocks lane confirmation for unavailable lanes and unavailable machine service", () => {
const { state, flow } = createFlow();
state.currentStep.value = WASH_STEPS.SELECT_LANE;
state.nearestDepartment.value.lanes[0].status = "OCCUPIED";
expect(flow.isNextButtonDisabled()).toBe(true);
state.nearestDepartment.value.lanes[0].status = "AVAILABLE";
state.radioWashType.value = "Machine";
state.isMachineAvailable.mockReturnValue(false);
expect(flow.isNextButtonDisabled()).toBe(true);
});
it("keeps lane confirmation enabled when the selected lane id is a string", async () => {
const { state, flow } = createFlow({ radioLaneOption: ref("7") });
state.currentStep.value = WASH_STEPS.SELECT_LANE;
expect(flow.isNextButtonDisabled()).toBe(false);
await flow.handleConfirmNext();
expect(state.onStartWash).toHaveBeenCalledWith(7, "AB12345", "12345679", WASH_STEPS.WASH_IN_PROGRESS);
});
it("stays on questions when lane allowed-service refresh fails", async () => {
const { state, flow } = createFlow({
updateLaneAllowedServices: vi.fn(async () => {
throw new Error("edge down");
}),
});
state.currentStep.value = WASH_STEPS.QUESTIONS;
await flow.handleConfirmNext();
expect(state.currentStep.value).toBe(WASH_STEPS.QUESTIONS);
});
});