Files
pleno-vue/tests/unit/reference-autocomplete-pos.spec.js
T

192 lines
5.4 KiB
JavaScript

// @vitest-environment jsdom
import { beforeEach, describe, expect, it, vi } from "vitest";
import { mountWithApp } from "./helpers/mountWithApp.js";
import ReferenceAutocompletePOS from "@/components/forms/department/pos/input/ReferenceAutocompletePOS.vue";
const requestState = vi.hoisted(() => ({
authenticatedRequest: vi.fn(),
}));
vi.mock("@/components/session/authenticatedRequest.vue", () => ({
authenticatedRequest: requestState.authenticatedRequest,
}));
const flushPromises = async () => {
await Promise.resolve();
await Promise.resolve();
};
function mountAutocomplete(props = {}) {
return mountWithApp(ReferenceAutocompletePOS, {
props: {
modelValue: "",
departmentId: 12,
customerId: 12345679,
reg1: "EC21235",
debounceMs: 0,
...props,
},
});
}
describe("ReferenceAutocompletePOS", () => {
beforeEach(() => {
requestState.authenticatedRequest.mockReset();
requestState.authenticatedRequest.mockResolvedValue({ data: { data: [] } });
});
it("fetches async suggestions with the current POS context", async () => {
requestState.authenticatedRequest.mockResolvedValue({
data: {
data: [
{
source: "booking",
section: "this_vehicle",
reference: "REF-BOOKING",
source_created_at: "2026-05-13 09:00:00",
last_used_at: "2026-05-13 09:00:00",
usage_count: 1,
origin_id: 7001,
score: 100,
},
],
},
});
const wrapper = mountAutocomplete();
await wrapper.find("input").trigger("focus");
await wrapper.find("input").setValue("REF");
await flushPromises();
expect(requestState.authenticatedRequest).toHaveBeenLastCalledWith(
"/orders/reference-suggestions",
"GET",
expect.objectContaining({
search: "REF",
department_id: 12,
customer_id: 12345679,
reg_1: "EC21235",
limit: 10,
})
);
});
it("keeps stale suggestion responses from replacing newer results", async () => {
let resolveFirst;
let resolveSecond;
requestState.authenticatedRequest
.mockReturnValueOnce(
new Promise((resolve) => {
resolveFirst = resolve;
})
)
.mockReturnValueOnce(
new Promise((resolve) => {
resolveSecond = resolve;
})
);
const wrapper = mountAutocomplete();
await wrapper.find("input").setValue("A");
await wrapper.find("input").setValue("AB");
resolveSecond({
data: {
data: [
{
source: "order",
section: "this_vehicle",
reference: "AB-NEW",
usage_count: 2,
origin_id: 2,
score: 200,
},
],
},
});
await flushPromises();
resolveFirst({
data: {
data: [
{
source: "vehicle",
section: "other_customer_vehicle",
reference: "A-STALE",
usage_count: 1,
origin_id: 1,
score: 10,
},
],
},
});
await flushPromises();
expect(wrapper.text()).toContain("AB-NEW");
expect(wrapper.text()).not.toContain("A-STALE");
});
it("renders source metadata and emits the selected suggestion", async () => {
requestState.authenticatedRequest.mockResolvedValue({
data: {
data: [
{
source: "booking",
section: "this_vehicle",
reference: "REF-BOOKING",
source_created_at: "2026-05-13 09:00:00",
last_used_at: "2026-05-14 10:30:00",
usage_count: 3,
origin_id: 7001,
score: 500,
},
{
source: "vehicle",
section: "other_customer_vehicle",
reference: "REF-OTHER-VEHICLE",
source_created_at: "2026-05-08 12:00:00",
last_used_at: "2026-05-08 12:00:00",
usage_count: 1,
origin_id: 7002,
score: 450,
},
],
},
});
const wrapper = mountAutocomplete();
await wrapper.find("input").trigger("focus");
await wrapper.find("input").setValue("REF");
await flushPromises();
expect(wrapper.get('[data-testid="pos-reference-section-this_vehicle"]').text()).toBe("This vehicle");
expect(wrapper.get('[data-testid="pos-reference-section-other_customer_vehicle"]').text()).toBe(
"Other vehicles, this customer"
);
const option = wrapper.get('[data-testid="pos-reference-option-booking-7001"]');
expect(option.text()).toContain("REF-BOOKING");
expect(option.text()).toContain("Booking date");
expect(option.text()).toContain("Last used");
expect(option.text()).toContain("3x used");
expect(wrapper.get('[data-testid="pos-reference-option-vehicle-7002"]').text()).toContain("REF-OTHER-VEHICLE");
await option.trigger("click");
expect(wrapper.emitted("select")?.[0]?.[0]).toMatchObject({
source: "booking",
reference: "REF-BOOKING",
usage_count: 3,
origin_id: 7001,
});
expect(wrapper.emitted("update:modelValue")?.at(-1)?.[0]).toBe("REF-BOOKING");
});
it("marks the actual input as invalid for required-reference warnings", async () => {
const wrapper = mountAutocomplete({ requiredWarning: true });
await flushPromises();
expect(wrapper.get("#reference").attributes("aria-invalid")).toBe("true");
});
});