Files
pleno-vue/tests/unit/pos-mobile-popup-renderer.spec.js
T

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)));"
);
});
});