chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
import { postgresTest } from "@internal/testcontainers";
|
||||
import { type PrismaClient } from "@trigger.dev/database";
|
||||
import slug from "slug";
|
||||
import { describe, expect, vi } from "vitest";
|
||||
import { ArchiveBranchService } from "~/services/archiveBranch.server";
|
||||
import { UpsertBranchService } from "~/services/upsertBranch.server";
|
||||
import { createTestOrgProjectWithMember, uniqueId } from "./fixtures/environmentVariablesFixtures";
|
||||
|
||||
vi.setConfig({ testTimeout: 60_000 });
|
||||
|
||||
async function createDevRoot(
|
||||
prisma: PrismaClient,
|
||||
projectId: string,
|
||||
organizationId: string,
|
||||
orgMemberId: string
|
||||
) {
|
||||
return prisma.runtimeEnvironment.create({
|
||||
data: {
|
||||
slug: "dev",
|
||||
apiKey: uniqueId("tr_dev"),
|
||||
pkApiKey: uniqueId("pk_dev"),
|
||||
shortcode: uniqueId("sc"),
|
||||
projectId,
|
||||
organizationId,
|
||||
type: "DEVELOPMENT",
|
||||
orgMemberId,
|
||||
maximumConcurrencyLimit: 17,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
describe("UpsertBranchService — DEVELOPMENT parent", () => {
|
||||
postgresTest(
|
||||
"creates a child branch that inherits the parent's ownership",
|
||||
async ({ prisma }) => {
|
||||
const { organization, project, user, orgMember } =
|
||||
await createTestOrgProjectWithMember(prisma);
|
||||
const devRoot = await createDevRoot(prisma, project.id, organization.id, orgMember.id);
|
||||
|
||||
const result = await new UpsertBranchService(prisma).call(
|
||||
{ type: "userMembership", userId: user.id },
|
||||
{ projectId: project.id, env: "development", branchName: "my-feature" }
|
||||
);
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
if (!result.success) return;
|
||||
|
||||
const { branch } = result;
|
||||
expect(branch.type).toBe("DEVELOPMENT");
|
||||
expect(branch.parentEnvironmentId).toBe(devRoot.id);
|
||||
expect(branch.branchName).toBe("my-feature");
|
||||
// The key dev-vs-preview divergence: dev branches MUST copy the parent's
|
||||
// orgMemberId (preview parents have none).
|
||||
expect(branch.orgMemberId).toBe(orgMember.id);
|
||||
// Children inherit the parent's concurrency limit at creation.
|
||||
expect(branch.maximumConcurrencyLimit).toBe(17);
|
||||
expect(branch.slug).toBe(slug(`${devRoot.slug}-my-feature`));
|
||||
}
|
||||
);
|
||||
|
||||
postgresTest(
|
||||
"is idempotent — upserting the same branch returns the existing row",
|
||||
async ({ prisma }) => {
|
||||
const { organization, project, user, orgMember } =
|
||||
await createTestOrgProjectWithMember(prisma);
|
||||
await createDevRoot(prisma, project.id, organization.id, orgMember.id);
|
||||
const orgFilter = { type: "userMembership" as const, userId: user.id };
|
||||
const options = { projectId: project.id, env: "development" as const, branchName: "dup" };
|
||||
|
||||
const first = await new UpsertBranchService(prisma).call(orgFilter, options);
|
||||
const second = await new UpsertBranchService(prisma).call(orgFilter, options);
|
||||
|
||||
expect(first.success && second.success).toBe(true);
|
||||
if (!first.success || !second.success) return;
|
||||
expect(second.alreadyExisted).toBe(true);
|
||||
expect(second.branch.id).toBe(first.branch.id);
|
||||
}
|
||||
);
|
||||
|
||||
postgresTest(
|
||||
"rejects an invalid branch name without touching the database",
|
||||
async ({ prisma }) => {
|
||||
const { organization, project, user, orgMember } =
|
||||
await createTestOrgProjectWithMember(prisma);
|
||||
await createDevRoot(prisma, project.id, organization.id, orgMember.id);
|
||||
|
||||
const result = await new UpsertBranchService(prisma).call(
|
||||
{ type: "userMembership", userId: user.id },
|
||||
{ projectId: project.id, env: "development", branchName: "bad branch name!" }
|
||||
);
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
describe("ArchiveBranchService — DEVELOPMENT", () => {
|
||||
postgresTest(
|
||||
"archives a dev branch and frees its slug/shortcode for reuse",
|
||||
async ({ prisma }) => {
|
||||
const { organization, project, user, orgMember } =
|
||||
await createTestOrgProjectWithMember(prisma);
|
||||
await createDevRoot(prisma, project.id, organization.id, orgMember.id);
|
||||
const orgFilter = { type: "userMembership" as const, userId: user.id };
|
||||
|
||||
const created = await new UpsertBranchService(prisma).call(orgFilter, {
|
||||
projectId: project.id,
|
||||
env: "development",
|
||||
branchName: "reuse-me",
|
||||
});
|
||||
expect(created.success).toBe(true);
|
||||
if (!created.success) return;
|
||||
const originalSlug = created.branch.slug;
|
||||
|
||||
const archived = await new ArchiveBranchService(prisma).call(orgFilter, {
|
||||
environmentId: created.branch.id,
|
||||
});
|
||||
expect(archived.success).toBe(true);
|
||||
if (!archived.success) return;
|
||||
expect(archived.branch.archivedAt).not.toBeNull();
|
||||
// Slug + shortcode are randomized on archive so the name can be reused.
|
||||
expect(archived.branch.slug).not.toBe(originalSlug);
|
||||
|
||||
// The same branch name can now be created again (new row, deterministic slug).
|
||||
const recreated = await new UpsertBranchService(prisma).call(orgFilter, {
|
||||
projectId: project.id,
|
||||
env: "development",
|
||||
branchName: "reuse-me",
|
||||
});
|
||||
expect(recreated.success).toBe(true);
|
||||
if (!recreated.success) return;
|
||||
expect(recreated.branch.id).not.toBe(created.branch.id);
|
||||
expect(recreated.branch.slug).toBe(originalSlug);
|
||||
}
|
||||
);
|
||||
|
||||
postgresTest("refuses to archive the default branch (the dev root)", async ({ prisma }) => {
|
||||
const { organization, project, user, orgMember } = await createTestOrgProjectWithMember(prisma);
|
||||
const devRoot = await createDevRoot(prisma, project.id, organization.id, orgMember.id);
|
||||
|
||||
const result = await new ArchiveBranchService(prisma).call(
|
||||
{ type: "userMembership", userId: user.id },
|
||||
{ environmentId: devRoot.id }
|
||||
);
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
if (result.success) return;
|
||||
expect(result.error).toBe("The default development branch cannot be archived.");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user