Enhance self-serve functionality with dynamic images, gate handling, and machine-scoped vehicle type filtering:

- Added dynamic image previews with query parameter handling and error recovery in `SelfServeTryModal.vue`.
- Introduced outside gate controls (`Entrance` and `Exit`) in `SelfServeMachineRelayControls.vue` with corresponding command handling logic.
- Enhanced vehicle type scoping logic in `SelfServeTasksPagination.vue` and `SelfServeConditionsPagination.vue` to ensure machine-type filtering consistency.
- Updated related unit tests to verify new dynamic image logic, gate controls, and scoping behaviors.
This commit is contained in:
Jeppe Bundgaard
2026-03-26 14:13:15 +01:00
parent 3e84421913
commit d354ce7737
12 changed files with 318 additions and 9 deletions
+81
View File
@@ -108,6 +108,7 @@ describe("SelfServeTryModal", () => {
mocks.questions.value = [];
mocks.visibleQuestions.value = [];
mocks.answers.value = {};
mocks.activeTasks.value = [];
mocks.currentQuestion.value = null;
mocks.evaluateCondition.mockReturnValue(true);
});
@@ -186,6 +187,86 @@ describe("SelfServeTryModal", () => {
});
});
it("renders dynamic image preview with expected query parameters when context exists", async () => {
mocks.activeTasks.value = [
{
id: 1,
buttons: [0, 2, 2, -1, 99],
dynamic_images_vehicle_type: 5,
},
];
const wrapper = mountWithApp(SelfServeTryModal, {
props: {
departmentId: 9,
laneId: 3,
vehicleTypeId: 3,
},
global: {
stubs: {
SelfServeQuestionCards: true,
SelfServeTaskList: true,
},
},
});
await flushPromises();
const image = wrapper.get('[data-testid="self-serve-try-dynamic-image"]');
const imageUrl = new URL(image.attributes("src"));
expect(imageUrl.pathname).toBe("/department/lanes/dynamic-image");
expect(imageUrl.searchParams.get("department")).toBe("9");
expect(imageUrl.searchParams.get("lane")).toBe("3");
expect(imageUrl.searchParams.get("current_step")).toBe("0");
expect(imageUrl.searchParams.get("vehicle_type")).toBe("3");
expect(imageUrl.searchParams.get("thumb_position")).toBe("5");
expect(JSON.parse(imageUrl.searchParams.get("buttons"))).toEqual([0, 2]);
});
it("does not render dynamic image preview without dynamic-image context", async () => {
mocks.activeTasks.value = [
{
id: 1,
buttons: [-1, 12, 99],
dynamic_images_vehicle_type: null,
},
];
const wrapper = mountModal();
await flushPromises();
expect(wrapper.find('[data-testid="self-serve-try-dynamic-image"]').exists()).toBe(false);
});
it("hides dynamic image on error and restores it when image context changes", async () => {
mocks.activeTasks.value = [
{
id: 1,
buttons: [1],
dynamic_images_vehicle_type: null,
},
];
const wrapper = mountModal();
await flushPromises();
await wrapper.get('[data-testid="self-serve-try-dynamic-image"]').trigger("error");
await flushPromises();
expect(wrapper.find('[data-testid="self-serve-try-dynamic-image"]').exists()).toBe(false);
await wrapper.get('[data-testid="self-serve-try-vehicle-type"]').setValue("3");
await flushPromises();
const image = wrapper.get('[data-testid="self-serve-try-dynamic-image"]');
const imageUrl = new URL(image.attributes("src"));
expect(imageUrl.searchParams.get("vehicle_type")).toBe("3");
expect(JSON.parse(imageUrl.searchParams.get("buttons"))).toEqual([1]);
});
it("does not duplicate the current question in the question cards list", async () => {
mocks.currentQuestion.value = { id: 11, question: "Question 11" };
mocks.visibleQuestions.value = [