Parcourir la source

feat: Added Modal component tests

Owen Diffey il y a 1 an
Parent
commit
56d02f3397

+ 1 - 9
frontend/dist/config/template.json

@@ -34,15 +34,7 @@
 	"messages": {
 		"accountRemoval": "Your account will be deactivated instantly and your data will shortly be deleted by an admin."
 	},
-	// "shortcutOverrides": {
-	// 	"editSong.useAllDiscogs": {
-	// 		"keyCode": 68,
-	// 		"ctrl": true,
-	// 		"alt": true,
-	// 		"shift": false,
-	// 		"preventDefault": true
-	// 	}
-	// },
+	"shortcutOverrides": {},
 	"debug": {
 		"git": {
 			"remote": false,

+ 2 - 2
frontend/src/components/ChristmasLights.spec.ts

@@ -6,8 +6,8 @@ import { useUserAuthStore } from "@/stores/userAuth";
 const { getWrapper } = useTestUtils();
 
 describe("ChristmasLights component", () => {
-	beforeEach(context => {
-		context.wrapper = getWrapper(ChristmasLights);
+	beforeEach(async context => {
+		context.wrapper = await getWrapper(ChristmasLights);
 	});
 
 	test("small prop", async ({ wrapper }) => {

+ 1 - 1
frontend/src/components/InfoIcon.spec.ts

@@ -4,7 +4,7 @@ import { useTestUtils } from "@/composables/useTestUtils";
 const { getWrapper } = useTestUtils();
 
 test("InfoIcon component", async () => {
-	const wrapper = getWrapper(InfoIcon, {
+	const wrapper = await getWrapper(InfoIcon, {
 		props: { tooltip: "This is a tooltip" }
 	});
 

+ 3 - 3
frontend/src/components/InputHelpBox.spec.ts

@@ -4,8 +4,8 @@ import { useTestUtils } from "@/composables/useTestUtils";
 const { getWrapper } = useTestUtils();
 
 describe("InputHelpBox component", () => {
-	beforeEach(context => {
-		context.wrapper = getWrapper(InputHelpBox, {
+	beforeEach(async context => {
+		context.wrapper = await getWrapper(InputHelpBox, {
 			props: {
 				message: "",
 				valid: true
@@ -29,7 +29,7 @@ describe("InputHelpBox component", () => {
 		{ valid: false, entered: true, expected: "is-danger" },
 		{ valid: false, entered: false, expected: "is-grey" },
 		{ valid: false, entered: undefined, expected: "is-danger" }
-	])("valid and entered props", ({ valid, entered, expected }) => {
+	])("valid and entered props %j", ({ valid, entered, expected }) => {
 		test("class updated", async ({ wrapper }) => {
 			await wrapper.setProps({
 				valid,

+ 75 - 0
frontend/src/components/Modal.spec.ts

@@ -0,0 +1,75 @@
+import { flushPromises } from "@vue/test-utils";
+import { h } from "vue";
+import { useTestUtils } from "@/composables/useTestUtils";
+import { useModalsStore } from "@/stores/modals";
+import Modal from "@/components/Modal.vue";
+
+const { getWrapper } = useTestUtils();
+
+describe("Modal component", () => {
+	beforeEach(async context => {
+		context.wrapper = await getWrapper(Modal);
+	});
+
+	test("title prop", async ({ wrapper }) => {
+		const title = "Modal Title";
+		await wrapper.setProps({ title });
+		expect(wrapper.find(".modal-card-title").text()).toBe(title);
+	});
+
+	test("size prop", async ({ wrapper }) => {
+		await wrapper.setProps({ size: "slim" });
+		expect(wrapper.find(".modal-card").classes()).toContain("modal-slim");
+
+		await wrapper.setProps({ size: "wide" });
+		expect(wrapper.find(".modal-card").classes()).toContain("modal-wide");
+	});
+
+	test("split prop", async ({ wrapper }) => {
+		expect(wrapper.find(".modal-card").classes()).not.toContain(
+			"modal-split"
+		);
+		await wrapper.setProps({ split: true });
+		expect(wrapper.find(".modal-card").classes()).toContain("modal-split");
+	});
+
+	test("christmas lights render if enabled", async () => {
+		const wrapper = await getWrapper(Modal, {
+			shallow: true,
+			lofig: { siteSettings: { christmas: true } }
+		});
+		expect(
+			wrapper.findComponent({ name: "ChristmasLights" }).exists()
+		).toBeTruthy();
+	});
+
+	test("click to close modal emits if intercepted", async ({ wrapper }) => {
+		await wrapper.setProps({ interceptClose: true });
+		await wrapper.find(".modal-background").trigger("click");
+		await wrapper.find(".modal-card-head > .delete").trigger("click");
+		expect(wrapper.emitted()).toHaveProperty("close");
+		expect(wrapper.emitted().close).toHaveLength(2);
+	});
+
+	test("click to close modal calls store action if not intercepted", async ({
+		wrapper
+	}) => {
+		const modalsStore = useModalsStore();
+		await wrapper.find(".modal-background").trigger("click");
+		await wrapper.find(".modal-card-head > .delete").trigger("click");
+		await flushPromises();
+		expect(modalsStore.closeCurrentModal).toHaveBeenCalledTimes(2);
+	});
+
+	test("renders slots", async () => {
+		const wrapper = await getWrapper(Modal, {
+			slots: {
+				sidebar: h("div", {}, "Sidebar Slot"),
+				toggleMobileSidebar: h("div", {}, "Toggle Mobile Sidebar Slot"),
+				body: h("div", {}, "Body Slot"),
+				footer: h("div", {}, "Footer Slot")
+			}
+		});
+		expect(wrapper.html()).toMatchSnapshot();
+	});
+});

+ 21 - 0
frontend/src/components/__snapshots__/Modal.spec.ts.snap

@@ -0,0 +1,21 @@
+// Vitest Snapshot v1
+
+exports[`Modal component > renders slots 1`] = `
+"<div class=\\"modal is-active\\">
+  <div class=\\"modal-background\\"></div>
+  <div>Sidebar Slot</div>
+  <div class=\\"modal-card\\">
+    <header class=\\"modal-card-head\\">
+      <div>Toggle Mobile Sidebar Slot</div>
+      <h2 class=\\"modal-card-title is-marginless\\">Modal</h2><span class=\\"delete material-icons\\">highlight_off</span>
+      <!--v-if-->
+    </header>
+    <section class=\\"modal-card-body\\">
+      <div>Body Slot</div>
+    </section>
+    <footer class=\\"modal-card-foot\\">
+      <div>Footer Slot</div>
+    </footer>
+  </div>
+</div>"
+`;

+ 22 - 8
frontend/src/composables/useTestUtils.ts

@@ -1,9 +1,16 @@
 import { createTestingPinia } from "@pinia/testing";
 import VueTippy, { Tippy } from "vue-tippy";
-import { mount } from "@vue/test-utils";
+import { flushPromises, mount } from "@vue/test-utils";
+import "lofig";
+
+const config = await import("../../dist/config/template.json");
 
 export const useTestUtils = () => {
-	const getWrapper = (component, options?) => {
+	const getWrapper = async (component, options?) => {
+		const opts = options || {};
+
+		if (!opts.global) opts.global = {};
+
 		const plugins = [
 			createTestingPinia(),
 			[
@@ -23,14 +30,11 @@ export const useTestUtils = () => {
 				}
 			]
 		];
-
-		const components = { Tippy };
-
-		const opts = options || {};
-		if (!opts.global) opts.global = {};
 		if (opts.global.plugins)
 			opts.global.plugins = [...opts.global.plugins, ...plugins];
 		else opts.global.plugins = plugins;
+
+		const components = { Tippy };
 		if (opts.global.components)
 			opts.global.components = {
 				...opts.global.components,
@@ -38,7 +42,17 @@ export const useTestUtils = () => {
 			};
 		else opts.global.components = components;
 
-		return mount(component, opts);
+		if (opts.lofig) {
+			lofig.config = {
+				...config,
+				...opts.lofig
+			};
+			delete opts.lofig;
+		} else lofig.config = config;
+
+		const wrapper = mount(component, opts);
+		await flushPromises();
+		return wrapper;
 	};
 
 	return { getWrapper };

+ 1 - 0
frontend/tsconfig.json

@@ -5,6 +5,7 @@
     "moduleResolution": "node",
     "importHelpers": true,
     "isolatedModules": true,
+    "resolveJsonModule": true,
     "noEmit": true,
     "baseUrl": ".",
     "paths": {