Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/routes/admin.host-aware.test.ts
T

87 lines
3.7 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
import type { LoaderFunctionArgs } from "react-router";
vi.mock("~/components/app/AppLayout", () => ({ default: ({ children }: { children: React.ReactNode }) => children }));
vi.mock("~/utils/data/.server/adminData", () => ({ loadAdminData: vi.fn() }));
vi.mock("~/components/ui/errors/ServerError", () => ({ default: () => null }));
vi.mock("~/modules/metrics/services/.server/MetricTracker", () => ({ createMetrics: vi.fn() }));
vi.mock("~/locale/i18next.server", () => ({ getTranslations: vi.fn() }));
vi.mock("@toolctrl/config", () => ({
loadRequiredWebConfig: () => ({
routing: {
appBaseDomain: "example.test",
webAppHost: "app.example.test",
adminAppHost: "admin.example.test",
apiHost: "api.example.test",
protocol: "https",
},
}),
getDomainRoutingConfig: () => ({
appBaseDomain: "example.test",
webAppHost: "app.example.test",
adminAppHost: "admin.example.test",
apiHost: "api.example.test",
protocol: "https",
}),
hostMatches: (host: string | undefined, expected: string) => host?.toLowerCase() === expected.toLowerCase(),
normalizeHost: (host: string | undefined) => host?.toLowerCase() ?? "",
}));
vi.mock("~/utils/helpers/.server/PermissionsService", () => ({ verifyUserHasPermission: vi.fn() }));
vi.mock("~/components/ui/analytics/AnalyticsOverview", () => ({ default: () => null }));
vi.mock("~/modules/analytics/services/.server/AnalyticsService", () => ({ default: { getOverview: vi.fn() } }));
import { createMetrics } from "~/modules/metrics/services/.server/MetricTracker";
import { loadAdminData } from "~/utils/data/.server/adminData";
import { adminRootRedirectTarget, isAdminRootPath, loader } from "./admin";
import { adminAnalyticsRedirectTarget, isAdminAnalyticsRootPath } from "./admin/analytics";
import { adminMetricsRedirectTarget, isAdminMetricsRootPath } from "./admin/metrics";
describe("admin route host-aware redirects", () => {
beforeEach(() => {
vi.clearAllMocks();
vi.mocked(createMetrics).mockResolvedValue({
time: vi.fn(async (_label: string, callback: () => unknown) => callback()),
getServerTimingHeader: () => ({}),
} as never);
vi.mocked(loadAdminData).mockResolvedValue({} as never);
});
it("redirects the admin host root to dashboard without legacy admin prefixes", () => {
const target = adminRootRedirectTarget();
expect(isAdminRootPath("/")).toBe(true);
expect(isAdminRootPath("/dashboard")).toBe(false);
expect(target).toBe("/dashboard");
expect(target).not.toBe("/admin");
expect(target).not.toBe("/admin/dashboard");
expect(target).not.toContain("/admin/");
});
it("redirects nested analytics and metrics defaults without legacy admin prefixes", () => {
expect(isAdminAnalyticsRootPath("/analytics")).toBe(true);
expect(adminAnalyticsRedirectTarget()).toBe("/analytics/overview");
expect(adminAnalyticsRedirectTarget()).not.toContain("/admin/");
expect(isAdminMetricsRootPath("/metrics")).toBe(true);
expect(adminMetricsRedirectTarget()).toBe("/metrics/summary");
expect(adminMetricsRedirectTarget()).not.toContain("/admin/");
});
it("server-redirects admin route clones away from non-admin hosts", async () => {
try {
await loader({
request: new Request("https://app.example.test/dashboard?tab=activity#events", {
headers: { host: "app.example.test" },
}),
params: {},
context: {},
unstable_pattern: "admin",
} as LoaderFunctionArgs);
} catch (error) {
const response = error as Response;
expect(response.headers.get("Location")).toBe("https://admin.example.test/dashboard?tab=activity#events");
}
expect(loadAdminData).not.toHaveBeenCalled();
});
});