mirror of
https://github.com/photoprism/photoprism.git
synced 2026-01-23 02:24:24 +00:00
Tests: Enhance Vitest setup and add PLightbox component tests
This commit is contained in:
parent
a8f4286100
commit
97200c951e
2 changed files with 141 additions and 1 deletions
102
frontend/tests/vitest/component/lightbox.basic.test.js
Normal file
102
frontend/tests/vitest/component/lightbox.basic.test.js
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
import { mount, config as VTUConfig } from "@vue/test-utils";
|
||||
import { describe, it, expect, beforeEach } from "vitest";
|
||||
import { nextTick } from "vue";
|
||||
import PLightbox from "component/lightbox.vue";
|
||||
|
||||
const mountLightbox = () =>
|
||||
mount(PLightbox, {
|
||||
global: {
|
||||
stubs: {
|
||||
"v-dialog": true,
|
||||
"v-icon": true,
|
||||
"v-slider": true,
|
||||
"p-lightbox-menu": true,
|
||||
"p-sidebar-info": true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
describe("PLightbox (low-mock, jsdom-friendly)", () => {
|
||||
beforeEach(() => {
|
||||
localStorage.removeItem("lightbox.info");
|
||||
sessionStorage.removeItem("lightbox.muted");
|
||||
});
|
||||
|
||||
it("toggleInfo updates info and localStorage when visible", async () => {
|
||||
const wrapper = mountLightbox();
|
||||
await wrapper.setData({ visible: true });
|
||||
|
||||
// Use exposed onShortCut to trigger info toggle (KeyI)
|
||||
await wrapper.vm.onShortCut({ code: "KeyI" });
|
||||
await nextTick();
|
||||
expect(localStorage.getItem("lightbox.info")).toBe("true");
|
||||
|
||||
await wrapper.vm.onShortCut({ code: "KeyI" });
|
||||
await nextTick();
|
||||
expect(localStorage.getItem("lightbox.info")).toBe("false");
|
||||
});
|
||||
|
||||
it("toggleMute writes sessionStorage without requiring video or exposed state", async () => {
|
||||
const wrapper = mountLightbox();
|
||||
expect(sessionStorage.getItem("lightbox.muted")).toBeNull();
|
||||
await wrapper.vm.onShortCut({ code: "KeyM" });
|
||||
expect(sessionStorage.getItem("lightbox.muted")).toBe("true");
|
||||
await wrapper.vm.onShortCut({ code: "KeyM" });
|
||||
expect(sessionStorage.getItem("lightbox.muted")).toBe("false");
|
||||
});
|
||||
|
||||
it("getPadding returns expected structure for large and small screens", async () => {
|
||||
const wrapper = mountLightbox();
|
||||
// Large viewport
|
||||
const large = wrapper.vm.$options.methods.getPadding.call(
|
||||
wrapper.vm,
|
||||
{ x: 1200, y: 800 },
|
||||
{ width: 4000, height: 3000 }
|
||||
);
|
||||
expect(large).toHaveProperty("top");
|
||||
expect(large).toHaveProperty("bottom");
|
||||
expect(large).toHaveProperty("left");
|
||||
expect(large).toHaveProperty("right");
|
||||
|
||||
// Small viewport (<= mobileBreakpoint) should yield zeros
|
||||
const small = wrapper.vm.$options.methods.getPadding.call(
|
||||
wrapper.vm,
|
||||
{ x: 360, y: 640 },
|
||||
{ width: 1200, height: 800 }
|
||||
);
|
||||
expect(small).toEqual({ top: 0, bottom: 0, left: 0, right: 0 });
|
||||
});
|
||||
|
||||
it("KeyI is ignored when dialog is not visible", async () => {
|
||||
const wrapper = mountLightbox();
|
||||
expect(localStorage.getItem("lightbox.info")).toBeNull();
|
||||
await wrapper.vm.onShortCut({ code: "KeyI" });
|
||||
expect(localStorage.getItem("lightbox.info")).toBeNull();
|
||||
});
|
||||
|
||||
it("getViewport falls back to window size without content ref", () => {
|
||||
const wrapper = mountLightbox();
|
||||
const vp = wrapper.vm.$options.methods.getViewport.call(wrapper.vm);
|
||||
expect(vp.x).toBeGreaterThan(0);
|
||||
expect(vp.y).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("menuActions marks Download action visible when allowed", () => {
|
||||
const wrapper = mountLightbox();
|
||||
const ctx = {
|
||||
$gettext: VTUConfig.global.mocks.$gettext,
|
||||
$pgettext: VTUConfig.global.mocks.$pgettext,
|
||||
// minimal state needed by menuActions visibility checks
|
||||
canManageAlbums: false,
|
||||
canArchive: false,
|
||||
canDownload: true,
|
||||
collection: null,
|
||||
context: "",
|
||||
model: {},
|
||||
};
|
||||
const actions = wrapper.vm.$options.methods.menuActions.call(ctx);
|
||||
const download = actions.find((a) => a?.name === "download");
|
||||
expect(download).toBeTruthy();
|
||||
expect(download.visible).toBe(true);
|
||||
});
|
||||
});
|
||||
|
|
@ -26,10 +26,48 @@ const vuetify = createVuetify({
|
|||
// Configure Vue Test Utils global configuration
|
||||
config.global.mocks = {
|
||||
$gettext: (text) => text,
|
||||
$pgettext: (_ctx, text) => text,
|
||||
$isRtl: false,
|
||||
$config: {
|
||||
feature: (_name) => true,
|
||||
feature: () => true,
|
||||
get: () => false,
|
||||
getSettings: () => ({ features: { edit: true, favorites: true, download: true, archive: true } }),
|
||||
allow: () => true,
|
||||
featExperimental: () => false,
|
||||
featDevelop: () => false,
|
||||
values: {},
|
||||
dir: () => "ltr",
|
||||
},
|
||||
$event: {
|
||||
subscribe: () => "sub-id",
|
||||
subscribeOnce: () => "sub-id-once",
|
||||
unsubscribe: () => {},
|
||||
publish: () => {},
|
||||
},
|
||||
$view: {
|
||||
enter: () => {},
|
||||
leave: () => {},
|
||||
isActive: () => true,
|
||||
},
|
||||
$notify: { success: () => {}, error: () => {}, warn: () => {} },
|
||||
$fullscreen: {
|
||||
isSupported: () => true,
|
||||
isEnabled: () => false,
|
||||
request: () => Promise.resolve(),
|
||||
exit: () => Promise.resolve(),
|
||||
},
|
||||
$clipboard: { selection: [], has: () => false, toggle: () => {} },
|
||||
$util: {
|
||||
hasTouch: () => false,
|
||||
encodeHTML: (s) => s,
|
||||
sanitizeHtml: (s) => s,
|
||||
formatSeconds: (n) => String(n),
|
||||
formatRemainingSeconds: () => "0",
|
||||
videoFormat: () => "avc",
|
||||
videoFormatUrl: () => "/v.mp4",
|
||||
thumb: () => ({ src: "/t.jpg", w: 100, h: 100 }),
|
||||
},
|
||||
$api: { post: vi.fn(), delete: vi.fn(), get: vi.fn() },
|
||||
};
|
||||
|
||||
config.global.plugins = [vuetify];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue