142 lines
4.5 KiB
JavaScript
142 lines
4.5 KiB
JavaScript
// @vitest-environment jsdom
|
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { mountWithApp } from "./helpers/mountWithApp.js";
|
|
|
|
const popupStore = vi.hoisted(() => ({
|
|
popups: null,
|
|
}));
|
|
|
|
vi.mock("@/components/displays/department/pos/steps/mobile/objects/PosDepartmentStepMobileFlow.vue", async () => {
|
|
const { computed, ref } = await import("vue");
|
|
const activePopup = ref(null);
|
|
|
|
popupStore.popups = {
|
|
isSet: computed(() => activePopup.value !== null),
|
|
get: () => activePopup.value,
|
|
set: (popup) => {
|
|
activePopup.value = popup;
|
|
return popup;
|
|
},
|
|
clear: () => {
|
|
activePopup.value = null;
|
|
},
|
|
};
|
|
|
|
return {
|
|
popups: popupStore.popups,
|
|
};
|
|
});
|
|
|
|
vi.mock("@/components/displays/department/pos/steps/mobile/objects/PosPopup.vue", async () => {
|
|
const { defineComponent } = await import("vue");
|
|
|
|
return {
|
|
popupComponentKeyToComponent: () =>
|
|
defineComponent({
|
|
name: "PopupInnerStub",
|
|
template: '<div data-testid="popup-inner-component">Popup body</div>',
|
|
}),
|
|
};
|
|
});
|
|
|
|
import PosDepartmentStepMobilePopupRenderer from "@/components/displays/department/pos/steps/mobile/elements/PosDepartmentStepMobilePopupRenderer.vue";
|
|
import { popups } from "@/components/displays/department/pos/steps/mobile/objects/PosDepartmentStepMobileFlow.vue";
|
|
|
|
function buildPopup(overrides = {}) {
|
|
return {
|
|
id: "select_vehicle",
|
|
title: "Select vehicle",
|
|
component: "select_vehicle",
|
|
style: {
|
|
height: "50vh",
|
|
maxHeight: "60vh",
|
|
},
|
|
actionButtons: [
|
|
{
|
|
label: "Confirm",
|
|
color: "primary",
|
|
},
|
|
{
|
|
label: "Close",
|
|
color: "light",
|
|
},
|
|
],
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function mountRenderer() {
|
|
return mountWithApp(PosDepartmentStepMobilePopupRenderer, {
|
|
global: {
|
|
stubs: {
|
|
WhiteBoxCard: false,
|
|
UnknownCustomer: true,
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
describe("POS mobile popup renderer", () => {
|
|
beforeEach(() => {
|
|
popups.clear();
|
|
});
|
|
|
|
afterEach(() => {
|
|
popups.clear();
|
|
});
|
|
|
|
it("renders popup footer actions only when action buttons exist", () => {
|
|
popups.set(buildPopup());
|
|
const wrapper = mountRenderer();
|
|
|
|
expect(wrapper.get('[data-testid="pos-mobile-popup-footer"]').text()).toContain("Confirm");
|
|
expect(wrapper.get('[data-testid="pos-mobile-popup-footer"]').text()).toContain("Close");
|
|
expect(wrapper.find(".card-footer").exists()).toBe(true);
|
|
});
|
|
|
|
it("omits the footer entirely when the popup has no action buttons", () => {
|
|
popups.set(buildPopup({ actionButtons: [] }));
|
|
const wrapper = mountRenderer();
|
|
|
|
expect(wrapper.find('[data-testid="pos-mobile-popup-footer"]').exists()).toBe(false);
|
|
expect(wrapper.find(".card-footer").exists()).toBe(false);
|
|
});
|
|
|
|
it("keeps the footer separate from the scroll region and applies sizing only to the popup shell", () => {
|
|
popups.set(buildPopup());
|
|
const wrapper = mountRenderer();
|
|
|
|
const shell = wrapper.get('[data-testid="pos-mobile-popup-shell"]');
|
|
const scrollRegion = wrapper.get('[data-testid="pos-mobile-popup-scroll-region"]');
|
|
const footer = wrapper.get('[data-testid="pos-mobile-popup-footer"]');
|
|
const innerComponent = wrapper.get('[data-testid="popup-inner-component"]');
|
|
const contentContainer = scrollRegion.element.closest(".card-content");
|
|
const footerContainer = footer.element.closest(".card-footer");
|
|
|
|
expect(shell.attributes("style")).toContain(
|
|
"height: min(50vh, calc(100vh - var(--popup-top-clearance) - var(--popup-bottom-clearance)));"
|
|
);
|
|
expect(shell.attributes("style")).toContain(
|
|
"max-height: min(60vh, calc(100vh - var(--popup-top-clearance) - var(--popup-bottom-clearance)));"
|
|
);
|
|
expect(innerComponent.attributes("style")).toBeUndefined();
|
|
expect(contentContainer).not.toBeNull();
|
|
expect(footerContainer).not.toBeNull();
|
|
expect(contentContainer?.nextElementSibling).toBe(footerContainer);
|
|
});
|
|
|
|
it("converts max-height-only popups into a constrained shell height so the footer can anchor", () => {
|
|
popups.set(buildPopup({ style: { maxHeight: "72dvh" } }));
|
|
const wrapper = mountRenderer();
|
|
|
|
const shell = wrapper.get('[data-testid="pos-mobile-popup-shell"]');
|
|
|
|
expect(shell.attributes("style")).toContain(
|
|
"max-height: min(72dvh, calc(100vh - var(--popup-top-clearance) - var(--popup-bottom-clearance)));"
|
|
);
|
|
expect(shell.attributes("style")).toContain(
|
|
"height: min(72dvh, calc(100vh - var(--popup-top-clearance) - var(--popup-bottom-clearance)));"
|
|
);
|
|
});
|
|
});
|