Files
pleno-vue/tests/unit/select-vehicle-form-pos.spec.js
T

336 lines
10 KiB
JavaScript

// @vitest-environment jsdom
import { nextTick, ref } from "vue";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { mountWithApp } from "./helpers/mountWithApp.js";
const posState = vi.hoisted(() => ({
customerId: null,
notes: null,
customerName: null,
reference: null,
reg1: null,
reg2: null,
reg3: null,
customerAttributes: null,
orderNotes: null,
orderPo: null,
orderId: null,
selectedOrderBookingId: null,
selectedOrderBookingPlate: null,
searchAndSelectCustomer: vi.fn(),
selectCustomer: vi.fn(),
setSelectedOrderBookingSelection: vi.fn(),
clearSelectedOrderBookingSelection: vi.fn(),
skipSelectedOrderBookingSelection: vi.fn(),
isSelectedOrderBookingSkippedForPlate: vi.fn(() => false),
doesVehiclePlateRequireBookingSelection: vi.fn(() => false),
getSelectedVehiclePlateBooking: vi.fn(() => null),
loadPendingBookings: vi.fn(async () => []),
ensureVehiclePlateBookingsLoaded: vi.fn(async () => []),
getCurrentStep: vi.fn(() => 1),
}));
vi.mock("@/components/shop/POSDepartmentProcess.vue", async () => {
posState.customerId = ref(null);
posState.notes = ref([]);
posState.customerName = ref("");
posState.reference = ref("");
posState.reg1 = ref("AB12345");
posState.reg2 = ref("");
posState.reg3 = ref("");
posState.customerAttributes = ref([]);
posState.orderNotes = ref("");
posState.orderPo = ref("");
posState.orderId = ref(null);
posState.selectedOrderBookingId = ref(null);
posState.selectedOrderBookingPlate = ref("");
posState.selectCustomer.mockImplementation((customer) => {
posState.customerId.value = customer?.customerNumber ?? null;
posState.customerName.value = customer?.name ?? "";
});
return {
customer_id: posState.customerId,
notes: posState.notes,
isCustomerBarred: vi.fn(() => false),
customer_name: posState.customerName,
reference: posState.reference,
reg_1: posState.reg1,
reg_2: posState.reg2,
reg_3: posState.reg3,
order_notes: posState.orderNotes,
order_po: posState.orderPo,
order_id: posState.orderId,
searchAndSelectCustomer: posState.searchAndSelectCustomer,
selectCustomer: posState.selectCustomer,
isCustomerSelected: () => Boolean(posState.customerId.value),
customer_attributes: posState.customerAttributes,
selectedOrderBookingId: posState.selectedOrderBookingId,
selectedOrderBookingPlate: posState.selectedOrderBookingPlate,
setSelectedOrderBookingSelection: posState.setSelectedOrderBookingSelection,
clearSelectedOrderBookingSelection: posState.clearSelectedOrderBookingSelection,
skipSelectedOrderBookingSelection: posState.skipSelectedOrderBookingSelection,
isSelectedOrderBookingSkippedForPlate: posState.isSelectedOrderBookingSkippedForPlate,
doesVehiclePlateRequireBookingSelection: posState.doesVehiclePlateRequireBookingSelection,
getSelectedVehiclePlateBooking: posState.getSelectedVehiclePlateBooking,
loadPendingBookings: posState.loadPendingBookings,
ensureVehiclePlateBookingsLoaded: posState.ensureVehiclePlateBookingsLoaded,
getCurrentStep: posState.getCurrentStep,
};
});
vi.mock("@/components/session/token/SessionUser.vue", () => ({
SessionUser: {
adminUser: false,
objects: {
orders: {
columns: {
reg_1: { label: "Nummerplade" },
reg_2: { label: "Reg. 2" },
reg_3: { label: "Reg. 3" },
reference: { label: "Reference" },
},
},
global: {
language: {
customer: "Kunde",
select: "Vælg",
other: "Andet",
no_data: "Ingen data",
last_wash: "Sidste vask",
copy: "Kopier",
have: "Har",
have_not: "Har ikke",
quantity: "Antal",
show: "Vis",
hide: "Skjul",
},
},
vehicles: {
meta: {
labels: {
single: "Køretøj",
},
},
columns: {
wash_subscription: {
label: "Vaskeabonnement",
},
},
},
products: {
meta: {
labels: {
single: "Produkt",
},
},
functions: {
getProductName: vi.fn(() => "Forvogn"),
},
},
},
},
}));
import SelectVehicleFormPOS from "@/components/forms/department/pos/SelectVehicleFormPOS.vue";
const linkedVehicle = {
id: 7002,
reg: "EC21235",
customer_id: 12345679,
type: 53,
wash_subscription: false,
addons: { list: [] },
last_order_id: null,
};
const unlinkedVehicle = {
id: 7001,
reg: "AB12345",
customer_id: null,
type: 53,
wash_subscription: false,
addons: { list: [] },
last_order_id: null,
};
const LicensePlateReg1InputStub = {
name: "LicensePlateReg1Input",
emits: ["update:vehicleObject", "update:focus", "update:bookingObject", "update:bookingMatches"],
methods: {
emitUnlinkedVehicle() {
this.$emit("update:vehicleObject", { ...unlinkedVehicle });
},
emitLinkedVehicle() {
this.$emit("update:vehicleObject", { ...linkedVehicle });
},
},
template: `
<div>
<button
type="button"
data-testid="emit-unlinked-vehicle"
@click="emitUnlinkedVehicle"
>
Emit unlinked vehicle
</button>
<button
type="button"
data-testid="emit-linked-vehicle"
@click="emitLinkedVehicle"
>
Emit linked vehicle
</button>
</div>
`,
};
const ExpandableContentBoxStub = {
name: "ExpandableContentBox",
props: {
expanded: {
type: Boolean,
default: false,
},
},
emits: ["update:expanded"],
template: `
<div data-testid="expandable-content-box-stub">
<slot v-if="expanded" name="expandedContent" />
<button
type="button"
data-testid="expandable-toggle"
@click="$emit('update:expanded', !expanded)"
>
Toggle
</button>
</div>
`,
};
const CustomerSearchFieldPosStub = {
name: "CustomerSearchFieldPos",
props: {
showCardPaymentButton: {
type: Boolean,
default: true,
},
},
template: `
<div data-testid="customer-search-field-pos-stub">
<button
type="button"
data-testid="customer-search-new-customer-stub"
>
Ny kunde
</button>
<button
v-if="showCardPaymentButton"
type="button"
data-testid="customer-search-card-payment-stub"
>
Vælg direkte betaling med betalingskort
</button>
</div>
`,
};
const SimpleStub = {
template: "<div />",
};
function mountForm() {
return mountWithApp(SelectVehicleFormPOS, {
global: {
stubs: {
CustomerSearchFieldPos: CustomerSearchFieldPosStub,
customerSearchFieldPos: CustomerSearchFieldPosStub,
ExpandableContentBox: ExpandableContentBoxStub,
LicensePlateReg1Input: LicensePlateReg1InputStub,
LicensePlateInput: SimpleStub,
PosNotes: SimpleStub,
OrderContentTable: SimpleStub,
OrderItemsTable: SimpleStub,
VehicleCustomerSuggestionsPos: SimpleStub,
DefaultObjectSelector: SimpleStub,
},
},
});
}
describe("SelectVehicleFormPOS", () => {
beforeEach(() => {
posState.customerId.value = null;
posState.notes.value = [];
posState.customerName.value = "";
posState.reference.value = "";
posState.reg1.value = "AB12345";
posState.reg2.value = "";
posState.reg3.value = "";
posState.customerAttributes.value = [];
posState.orderNotes.value = "";
posState.orderPo.value = "";
posState.orderId.value = null;
posState.selectedOrderBookingId.value = null;
posState.selectedOrderBookingPlate.value = "";
posState.searchAndSelectCustomer.mockClear();
posState.selectCustomer.mockClear();
posState.setSelectedOrderBookingSelection.mockClear();
posState.clearSelectedOrderBookingSelection.mockClear();
posState.skipSelectedOrderBookingSelection.mockClear();
posState.isSelectedOrderBookingSkippedForPlate.mockReset();
posState.isSelectedOrderBookingSkippedForPlate.mockReturnValue(false);
posState.doesVehiclePlateRequireBookingSelection.mockReset();
posState.doesVehiclePlateRequireBookingSelection.mockReturnValue(false);
posState.getSelectedVehiclePlateBooking.mockReset();
posState.getSelectedVehiclePlateBooking.mockReturnValue(null);
posState.loadPendingBookings.mockClear();
posState.ensureVehiclePlateBookingsLoaded.mockReset();
posState.ensureVehiclePlateBookingsLoaded.mockResolvedValue([]);
});
it("shows a single inline customer selector before a vehicle is linked", () => {
const wrapper = mountForm();
expect(wrapper.findAll('[data-testid="customer-search-field-pos-stub"]')).toHaveLength(1);
expect(wrapper.findAll('[data-testid="customer-search-new-customer-stub"]')).toHaveLength(1);
expect(wrapper.findAll('[data-testid="customer-search-card-payment-stub"]')).toHaveLength(1);
expect(wrapper.find('[data-testid="expandable-content-box-stub"]').exists()).toBe(false);
});
it("keeps a single inline customer selector when an unlinked vehicle card is expanded", async () => {
const wrapper = mountForm();
await wrapper.get('[data-testid="emit-unlinked-vehicle"]').trigger("click");
await nextTick();
expect(wrapper.findAll('[data-testid="customer-search-field-pos-stub"]')).toHaveLength(1);
expect(wrapper.findAll('[data-testid="customer-search-new-customer-stub"]')).toHaveLength(1);
expect(wrapper.find('[data-testid="expandable-content-box-stub"]').exists()).toBe(true);
await wrapper.get('[data-testid="expandable-toggle"]').trigger("click");
await nextTick();
expect(wrapper.findAll('[data-testid="customer-search-field-pos-stub"]')).toHaveLength(1);
expect(wrapper.findAll('[data-testid="customer-search-new-customer-stub"]')).toHaveLength(1);
expect(wrapper.findAll('[data-testid="customer-search-card-payment-stub"]')).toHaveLength(1);
});
it("moves customer selection into the expanded other section for linked vehicles", async () => {
const wrapper = mountForm();
await wrapper.get('[data-testid="emit-linked-vehicle"]').trigger("click");
await nextTick();
expect(wrapper.findAll('[data-testid="customer-search-field-pos-stub"]')).toHaveLength(0);
await wrapper.get('[data-testid="expandable-toggle"]').trigger("click");
await nextTick();
expect(wrapper.findAll('[data-testid="customer-search-field-pos-stub"]')).toHaveLength(1);
expect(wrapper.findAll('[data-testid="customer-search-new-customer-stub"]')).toHaveLength(1);
expect(wrapper.findAll('[data-testid="customer-search-card-payment-stub"]')).toHaveLength(1);
});
});