194 lines
7.4 KiB
JavaScript
194 lines
7.4 KiB
JavaScript
// @vitest-environment jsdom
|
|
import { flushPromises } from "@vue/test-utils";
|
|
import { nextTick } from "vue";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { mountWithApp } from "./helpers/mountWithApp.js";
|
|
|
|
const mocks = vi.hoisted(() => {
|
|
const asMockRef = (value) => ({ value, __v_isRef: true });
|
|
|
|
return {
|
|
guestDepartments: asMockRef([]),
|
|
nearestDepartment: asMockRef(null),
|
|
fetchDepartments: vi.fn(async () => []),
|
|
evaluateLocationDepartments: vi.fn(),
|
|
orderDepartmentsByDistance: vi.fn((departments) => departments),
|
|
selectDepartment: vi.fn(),
|
|
useWashDepartments: vi.fn(),
|
|
locationRef: asMockRef({
|
|
coords: {
|
|
latitude: 55.5,
|
|
longitude: 12.4,
|
|
},
|
|
}),
|
|
getDistance: vi.fn(() => 3),
|
|
};
|
|
});
|
|
|
|
vi.mock("@/composables/useWashDepartments", () => ({
|
|
useWashDepartments: mocks.useWashDepartments,
|
|
}));
|
|
|
|
vi.mock("@/components/displays/department/pos/steps/mobile/objects/PosDepartmentStepMobileFlow.vue", () => ({
|
|
locations: {
|
|
location: mocks.locationRef,
|
|
normalizeCoordinatePair: (coordinates) => {
|
|
const latitude = Number(coordinates?.latitude);
|
|
const longitude = Number(coordinates?.longitude);
|
|
return Number.isFinite(latitude) && Number.isFinite(longitude) ? { latitude, longitude } : null;
|
|
},
|
|
hasValidCoordinatePair: (coordinates) => {
|
|
const latitude = Number(coordinates?.latitude);
|
|
const longitude = Number(coordinates?.longitude);
|
|
return Number.isFinite(latitude) && Number.isFinite(longitude);
|
|
},
|
|
getDistance: mocks.getDistance,
|
|
},
|
|
}));
|
|
|
|
import MyWash from "@/views/dashboards/userDashboard/wash/MyWash.vue";
|
|
|
|
const eligibleLane = { id: 10, name: "10", status: "AVAILABLE", selfserve_enabled: true };
|
|
|
|
const makeDepartment = (overrides = {}) => ({
|
|
id: 1,
|
|
name: "Glostrup",
|
|
address: "Fabriksparken 18",
|
|
latitude: 55.5,
|
|
longitude: 12.4,
|
|
distance: 1,
|
|
self_serve_enabled: true,
|
|
lanes: [eligibleLane],
|
|
...overrides,
|
|
});
|
|
|
|
const mountMyWash = async () => {
|
|
const wrapper = mountWithApp(MyWash, {
|
|
global: {
|
|
stubs: {
|
|
PosDepartmentStepMobile1Location: {
|
|
emits: ["location-updated"],
|
|
template: "<button data-testid='location-stub' @click=\"$emit('location-updated', {})\">location</button>",
|
|
},
|
|
BLoading: {
|
|
props: ["modelValue"],
|
|
template: "<div v-if='modelValue' data-testid='loading-stub' />",
|
|
},
|
|
BMessage: {
|
|
template: "<div class='b-message-stub' v-bind='$attrs'><slot /></div>",
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
await flushPromises();
|
|
await nextTick();
|
|
|
|
return wrapper;
|
|
};
|
|
|
|
describe("MyWash entry", () => {
|
|
beforeEach(() => {
|
|
mocks.guestDepartments.value = [];
|
|
mocks.nearestDepartment.value = null;
|
|
mocks.locationRef.value = {
|
|
coords: {
|
|
latitude: 55.5,
|
|
longitude: 12.4,
|
|
},
|
|
};
|
|
mocks.fetchDepartments.mockReset();
|
|
mocks.fetchDepartments.mockImplementation(async () => mocks.guestDepartments.value);
|
|
mocks.evaluateLocationDepartments.mockReset();
|
|
mocks.orderDepartmentsByDistance.mockReset();
|
|
mocks.orderDepartmentsByDistance.mockImplementation((departments) => departments);
|
|
mocks.selectDepartment.mockReset();
|
|
mocks.selectDepartment.mockImplementation((departmentId) => {
|
|
mocks.nearestDepartment.value =
|
|
mocks.guestDepartments.value.find((department) => department.id === departmentId) || null;
|
|
});
|
|
mocks.useWashDepartments.mockReset();
|
|
mocks.useWashDepartments.mockImplementation(() => ({
|
|
guestDepartments: mocks.guestDepartments,
|
|
nearestDepartment: mocks.nearestDepartment,
|
|
fetchDepartments: mocks.fetchDepartments,
|
|
evaluateLocationDepartments: mocks.evaluateLocationDepartments,
|
|
orderDepartmentsByDistance: mocks.orderDepartmentsByDistance,
|
|
selectDepartment: mocks.selectDepartment,
|
|
}));
|
|
mocks.getDistance.mockReset();
|
|
mocks.getDistance.mockReturnValue(3);
|
|
});
|
|
|
|
it("enables the start CTA when the nearest department is self-serve enabled with an available lane", async () => {
|
|
const nearest = makeDepartment();
|
|
mocks.guestDepartments.value = [nearest];
|
|
mocks.nearestDepartment.value = nearest;
|
|
|
|
const wrapper = await mountMyWash();
|
|
|
|
expect(mocks.useWashDepartments).toHaveBeenCalledWith({ includeLanes: true });
|
|
expect(wrapper.find('[data-testid="self-serve-home-start"]').exists()).toBe(true);
|
|
expect(wrapper.find('[data-testid="self-serve-home-start"]').attributes("href")).toBe("/user/wash/start");
|
|
expect(wrapper.find('[data-testid="self-serve-home-start-disabled"]').exists()).toBe(false);
|
|
expect(wrapper.find('[data-testid="self-serve-home-unavailable-message"]').exists()).toBe(false);
|
|
});
|
|
|
|
it("replaces the start CTA when the nearest department is disabled and lets users select another eligible department", async () => {
|
|
const nearest = makeDepartment({ self_serve_enabled: false });
|
|
const alternative = makeDepartment({ id: 2, name: "Roskilde", distance: 5 });
|
|
mocks.guestDepartments.value = [nearest, alternative];
|
|
mocks.nearestDepartment.value = nearest;
|
|
|
|
const wrapper = await mountMyWash();
|
|
|
|
expect(wrapper.find('[data-testid="self-serve-home-start"]').exists()).toBe(false);
|
|
expect(wrapper.find('[data-testid="self-serve-home-start-disabled"]').exists()).toBe(true);
|
|
expect(wrapper.find('[data-testid="self-serve-home-unavailable-message"]').text()).toContain(
|
|
"Glostrup er ikke aktiveret til selvvask lige nu."
|
|
);
|
|
|
|
await wrapper.find('[data-testid="self-serve-home-select-department-2"]').trigger("click");
|
|
await nextTick();
|
|
|
|
expect(mocks.selectDepartment).toHaveBeenCalledWith(2);
|
|
});
|
|
|
|
it("replaces the start CTA when the nearest department has no enabled and available lanes", async () => {
|
|
const nearest = makeDepartment({
|
|
lanes: [
|
|
{ id: 10, name: "10", status: "MAINTENANCE", selfserve_enabled: true },
|
|
{ id: 11, name: "11", status: "AVAILABLE", selfserve_enabled: false },
|
|
],
|
|
});
|
|
const alternative = makeDepartment({ id: 3, name: "Køge", distance: 7 });
|
|
mocks.guestDepartments.value = [nearest, alternative];
|
|
mocks.nearestDepartment.value = nearest;
|
|
|
|
const wrapper = await mountMyWash();
|
|
|
|
expect(wrapper.find('[data-testid="self-serve-home-start"]').exists()).toBe(false);
|
|
expect(wrapper.find('[data-testid="self-serve-home-start-disabled"]').exists()).toBe(true);
|
|
expect(wrapper.find('[data-testid="self-serve-home-unavailable-message"]').text()).toContain(
|
|
"Glostrup har ingen ledige selvvask-baner lige nu."
|
|
);
|
|
expect(wrapper.find('[data-testid="self-serve-home-select-department-3"]').exists()).toBe(true);
|
|
});
|
|
|
|
it("handles missing geolocation by disabling start and offering eligible departments", async () => {
|
|
const eligible = makeDepartment({ id: 4, name: "Odense" });
|
|
mocks.locationRef.value = null;
|
|
mocks.guestDepartments.value = [eligible];
|
|
mocks.nearestDepartment.value = null;
|
|
|
|
const wrapper = await mountMyWash();
|
|
|
|
expect(wrapper.find('[data-testid="self-serve-home-start"]').exists()).toBe(false);
|
|
expect(wrapper.find('[data-testid="self-serve-home-start-disabled"]').exists()).toBe(true);
|
|
expect(wrapper.find('[data-testid="self-serve-home-unavailable-message"]').text()).toContain(
|
|
"Vi kan ikke finde din nærmeste afdeling uden en placering."
|
|
);
|
|
expect(wrapper.find('[data-testid="self-serve-home-select-department-4"]').exists()).toBe(true);
|
|
});
|
|
});
|