forked from bai/curriculum-project-hub
90 lines
3.8 KiB
TypeScript
90 lines
3.8 KiB
TypeScript
import { afterAll, beforeEach, describe, expect, it } from "vitest";
|
|
import { bootstrapAlphaSilo } from "../../src/deployment/bootstrap-silo.js";
|
|
import { requireSiloOrganization } from "../../src/deployment/silo.js";
|
|
import { prisma, testSecretEnvelope } from "./helpers.js";
|
|
|
|
const input = {
|
|
organization: { id: "org_alpha", slug: "alpha", name: "Alpha School" },
|
|
owner: { openId: "ou_owner", displayName: "Owner" },
|
|
feishu: { appId: "cli_alpha", appSecret: "feishu-secret", botOpenId: "ou_bot" },
|
|
provider: {
|
|
providerId: "openrouter",
|
|
baseUrl: "https://openrouter.ai/api",
|
|
authToken: "provider-secret",
|
|
},
|
|
teams: [{ slug: "teachers", name: "Teachers" }],
|
|
} as const;
|
|
|
|
describe("Alpha Silo bootstrap", () => {
|
|
beforeEach(async () => {
|
|
await prisma.$executeRawUnsafe(`TRUNCATE TABLE "Organization" RESTART IDENTITY CASCADE`);
|
|
await prisma.organization.create({
|
|
data: {
|
|
id: "org_default",
|
|
slug: "legacy-default",
|
|
name: "Legacy Default Organization",
|
|
projectSettings: { create: { membersCanCreateProjects: true } },
|
|
folders: {
|
|
create: {
|
|
id: "folder_inbox_2b99350e0db97ad0cbcb55c20ee8bafa",
|
|
name: "Inbox",
|
|
sortKey: "000000",
|
|
},
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await prisma.$disconnect();
|
|
});
|
|
|
|
it("creates one scoped Organization and is idempotent", async () => {
|
|
const probes = { feishu: async () => {}, provider: async () => {} };
|
|
const first = await bootstrapAlphaSilo(prisma, testSecretEnvelope, input, probes);
|
|
const second = await bootstrapAlphaSilo(prisma, testSecretEnvelope, input, probes);
|
|
|
|
expect(first).toMatchObject({ organizationId: "org_alpha", initialized: true, providerConfigured: true });
|
|
expect(second).toMatchObject({ organizationId: "org_alpha", initialized: false, providerConfigured: true });
|
|
await expect(requireSiloOrganization(prisma, "org_alpha")).resolves.toMatchObject({ slug: "alpha" });
|
|
expect(await prisma.organization.count()).toBe(1);
|
|
expect(await prisma.organizationMembership.count({ where: { role: "OWNER", revokedAt: null } })).toBe(1);
|
|
expect(await prisma.feishuUserIdentity.count()).toBe(1);
|
|
expect(await prisma.team.count({ where: { slug: "teachers", archivedAt: null } })).toBe(1);
|
|
expect(await prisma.teamMembership.count({ where: { revokedAt: null } })).toBe(1);
|
|
expect(await prisma.organizationProviderConnection.count({ where: { status: "ACTIVE" } })).toBe(1);
|
|
|
|
const persisted = JSON.stringify({
|
|
feishu: await prisma.feishuApplicationCredentialVersion.findMany(),
|
|
provider: await prisma.providerCredentialVersion.findMany(),
|
|
});
|
|
expect(persisted).not.toContain("feishu-secret");
|
|
expect(persisted).not.toContain("provider-secret");
|
|
});
|
|
|
|
it("rejects a configured Organization that does not match the database", async () => {
|
|
await bootstrapAlphaSilo(prisma, testSecretEnvelope, input, {
|
|
feishu: async () => {},
|
|
provider: async () => {},
|
|
});
|
|
await expect(requireSiloOrganization(prisma, "org_other")).rejects.toThrow("Silo Organization mismatch");
|
|
});
|
|
|
|
it("does not delete a legacy migration Organization that contains tenant data", async () => {
|
|
await prisma.project.create({
|
|
data: {
|
|
organizationId: "org_default",
|
|
folderId: "folder_inbox_2b99350e0db97ad0cbcb55c20ee8bafa",
|
|
name: "Legacy Project",
|
|
workspaceDir: "legacy-project",
|
|
},
|
|
});
|
|
|
|
await expect(bootstrapAlphaSilo(prisma, testSecretEnvelope, input, {
|
|
feishu: async () => {},
|
|
provider: async () => {},
|
|
})).rejects.toThrow("bootstrap database is not the configured single-Organization Silo");
|
|
await expect(prisma.organization.findUnique({ where: { id: "org_default" } })).resolves.not.toBeNull();
|
|
});
|
|
});
|