Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion apps/web/i18n.lock
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,6 @@ checksums:
environments/contacts/contacts_table_refresh: 6a959475991dd4ab28ad881bae569a09
environments/contacts/contacts_table_refresh_success: 40951396e88e5c8fdafa0b3bb4fadca8
environments/contacts/create_attribute: 87320615901f95b4f35ee83c290a3a6c
environments/contacts/create_key: 0d385c354af8963acbe35cd646710f86
environments/contacts/create_new_attribute: c17d407dacd0b90f360f9f5e899d662f
environments/contacts/create_new_attribute_description: cc19d76bb6940537bbe3461191f25d26
environments/contacts/custom_attributes: fffc7722742d1291b102dc737cf2fc9e
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Kontakte aktualisieren",
"contacts_table_refresh_success": "Kontakte erfolgreich aktualisiert",
"create_attribute": "Attribut erstellen",
"create_key": "Schlüssel erstellen",
"create_new_attribute": "Neues Attribut erstellen",
"create_new_attribute_description": "Erstellen Sie ein neues Attribut für Segmentierungszwecke.",
"custom_attributes": "Benutzerdefinierte Attribute",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Refresh contacts",
"contacts_table_refresh_success": "Contacts refreshed successfully",
"create_attribute": "Create attribute",
"create_key": "Create Key",
"create_new_attribute": "Create new attribute",
"create_new_attribute_description": "Create a new attribute for segmentation purposes.",
"custom_attributes": "Custom Attributes",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Actualizar contactos",
"contacts_table_refresh_success": "Contactos actualizados correctamente",
"create_attribute": "Crear atributo",
"create_key": "Crear clave",
"create_new_attribute": "Crear atributo nuevo",
"create_new_attribute_description": "Crea un atributo nuevo para fines de segmentación.",
"custom_attributes": "Atributos personalizados",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Actualiser les contacts",
"contacts_table_refresh_success": "Contacts rafraîchis avec succès",
"create_attribute": "Créer un attribut",
"create_key": "Créer une clé",
"create_new_attribute": "Créer un nouvel attribut",
"create_new_attribute_description": "Créez un nouvel attribut à des fins de segmentation.",
"custom_attributes": "Attributs personnalisés",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/hu-HU.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Partnerek frissítése",
"contacts_table_refresh_success": "A partnerek sikeresen frissítve",
"create_attribute": "Attribútum létrehozása",
"create_key": "Kulcs létrehozása",
"create_new_attribute": "Új attribútum létrehozása",
"create_new_attribute_description": "Új attribútum létrehozása szakaszolási célokhoz.",
"custom_attributes": "Egyéni attribútumok",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "連絡先を更新",
"contacts_table_refresh_success": "連絡先を正常に更新しました",
"create_attribute": "属性を作成",
"create_key": "キーを作成",
"create_new_attribute": "新しい属性を作成",
"create_new_attribute_description": "セグメンテーション用の新しい属性を作成します。",
"custom_attributes": "カスタム属性",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/nl-NL.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Vernieuw contacten",
"contacts_table_refresh_success": "Contacten zijn vernieuwd",
"create_attribute": "Attribuut aanmaken",
"create_key": "Sleutel aanmaken",
"create_new_attribute": "Nieuw attribuut aanmaken",
"create_new_attribute_description": "Maak een nieuw attribuut aan voor segmentatiedoeleinden.",
"custom_attributes": "Aangepaste kenmerken",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Atualizar contatos",
"contacts_table_refresh_success": "Contatos atualizados com sucesso",
"create_attribute": "Criar atributo",
"create_key": "Criar chave",
"create_new_attribute": "Criar novo atributo",
"create_new_attribute_description": "Crie um novo atributo para fins de segmentação.",
"custom_attributes": "Atributos personalizados",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/pt-PT.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Atualizar contactos",
"contacts_table_refresh_success": "Contactos atualizados com sucesso",
"create_attribute": "Criar atributo",
"create_key": "Criar chave",
"create_new_attribute": "Criar novo atributo",
"create_new_attribute_description": "Crie um novo atributo para fins de segmentação.",
"custom_attributes": "Atributos personalizados",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/ro-RO.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Reîmprospătare contacte",
"contacts_table_refresh_success": "Contactele au fost actualizate cu succes",
"create_attribute": "Creează atribut",
"create_key": "Creează cheie",
"create_new_attribute": "Creează atribut nou",
"create_new_attribute_description": "Creează un atribut nou pentru segmentare.",
"custom_attributes": "Atribute personalizate",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/ru-RU.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Обновить контакты",
"contacts_table_refresh_success": "Контакты успешно обновлены",
"create_attribute": "Создать атрибут",
"create_key": "Создать ключ",
"create_new_attribute": "Создать новый атрибут",
"create_new_attribute_description": "Создайте новый атрибут для целей сегментации.",
"custom_attributes": "Пользовательские атрибуты",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/sv-SE.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "Uppdatera kontakter",
"contacts_table_refresh_success": "Kontakter uppdaterade",
"create_attribute": "Skapa attribut",
"create_key": "Skapa nyckel",
"create_new_attribute": "Skapa nytt attribut",
"create_new_attribute_description": "Skapa ett nytt attribut för segmenteringsändamål.",
"custom_attributes": "Anpassade attribut",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/zh-Hans-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "刷新 联系人",
"contacts_table_refresh_success": "联系人 已成功刷新",
"create_attribute": "创建属性",
"create_key": "创建键",
"create_new_attribute": "创建新属性",
"create_new_attribute_description": "为细分目的创建新属性。",
"custom_attributes": "自定义属性",
Expand Down
1 change: 0 additions & 1 deletion apps/web/locales/zh-Hant-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,6 @@
"contacts_table_refresh": "重新整理聯絡人",
"contacts_table_refresh_success": "聯絡人已成功重新整理",
"create_attribute": "建立屬性",
"create_key": "建立金鑰",
"create_new_attribute": "建立新屬性",
"create_new_attribute_description": "建立新屬性以進行分群用途。",
"custom_attributes": "自訂屬性",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import { validateInputs } from "@/lib/utils/validate";
import { segmentFilterToPrismaQuery } from "@/modules/ee/contacts/segments/lib/filter/prisma-query";
import { getPersonSegmentIds, getSegments } from "./segments";

// Mock the cache functions
vi.mock("@/lib/cache", () => ({
cache: {
withCache: vi.fn(async (fn) => await fn()), // Just execute the function without caching for tests
withCache: vi.fn(async (fn) => await fn()),
},
}));

Expand All @@ -30,15 +29,15 @@ vi.mock("@formbricks/database", () => ({
contact: {
findFirst: vi.fn(),
},
$transaction: vi.fn(),
},
}));

// Mock React cache
vi.mock("react", async () => {
const actual = await vi.importActual("react");
return {
...actual,
cache: <T extends (...args: any[]) => any>(fn: T): T => fn, // Return the function with the same type signature
cache: <T extends (...args: any[]) => any>(fn: T): T => fn,
};
});

Expand Down Expand Up @@ -97,22 +96,20 @@ describe("segments lib", () => {
});

describe("getPersonSegmentIds", () => {
const mockWhereClause = { AND: [{ environmentId: mockEnvironmentId }, {}] };

beforeEach(() => {
vi.mocked(prisma.segment.findMany).mockResolvedValue(
mockSegmentsData as Prisma.Result<typeof prisma.segment, unknown, "findMany">
);
vi.mocked(segmentFilterToPrismaQuery).mockResolvedValue({
ok: true,
data: { whereClause: { AND: [{ environmentId: mockEnvironmentId }, {}] } },
data: { whereClause: mockWhereClause },
});
});

test("should return person segment IDs successfully", async () => {
vi.mocked(prisma.contact.findFirst).mockResolvedValue({ id: mockContactId } as Prisma.Result<
typeof prisma.contact,
unknown,
"findFirst"
>);
vi.mocked(prisma.$transaction).mockResolvedValue([{ id: mockContactId }, { id: mockContactId }]);

const result = await getPersonSegmentIds(
mockEnvironmentId,
Expand All @@ -128,12 +125,12 @@ describe("segments lib", () => {
});

expect(segmentFilterToPrismaQuery).toHaveBeenCalledTimes(mockSegmentsData.length);
expect(prisma.contact.findFirst).toHaveBeenCalledTimes(mockSegmentsData.length);
expect(prisma.$transaction).toHaveBeenCalledTimes(1);
expect(result).toEqual(mockSegmentsData.map((s) => s.id));
});

test("should return empty array if no segments exist", async () => {
vi.mocked(prisma.segment.findMany).mockResolvedValue([]); // No segments
vi.mocked(prisma.segment.findMany).mockResolvedValue([]);

const result = await getPersonSegmentIds(
mockEnvironmentId,
Expand All @@ -144,27 +141,26 @@ describe("segments lib", () => {

expect(result).toEqual([]);
expect(segmentFilterToPrismaQuery).not.toHaveBeenCalled();
expect(prisma.$transaction).not.toHaveBeenCalled();
});

test("should return empty array if segments exist but none match", async () => {
vi.mocked(prisma.contact.findFirst).mockResolvedValue(null);
vi.mocked(prisma.$transaction).mockResolvedValue([null, null]);

const result = await getPersonSegmentIds(
mockEnvironmentId,
mockContactId,
mockContactUserId,
mockDeviceType
);

expect(result).toEqual([]);
expect(segmentFilterToPrismaQuery).toHaveBeenCalledTimes(mockSegmentsData.length);
expect(prisma.$transaction).toHaveBeenCalledTimes(1);
});

test("should call validateInputs with correct parameters", async () => {
vi.mocked(prisma.contact.findFirst).mockResolvedValue({ id: mockContactId } as Prisma.Result<
typeof prisma.contact,
unknown,
"findFirst"
>);
vi.mocked(prisma.$transaction).mockResolvedValue([{ id: mockContactId }, { id: mockContactId }]);

await getPersonSegmentIds(mockEnvironmentId, mockContactId, mockContactUserId, mockDeviceType);
expect(validateInputs).toHaveBeenCalledWith(
Expand All @@ -175,14 +171,7 @@ describe("segments lib", () => {
});

test("should return only matching segment IDs", async () => {
// First segment matches, second doesn't
vi.mocked(prisma.contact.findFirst)
.mockResolvedValueOnce({ id: mockContactId } as Prisma.Result<
typeof prisma.contact,
unknown,
"findFirst"
>) // First segment matches
.mockResolvedValueOnce(null); // Second segment does not match
vi.mocked(prisma.$transaction).mockResolvedValue([{ id: mockContactId }, null]);

const result = await getPersonSegmentIds(
mockEnvironmentId,
Expand All @@ -193,6 +182,66 @@ describe("segments lib", () => {

expect(result).toEqual([mockSegmentsData[0].id]);
expect(segmentFilterToPrismaQuery).toHaveBeenCalledTimes(mockSegmentsData.length);
expect(prisma.$transaction).toHaveBeenCalledTimes(1);
});

test("should include segments with no filters as always-matching", async () => {
const segmentsWithEmptyFilters = [
{ id: "segment-no-filter", filters: [] },
{ id: "segment-with-filter", filters: [{}] as TBaseFilter[] },
];
vi.mocked(prisma.segment.findMany).mockResolvedValue(
segmentsWithEmptyFilters as Prisma.Result<typeof prisma.segment, unknown, "findMany">
);
vi.mocked(prisma.$transaction).mockResolvedValue([{ id: mockContactId }]);

const result = await getPersonSegmentIds(
mockEnvironmentId,
mockContactId,
mockContactUserId,
mockDeviceType
);

expect(result).toContain("segment-no-filter");
expect(result).toContain("segment-with-filter");
expect(segmentFilterToPrismaQuery).toHaveBeenCalledTimes(1);
expect(prisma.$transaction).toHaveBeenCalledTimes(1);
});

test("should skip segments where filter query building fails", async () => {
vi.mocked(segmentFilterToPrismaQuery)
.mockResolvedValueOnce({
ok: true,
data: { whereClause: mockWhereClause },
})
.mockResolvedValueOnce({
ok: false,
error: { type: "bad_request", message: "Invalid filters", details: [] },
});
vi.mocked(prisma.$transaction).mockResolvedValue([{ id: mockContactId }]);

const result = await getPersonSegmentIds(
mockEnvironmentId,
mockContactId,
mockContactUserId,
mockDeviceType
);

expect(result).toEqual(["segment1"]);
expect(prisma.$transaction).toHaveBeenCalledTimes(1);
});

test("should return empty array on unexpected error", async () => {
vi.mocked(prisma.segment.findMany).mockRejectedValue(new Error("Unexpected"));

const result = await getPersonSegmentIds(
mockEnvironmentId,
mockContactId,
mockContactUserId,
mockDeviceType
);

expect(result).toEqual([]);
});
});
});
Loading
Loading