Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/utils/data/.server/appData.performance.test.ts
T

96 lines
4.2 KiB
TypeScript

// @vitest-environment node
import { describe, expect, it, vi } from "vitest";
import { TenantUserType } from "~/application/enums/tenants/TenantUserType";
type Deferred<T> = {
promise: Promise<T>;
resolve: (value: T) => void;
};
function deferred<T>(): Deferred<T> {
let resolve!: (value: T) => void;
const promise = new Promise<T>((done) => {
resolve = done;
});
return { promise, resolve };
}
const mocks = vi.hoisted(() => {
const postDetails = {
tenantUser: deferred<{ type: TenantUserType }>(),
tenantTypes: deferred<unknown[]>(),
credits: deferred<unknown>(),
productAccess: deferred<{ allowed: boolean }>(),
};
return { postDetails };
});
vi.mock("~/utils/services/.server/urlService", () => ({ getTenantIdFromUrl: vi.fn(async () => "tenant_1") }));
vi.mock("~/utils/session.server", () => ({ getUserInfo: vi.fn(async () => ({ userId: "user_1", lng: "en" })) }));
vi.mock("@toolctrl/db/auth-boundary.server", () => ({
getAuthUserWithoutPasswordById: vi.fn(async () => ({ id: "user_1", admin: false, locale: "en" })),
getTenantsForUser: vi.fn(async () => [{ id: "tenant_1", slug: "acme", name: "Acme" }]),
}));
vi.mock("~/utils/db/tenants.db.server", () => ({
adminGetAllActiveTenantSimple: vi.fn(async () => []),
getTenantSimple: vi.fn(async () => ({ id: "tenant_1", slug: "acme", name: "Acme", deactivatedReason: null })),
getTenantUserType: vi.fn(() => mocks.postDetails.tenantUser.promise),
}));
vi.mock("@toolctrl/config", () => ({ loadRequiredWebConfig: vi.fn(() => ({ routing: {} })) }));
vi.mock("~/utils/db/entities/entities.db.server", () => ({ getAllEntities: vi.fn(async () => []) }));
vi.mock("~/utils/db/entities/entityGroups.db.server", () => ({ getAllEntityGroups: vi.fn(async () => []) }));
vi.mock("~/utils/db/permissions/groups.db.server", () => ({ getMyGroups: vi.fn(async () => []) }));
vi.mock("~/utils/db/permissions/roles.db.server", () => ({ getAllRolesWithoutPermissions: vi.fn(async () => []) }));
vi.mock("~/utils/db/permissions/userRoles.db.server", () => ({
getPermissionsByUser: vi.fn(async () => []),
getUserRoleInAdmin: vi.fn(async () => null),
getUserRoleInTenant: vi.fn(async () => null),
}));
vi.mock("~/utils/db/tenants/tenantTypes.db.server", () => ({ getAllTenantTypes: vi.fn(() => mocks.postDetails.tenantTypes.promise) }));
vi.mock("~/utils/services/.server/subscriptionService", () => ({
getActiveTenantSubscriptions: vi.fn(async () => ({ products: [] })),
getPlanFeatureUsage: vi.fn(() => mocks.postDetails.credits.promise),
}));
vi.mock("~/modules/onboarding/services/OnboardingService", () => ({ default: { getUserActiveOnboarding: vi.fn(async () => null) } }));
vi.mock("~/utils/entitlements/.server/productAccess.server", () => ({
resolveTenantProductAccess: vi.fn(() => mocks.postDetails.productAccess.promise),
}));
import { getTenantUserType } from "~/utils/db/tenants.db.server";
import { getAllTenantTypes } from "~/utils/db/tenants/tenantTypes.db.server";
import { getPlanFeatureUsage } from "~/utils/services/.server/subscriptionService";
import { resolveTenantProductAccess } from "~/utils/entitlements/.server/productAccess.server";
import { loadAppData } from "./appData";
async function flushAsyncWork() {
await new Promise((resolve) => setImmediate(resolve));
}
describe("loadAppData performance", () => {
it("starts post-detail shell lookups in parallel", async () => {
const result = loadAppData({
request: new Request("https://app.example.test/acme/dashboard"),
params: { tenant: "acme" },
t: ((key: string) => key) as never,
});
await flushAsyncWork();
expect(getTenantUserType).toHaveBeenCalledWith("user_1", "tenant_1");
expect(getAllTenantTypes).toHaveBeenCalled();
expect(getPlanFeatureUsage).toHaveBeenCalledWith("tenant_1", "ai-credits");
expect(resolveTenantProductAccess).toHaveBeenCalled();
mocks.postDetails.tenantUser.resolve({ type: TenantUserType.MEMBER });
mocks.postDetails.tenantTypes.resolve([]);
mocks.postDetails.credits.resolve(undefined);
mocks.postDetails.productAccess.resolve({ allowed: true });
await expect(result).resolves.toMatchObject({
currentRole: TenantUserType.MEMBER,
tenantTypes: [],
productAccess: expect.any(Object),
});
});
});