Files
pleno-vue/tests/unit/guest-auth-entry-loader.spec.js
T

181 lines
5.3 KiB
JavaScript

// @vitest-environment jsdom
import { defineComponent, h, nextTick } from "vue";
import { mount } from "@vue/test-utils";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
hasStoredSessionToken: vi.fn(),
routerReplace: vi.fn(),
routeQuery: {},
}));
vi.mock("@/services/sessionStorage.js", () => ({
hasStoredSessionToken: mocks.hasStoredSessionToken,
}));
vi.mock("vue-router", () => ({
useRoute: () => ({ query: mocks.routeQuery }),
useRouter: () => ({ replace: mocks.routerReplace }),
}));
vi.mock("@/components/global/BrandedLoadingScreen.vue", () => ({
default: defineComponent({
name: "MockBrandedLoadingScreen",
props: {
title: {
type: String,
default: "",
},
testId: {
type: String,
default: "branded-loading-screen",
},
statusTestId: {
type: String,
default: "",
},
},
setup(props) {
return () =>
h("div", { "data-testid": props.testId }, [
h("span", { "data-testid": props.statusTestId || undefined }, props.title),
]);
},
}),
}));
vi.mock("@/components/forms/auth/LoginForm.vue", () => ({
default: defineComponent({
name: "MockLoginForm",
setup() {
return () => h("form", { "data-testid": "login-form" });
},
}),
}));
vi.mock("@/components/forms/auth/SubuserLoginForm.vue", () => ({
default: defineComponent({
name: "MockSubuserLoginForm",
setup() {
return () => h("form", { "data-testid": "subuser-login-form" });
},
}),
}));
vi.mock("@/components/forms/auth/LoginEmployeeForm.vue", () => ({
default: defineComponent({
name: "MockLoginEmployeeForm",
setup() {
return () => h("form", { "data-testid": "employee-login-form" });
},
}),
}));
vi.mock("@/views/errors/ConnectivityIssue.vue", () => ({
default: defineComponent({
name: "MockConnectivityIssue",
setup(_, { slots }) {
return () => h("div", { "data-testid": "connectivity-wrapper" }, slots.default?.());
},
}),
}));
import LandingPage from "@/views/pages/LandingPage.vue";
import Login from "@/views/auth/Login.vue";
import SubuserLogin from "@/views/auth/SubuserLogin.vue";
import Employee from "@/views/auth/Employee.vue";
const routerLinkStub = defineComponent({
name: "RouterLinkStub",
props: {
to: {
type: [String, Object],
default: "",
},
},
setup(_, { slots }) {
return () => h("a", slots.default?.());
},
});
const mountView = (component) =>
mount(component, {
global: {
mocks: {
$t: (key) => key,
},
stubs: {
RouterLink: routerLinkStub,
},
},
});
describe("guest auth entry loaders", () => {
beforeEach(() => {
mocks.hasStoredSessionToken.mockReset();
mocks.hasStoredSessionToken.mockReturnValue(false);
mocks.routerReplace.mockReset();
Object.keys(mocks.routeQuery).forEach((key) => delete mocks.routeQuery[key]);
});
afterEach(() => {
document.body.innerHTML = "";
});
it("shows the landing login form when no stored session exists", async () => {
const wrapper = mountView(LandingPage);
await nextTick();
expect(wrapper.find('[data-testid="login-form"]').exists()).toBe(true);
expect(wrapper.find('[data-testid="guest-session-loading"]').exists()).toBe(false);
expect(mocks.routerReplace).not.toHaveBeenCalled();
});
it("keeps authenticated landing visits on the session loader before redirecting", async () => {
mocks.hasStoredSessionToken.mockReturnValue(true);
const wrapper = mountView(LandingPage);
await nextTick();
expect(wrapper.find('[data-testid="login-form"]').exists()).toBe(false);
expect(wrapper.get('[data-testid="guest-session-loading-status"]').text()).toBe("Bekræfter bruger...");
expect(mocks.routerReplace).toHaveBeenCalledWith({ name: "default" });
});
it("keeps authenticated customer-login visits on the loader and honors safe redirects", async () => {
mocks.hasStoredSessionToken.mockReturnValue(true);
mocks.routeQuery.redirect = "/user/orders?status=open#latest";
const wrapper = mountView(Login);
await nextTick();
expect(wrapper.find('[data-testid="login-form"]').exists()).toBe(false);
expect(wrapper.get('[data-testid="guest-session-loading-status"]').text()).toBe("Bekræfter bruger...");
expect(mocks.routerReplace).toHaveBeenCalledWith("/user/orders?status=open#latest");
});
it("falls back to the session redirect route for unsafe login redirects", async () => {
mocks.hasStoredSessionToken.mockReturnValue(true);
mocks.routeQuery.redirect = "https://example.invalid/user";
mountView(Login);
await nextTick();
expect(mocks.routerReplace).toHaveBeenCalledWith({ name: "default" });
});
it.each([
["driver", SubuserLogin, "subuser-login-form"],
["operator", Employee, "employee-login-form"],
])("keeps authenticated %s login visits on the session loader", async (_label, component, formTestId) => {
mocks.hasStoredSessionToken.mockReturnValue(true);
const wrapper = mountView(component);
await nextTick();
expect(wrapper.find(`[data-testid="${formTestId}"]`).exists()).toBe(false);
expect(wrapper.get('[data-testid="guest-session-loading-status"]').text()).toBe("Bekræfter bruger...");
expect(mocks.routerReplace).toHaveBeenCalledWith({ name: "default" });
});
});