96 lines
4.2 KiB
TypeScript
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),
|
|
});
|
|
});
|
|
});
|