mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-30 02:10:12 -06:00
fix test
This commit is contained in:
@@ -20,7 +20,7 @@ vi.mock("@/modules/ee/contacts/lib/contact-attributes", () => ({
|
||||
vi.mock("@formbricks/database", () => ({
|
||||
prisma: {
|
||||
$transaction: vi.fn(),
|
||||
contactAttribute: { upsert: vi.fn() },
|
||||
contactAttribute: { upsert: vi.fn(), findMany: vi.fn(), deleteMany: vi.fn() },
|
||||
contactAttributeKey: { create: vi.fn() },
|
||||
},
|
||||
}));
|
||||
@@ -52,17 +52,37 @@ const attributeKeys: TContactAttributeKey[] = [
|
||||
type: "default",
|
||||
environmentId,
|
||||
},
|
||||
{
|
||||
id: "key-3",
|
||||
key: "customAttr",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
isUnique: false,
|
||||
name: "Custom Attribute",
|
||||
description: null,
|
||||
type: "custom",
|
||||
environmentId,
|
||||
},
|
||||
];
|
||||
|
||||
describe("updateAttributes", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
// Set default mock return values - these will be overridden in individual tests
|
||||
vi.mocked(prisma.contactAttribute.findMany).mockResolvedValue([]);
|
||||
vi.mocked(prisma.contactAttribute.deleteMany).mockResolvedValue({ count: 0 });
|
||||
vi.mocked(prisma.$transaction).mockResolvedValue(undefined);
|
||||
});
|
||||
|
||||
test("updates existing attributes", async () => {
|
||||
vi.mocked(getContactAttributeKeys).mockResolvedValue(attributeKeys);
|
||||
vi.mocked(hasEmailAttribute).mockResolvedValue(false);
|
||||
vi.mocked(prisma.contactAttribute.findMany).mockResolvedValue([
|
||||
{ attributeKey: { key: "name" } },
|
||||
{ attributeKey: { key: "email" } },
|
||||
] as any);
|
||||
vi.mocked(prisma.$transaction).mockResolvedValue(undefined);
|
||||
vi.mocked(prisma.contactAttribute.deleteMany).mockResolvedValue({ count: 0 });
|
||||
const attributes = { name: "John", email: "john@example.com" };
|
||||
const result = await updateAttributes(contactId, userId, environmentId, attributes);
|
||||
expect(prisma.$transaction).toHaveBeenCalled();
|
||||
@@ -73,7 +93,12 @@ describe("updateAttributes", () => {
|
||||
test("skips updating email if it already exists", async () => {
|
||||
vi.mocked(getContactAttributeKeys).mockResolvedValue(attributeKeys);
|
||||
vi.mocked(hasEmailAttribute).mockResolvedValue(true);
|
||||
vi.mocked(prisma.contactAttribute.findMany).mockResolvedValue([
|
||||
{ attributeKey: { key: "name" } },
|
||||
{ attributeKey: { key: "email" } },
|
||||
] as any);
|
||||
vi.mocked(prisma.$transaction).mockResolvedValue(undefined);
|
||||
vi.mocked(prisma.contactAttribute.deleteMany).mockResolvedValue({ count: 0 });
|
||||
const attributes = { name: "John", email: "john@example.com" };
|
||||
const result = await updateAttributes(contactId, userId, environmentId, attributes);
|
||||
expect(prisma.$transaction).toHaveBeenCalled();
|
||||
@@ -85,7 +110,9 @@ describe("updateAttributes", () => {
|
||||
test("creates new attributes if under limit", async () => {
|
||||
vi.mocked(getContactAttributeKeys).mockResolvedValue([attributeKeys[0]]);
|
||||
vi.mocked(hasEmailAttribute).mockResolvedValue(false);
|
||||
vi.mocked(prisma.contactAttribute.findMany).mockResolvedValue([{ attributeKey: { key: "name" } }] as any);
|
||||
vi.mocked(prisma.$transaction).mockResolvedValue(undefined);
|
||||
vi.mocked(prisma.contactAttribute.deleteMany).mockResolvedValue({ count: 0 });
|
||||
const attributes = { name: "John", newAttr: "val" };
|
||||
const result = await updateAttributes(contactId, userId, environmentId, attributes);
|
||||
expect(prisma.$transaction).toHaveBeenCalled();
|
||||
@@ -97,7 +124,12 @@ describe("updateAttributes", () => {
|
||||
test("does not create new attributes if over the limit", async () => {
|
||||
vi.mocked(getContactAttributeKeys).mockResolvedValue(attributeKeys);
|
||||
vi.mocked(hasEmailAttribute).mockResolvedValue(false);
|
||||
vi.mocked(prisma.contactAttribute.findMany).mockResolvedValue([
|
||||
{ attributeKey: { key: "name" } },
|
||||
{ attributeKey: { key: "email" } },
|
||||
] as any);
|
||||
vi.mocked(prisma.$transaction).mockResolvedValue(undefined);
|
||||
vi.mocked(prisma.contactAttribute.deleteMany).mockResolvedValue({ count: 0 });
|
||||
const attributes = { name: "John", newAttr: "val" };
|
||||
const result = await updateAttributes(contactId, userId, environmentId, attributes);
|
||||
expect(result.success).toBe(true);
|
||||
@@ -107,10 +139,109 @@ describe("updateAttributes", () => {
|
||||
test("returns success with no attributes to update or create", async () => {
|
||||
vi.mocked(getContactAttributeKeys).mockResolvedValue([]);
|
||||
vi.mocked(hasEmailAttribute).mockResolvedValue(false);
|
||||
vi.mocked(prisma.contactAttribute.findMany).mockResolvedValue([]);
|
||||
vi.mocked(prisma.$transaction).mockResolvedValue(undefined);
|
||||
vi.mocked(prisma.contactAttribute.deleteMany).mockResolvedValue({ count: 0 });
|
||||
const attributes = {};
|
||||
const result = await updateAttributes(contactId, userId, environmentId, attributes);
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.messages).toEqual([]);
|
||||
});
|
||||
|
||||
test("deletes non-default attributes that are removed from payload", async () => {
|
||||
// Reset mocks explicitly for this test
|
||||
vi.mocked(prisma.contactAttribute.deleteMany).mockClear();
|
||||
|
||||
vi.mocked(getContactAttributeKeys).mockResolvedValue(attributeKeys);
|
||||
vi.mocked(hasEmailAttribute).mockResolvedValue(false);
|
||||
vi.mocked(prisma.contactAttribute.findMany).mockResolvedValue([
|
||||
{ attributeKey: { key: "name" } },
|
||||
{ attributeKey: { key: "email" } },
|
||||
{ attributeKey: { key: "customAttr" } },
|
||||
] as any);
|
||||
vi.mocked(prisma.$transaction).mockResolvedValue(undefined);
|
||||
vi.mocked(prisma.contactAttribute.deleteMany).mockResolvedValue({ count: 1 });
|
||||
const attributes = { name: "John", email: "john@example.com" };
|
||||
const result = await updateAttributes(contactId, userId, environmentId, attributes);
|
||||
// Only customAttr (key-3) should be deleted, not name (key-1) or email (key-2)
|
||||
expect(prisma.contactAttribute.deleteMany).toHaveBeenCalledWith({
|
||||
where: {
|
||||
contactId,
|
||||
attributeKeyId: {
|
||||
in: ["key-3"],
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.messages).toEqual([]);
|
||||
});
|
||||
|
||||
test("does not delete default attributes even if removed from payload", async () => {
|
||||
// Reset mocks explicitly for this test
|
||||
vi.mocked(prisma.contactAttribute.deleteMany).mockClear();
|
||||
|
||||
// Need to include userId and firstName in attributeKeys for this test
|
||||
// Note: DEFAULT_ATTRIBUTES includes: email, userId, firstName, lastName (not "name")
|
||||
const attributeKeysWithDefaults: TContactAttributeKey[] = [
|
||||
{
|
||||
id: "key-2",
|
||||
key: "email",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
isUnique: false,
|
||||
name: "Email",
|
||||
description: null,
|
||||
type: "default",
|
||||
environmentId,
|
||||
},
|
||||
{
|
||||
id: "key-4",
|
||||
key: "userId",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
isUnique: false,
|
||||
name: "User ID",
|
||||
description: null,
|
||||
type: "default",
|
||||
environmentId,
|
||||
},
|
||||
{
|
||||
id: "key-5",
|
||||
key: "firstName",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
isUnique: false,
|
||||
name: "First Name",
|
||||
description: null,
|
||||
type: "default",
|
||||
environmentId,
|
||||
},
|
||||
{
|
||||
id: "key-3",
|
||||
key: "customAttr",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
isUnique: false,
|
||||
name: "Custom Attribute",
|
||||
description: null,
|
||||
type: "custom",
|
||||
environmentId,
|
||||
},
|
||||
];
|
||||
vi.mocked(getContactAttributeKeys).mockResolvedValue(attributeKeysWithDefaults);
|
||||
vi.mocked(hasEmailAttribute).mockResolvedValue(false);
|
||||
vi.mocked(prisma.contactAttribute.findMany).mockResolvedValue([
|
||||
{ attributeKey: { key: "email" } },
|
||||
{ attributeKey: { key: "userId" } },
|
||||
{ attributeKey: { key: "firstName" } },
|
||||
] as any);
|
||||
vi.mocked(prisma.$transaction).mockResolvedValue(undefined);
|
||||
vi.mocked(prisma.contactAttribute.deleteMany).mockResolvedValue({ count: 0 });
|
||||
const attributes = { customAttr: "value" };
|
||||
const result = await updateAttributes(contactId, userId, environmentId, attributes);
|
||||
// Should not delete default attributes (email, userId, firstName) - deleteMany should not be called
|
||||
// since all current attributes are default attributes
|
||||
expect(prisma.contactAttribute.deleteMany).not.toHaveBeenCalled();
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,6 +21,7 @@ describe("updateContactAttributes", () => {
|
||||
const environmentId = "env123";
|
||||
const userId = "user123";
|
||||
const attributes = {
|
||||
userId,
|
||||
firstName: "John",
|
||||
lastName: "Doe",
|
||||
email: "john@example.com",
|
||||
@@ -37,9 +38,39 @@ describe("updateContactAttributes", () => {
|
||||
};
|
||||
|
||||
const mockCurrentKeys = [
|
||||
{ id: "key1", key: "firstName", name: "First Name", environmentId },
|
||||
{ id: "key2", key: "lastName", name: "Last Name", environmentId },
|
||||
{ id: "key3", key: "email", name: "Email", environmentId },
|
||||
{
|
||||
id: "key1",
|
||||
key: "firstName",
|
||||
name: "First Name",
|
||||
environmentId,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
type: "default" as const,
|
||||
isUnique: false,
|
||||
description: null,
|
||||
},
|
||||
{
|
||||
id: "key2",
|
||||
key: "lastName",
|
||||
name: "Last Name",
|
||||
environmentId,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
type: "default" as const,
|
||||
isUnique: false,
|
||||
description: null,
|
||||
},
|
||||
{
|
||||
id: "key3",
|
||||
key: "email",
|
||||
name: "Email",
|
||||
environmentId,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
type: "default" as const,
|
||||
isUnique: false,
|
||||
description: null,
|
||||
},
|
||||
];
|
||||
|
||||
const mockUpdatedAttributes = {
|
||||
@@ -84,10 +115,42 @@ describe("updateContactAttributes", () => {
|
||||
},
|
||||
};
|
||||
|
||||
const mockCurrentKeys = [{ id: "key1", key: "firstName", name: "First Name", environmentId }];
|
||||
const mockCurrentKeys = [
|
||||
{
|
||||
id: "key1",
|
||||
key: "firstName",
|
||||
name: "First Name",
|
||||
environmentId,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
type: "default" as const,
|
||||
isUnique: false,
|
||||
description: null,
|
||||
},
|
||||
];
|
||||
const mockUpdatedKeys = [
|
||||
{ id: "key1", key: "firstName", name: "First Name", environmentId },
|
||||
{ id: "key2", key: "newCustomField", name: "newCustomField", environmentId },
|
||||
{
|
||||
id: "key1",
|
||||
key: "firstName",
|
||||
name: "First Name",
|
||||
environmentId,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
type: "default" as const,
|
||||
isUnique: false,
|
||||
description: null,
|
||||
},
|
||||
{
|
||||
id: "key2",
|
||||
key: "newCustomField",
|
||||
name: "newCustomField",
|
||||
environmentId,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
type: "custom" as const,
|
||||
isUnique: false,
|
||||
description: null,
|
||||
},
|
||||
];
|
||||
|
||||
const mockUpdatedAttributes = {
|
||||
@@ -107,7 +170,17 @@ describe("updateContactAttributes", () => {
|
||||
|
||||
expect(result.updatedAttributes).toEqual(mockUpdatedAttributes);
|
||||
expect(result.updatedAttributeKeys).toEqual([
|
||||
{ id: "key2", key: "newCustomField", name: "newCustomField", environmentId },
|
||||
{
|
||||
id: "key2",
|
||||
key: "newCustomField",
|
||||
name: "newCustomField",
|
||||
environmentId,
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: expect.any(Date),
|
||||
type: "custom",
|
||||
isUnique: false,
|
||||
description: null,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -126,7 +199,19 @@ describe("updateContactAttributes", () => {
|
||||
},
|
||||
};
|
||||
|
||||
const mockCurrentKeys = [{ id: "key1", key: "firstName", name: "First Name", environmentId }];
|
||||
const mockCurrentKeys = [
|
||||
{
|
||||
id: "key1",
|
||||
key: "firstName",
|
||||
name: "First Name",
|
||||
environmentId,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
type: "default" as const,
|
||||
isUnique: false,
|
||||
description: null,
|
||||
},
|
||||
];
|
||||
const mockUpdatedAttributes = {
|
||||
firstName: "John",
|
||||
};
|
||||
@@ -163,7 +248,19 @@ describe("updateContactAttributes", () => {
|
||||
},
|
||||
};
|
||||
|
||||
const mockCurrentKeys = [{ id: "key1", key: "email", name: "Email", environmentId }];
|
||||
const mockCurrentKeys = [
|
||||
{
|
||||
id: "key1",
|
||||
key: "email",
|
||||
name: "Email",
|
||||
environmentId,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
type: "default" as const,
|
||||
isUnique: false,
|
||||
description: null,
|
||||
},
|
||||
];
|
||||
const mockUpdatedAttributes = {
|
||||
email: "existing@example.com",
|
||||
};
|
||||
@@ -190,6 +287,8 @@ describe("updateContactAttributes", () => {
|
||||
|
||||
vi.mocked(getContact).mockResolvedValue(null);
|
||||
|
||||
await expect(updateContactAttributes(contactId, attributes)).rejects.toThrow("Contact not found");
|
||||
await expect(updateContactAttributes(contactId, attributes)).rejects.toThrow(
|
||||
"contact with ID contact123 not found"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user