mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-15 18:30:39 +09:00
test: harden onboarding route coverage
This commit is contained in:
parent
cc1620e4fe
commit
2c05c2c0ac
6 changed files with 203 additions and 85 deletions
80
ui/src/lib/onboarding-route.test.ts
Normal file
80
ui/src/lib/onboarding-route.test.ts
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
isOnboardingPath,
|
||||
resolveRouteOnboardingOptions,
|
||||
shouldRedirectCompanylessRouteToOnboarding,
|
||||
} from "./onboarding-route";
|
||||
|
||||
describe("isOnboardingPath", () => {
|
||||
it("matches the global onboarding route", () => {
|
||||
expect(isOnboardingPath("/onboarding")).toBe(true);
|
||||
});
|
||||
|
||||
it("matches a company-prefixed onboarding route", () => {
|
||||
expect(isOnboardingPath("/pap/onboarding")).toBe(true);
|
||||
});
|
||||
|
||||
it("ignores non-onboarding routes", () => {
|
||||
expect(isOnboardingPath("/pap/dashboard")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveRouteOnboardingOptions", () => {
|
||||
it("opens company creation for the global onboarding route", () => {
|
||||
expect(
|
||||
resolveRouteOnboardingOptions({
|
||||
pathname: "/onboarding",
|
||||
companies: [],
|
||||
}),
|
||||
).toEqual({ initialStep: 1 });
|
||||
});
|
||||
|
||||
it("opens agent creation when the prefixed company exists", () => {
|
||||
expect(
|
||||
resolveRouteOnboardingOptions({
|
||||
pathname: "/pap/onboarding",
|
||||
companyPrefix: "pap",
|
||||
companies: [{ id: "company-1", issuePrefix: "PAP" }],
|
||||
}),
|
||||
).toEqual({ initialStep: 2, companyId: "company-1" });
|
||||
});
|
||||
|
||||
it("falls back to company creation when the prefixed company is missing", () => {
|
||||
expect(
|
||||
resolveRouteOnboardingOptions({
|
||||
pathname: "/pap/onboarding",
|
||||
companyPrefix: "pap",
|
||||
companies: [],
|
||||
}),
|
||||
).toEqual({ initialStep: 1 });
|
||||
});
|
||||
});
|
||||
|
||||
describe("shouldRedirectCompanylessRouteToOnboarding", () => {
|
||||
it("redirects companyless entry routes into onboarding", () => {
|
||||
expect(
|
||||
shouldRedirectCompanylessRouteToOnboarding({
|
||||
pathname: "/",
|
||||
hasCompanies: false,
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("does not redirect when already on onboarding", () => {
|
||||
expect(
|
||||
shouldRedirectCompanylessRouteToOnboarding({
|
||||
pathname: "/onboarding",
|
||||
hasCompanies: false,
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it("does not redirect when companies exist", () => {
|
||||
expect(
|
||||
shouldRedirectCompanylessRouteToOnboarding({
|
||||
pathname: "/issues",
|
||||
hasCompanies: true,
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
51
ui/src/lib/onboarding-route.ts
Normal file
51
ui/src/lib/onboarding-route.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
type OnboardingRouteCompany = {
|
||||
id: string;
|
||||
issuePrefix: string;
|
||||
};
|
||||
|
||||
export function isOnboardingPath(pathname: string): boolean {
|
||||
const segments = pathname.split("/").filter(Boolean);
|
||||
|
||||
if (segments.length === 1) {
|
||||
return segments[0]?.toLowerCase() === "onboarding";
|
||||
}
|
||||
|
||||
if (segments.length === 2) {
|
||||
return segments[1]?.toLowerCase() === "onboarding";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function resolveRouteOnboardingOptions(params: {
|
||||
pathname: string;
|
||||
companyPrefix?: string;
|
||||
companies: OnboardingRouteCompany[];
|
||||
}): { initialStep: 1 | 2; companyId?: string } | null {
|
||||
const { pathname, companyPrefix, companies } = params;
|
||||
|
||||
if (!isOnboardingPath(pathname)) return null;
|
||||
|
||||
if (!companyPrefix) {
|
||||
return { initialStep: 1 };
|
||||
}
|
||||
|
||||
const matchedCompany =
|
||||
companies.find(
|
||||
(company) =>
|
||||
company.issuePrefix.toUpperCase() === companyPrefix.toUpperCase(),
|
||||
) ?? null;
|
||||
|
||||
if (!matchedCompany) {
|
||||
return { initialStep: 1 };
|
||||
}
|
||||
|
||||
return { initialStep: 2, companyId: matchedCompany.id };
|
||||
}
|
||||
|
||||
export function shouldRedirectCompanylessRouteToOnboarding(params: {
|
||||
pathname: string;
|
||||
hasCompanies: boolean;
|
||||
}): boolean {
|
||||
return !params.hasCompanies && !isOnboardingPath(params.pathname);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue