chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
import { containerTest } from "@internal/testcontainers";
|
||||
import type { PrismaClient } from "@trigger.dev/database";
|
||||
import { describe, expect, vi } from "vitest";
|
||||
import { removeTeamMember } from "~/models/removeTeamMember.server";
|
||||
|
||||
vi.setConfig({ testTimeout: 60_000 });
|
||||
|
||||
async function seedOrgWithMembers(prisma: PrismaClient, slugBase: string) {
|
||||
const slug = `${slugBase}_${Math.random().toString(36).slice(2, 10)}`;
|
||||
const admin = await prisma.user.create({
|
||||
data: { email: `admin_${slug}@example.com`, authenticationMethod: "MAGIC_LINK" },
|
||||
});
|
||||
const member = await prisma.user.create({
|
||||
data: { email: `member_${slug}@example.com`, authenticationMethod: "MAGIC_LINK" },
|
||||
});
|
||||
|
||||
const organization = await prisma.organization.create({
|
||||
data: {
|
||||
title: slug,
|
||||
slug,
|
||||
members: {
|
||||
createMany: {
|
||||
data: [
|
||||
{ userId: admin.id, role: "ADMIN" },
|
||||
{ userId: member.id, role: "MEMBER" },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
include: { members: true },
|
||||
});
|
||||
|
||||
const adminMember = organization.members.find((m) => m.userId === admin.id)!;
|
||||
const regularMember = organization.members.find((m) => m.userId === member.id)!;
|
||||
return { organization, admin, member, adminMember, regularMember };
|
||||
}
|
||||
|
||||
describe("removeTeamMember", () => {
|
||||
containerTest(
|
||||
"refuses to delete an OrgMember that belongs to a different org",
|
||||
async ({ prisma }) => {
|
||||
const a = await seedOrgWithMembers(prisma, "orga");
|
||||
const b = await seedOrgWithMembers(prisma, "orgb");
|
||||
|
||||
await expect(
|
||||
removeTeamMember(
|
||||
{
|
||||
userId: a.admin.id,
|
||||
slug: a.organization.slug,
|
||||
memberId: b.regularMember.id,
|
||||
},
|
||||
prisma
|
||||
)
|
||||
).rejects.toThrow();
|
||||
|
||||
const stillThere = await prisma.orgMember.findUnique({
|
||||
where: { id: b.regularMember.id },
|
||||
});
|
||||
expect(stillThere).not.toBeNull();
|
||||
}
|
||||
);
|
||||
|
||||
containerTest("removes a member that belongs to the actor's org", async ({ prisma }) => {
|
||||
const a = await seedOrgWithMembers(prisma, "orga");
|
||||
|
||||
const result = await removeTeamMember(
|
||||
{
|
||||
userId: a.admin.id,
|
||||
slug: a.organization.slug,
|
||||
memberId: a.regularMember.id,
|
||||
},
|
||||
prisma
|
||||
);
|
||||
expect(result.id).toBe(a.regularMember.id);
|
||||
|
||||
const gone = await prisma.orgMember.findUnique({
|
||||
where: { id: a.regularMember.id },
|
||||
});
|
||||
expect(gone).toBeNull();
|
||||
});
|
||||
|
||||
containerTest("allows the actor to leave their own org (self-leave)", async ({ prisma }) => {
|
||||
const a = await seedOrgWithMembers(prisma, "orga");
|
||||
|
||||
const result = await removeTeamMember(
|
||||
{
|
||||
userId: a.member.id,
|
||||
slug: a.organization.slug,
|
||||
memberId: a.regularMember.id,
|
||||
},
|
||||
prisma
|
||||
);
|
||||
expect(result.userId).toBe(a.member.id);
|
||||
|
||||
const gone = await prisma.orgMember.findUnique({
|
||||
where: { id: a.regularMember.id },
|
||||
});
|
||||
expect(gone).toBeNull();
|
||||
});
|
||||
|
||||
containerTest(
|
||||
"throws the in-org not-found error for an unknown memberId (locks the error message the route renders)",
|
||||
async ({ prisma }) => {
|
||||
const a = await seedOrgWithMembers(prisma, "orga");
|
||||
|
||||
await expect(
|
||||
removeTeamMember(
|
||||
{
|
||||
userId: a.admin.id,
|
||||
slug: a.organization.slug,
|
||||
memberId: "doesnotexist",
|
||||
},
|
||||
prisma
|
||||
)
|
||||
).rejects.toThrow("Member not found in this organization");
|
||||
}
|
||||
);
|
||||
|
||||
containerTest("throws when the actor is not a member of the slug org", async ({ prisma }) => {
|
||||
const a = await seedOrgWithMembers(prisma, "orga");
|
||||
const b = await seedOrgWithMembers(prisma, "orgb");
|
||||
|
||||
await expect(
|
||||
removeTeamMember(
|
||||
{
|
||||
userId: a.admin.id,
|
||||
slug: b.organization.slug,
|
||||
memberId: b.regularMember.id,
|
||||
},
|
||||
prisma
|
||||
)
|
||||
).rejects.toThrow("User does not have access to this organization");
|
||||
|
||||
const stillThere = await prisma.orgMember.findUnique({
|
||||
where: { id: b.regularMember.id },
|
||||
});
|
||||
expect(stillThere).not.toBeNull();
|
||||
});
|
||||
|
||||
containerTest(
|
||||
"uses an exact-message error for cross-tenant attempts (locks contract)",
|
||||
async ({ prisma }) => {
|
||||
const a = await seedOrgWithMembers(prisma, "orga");
|
||||
const b = await seedOrgWithMembers(prisma, "orgb");
|
||||
|
||||
await expect(
|
||||
removeTeamMember(
|
||||
{
|
||||
userId: a.admin.id,
|
||||
slug: a.organization.slug,
|
||||
memberId: b.regularMember.id,
|
||||
},
|
||||
prisma
|
||||
)
|
||||
).rejects.toThrow("Member not found in this organization");
|
||||
}
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user