Fix test cases

This commit is contained in:
Dries Augustyns
2025-12-04 13:17:07 +01:00
parent 04634a447b
commit 73918f5211
4 changed files with 88 additions and 44 deletions
@@ -43,9 +43,9 @@ describe('Workflows Controller', () => {
expect(responseBody.fields).toContain('contact.subscribed'); expect(responseBody.fields).toContain('contact.subscribed');
// Should include custom contact data fields // Should include custom contact data fields
expect(responseBody.fields).toContain('data.firstName'); expect(responseBody.fields).toContain('contact.data.firstName');
expect(responseBody.fields).toContain('data.lastName'); expect(responseBody.fields).toContain('contact.data.lastName');
expect(responseBody.fields).toContain('data.plan'); expect(responseBody.fields).toContain('contact.data.plan');
// Should include event fields // Should include event fields
expect(responseBody.fields).toContain('event.subject'); expect(responseBody.fields).toContain('event.subject');
@@ -233,7 +233,9 @@ describe('SegmentService', () => {
expect(segment.name).toBe('VIP Customers'); expect(segment.name).toBe('VIP Customers');
expect(segment.projectId).toBe(projectId); expect(segment.projectId).toBe(projectId);
expect(Array.isArray(segment.filters)).toBe(true); // Segments now use condition object with groups containing filters
expect(segment.condition).toBeDefined();
expect(typeof segment.condition).toBe('object');
}); });
it('should list all segments for a project', async () => { it('should list all segments for a project', async () => {
@@ -387,7 +389,10 @@ describe('SegmentService', () => {
await expect( await expect(
SegmentService.create(projectId, { SegmentService.create(projectId, {
name: 'Invalid Segment', name: 'Invalid Segment',
filters: [], condition: {
logic: 'AND',
groups: [{filters: []}],
},
}), }),
).rejects.toThrow(/at least one filter/i); ).rejects.toThrow(/at least one filter/i);
}); });
@@ -396,13 +401,20 @@ describe('SegmentService', () => {
await expect( await expect(
SegmentService.create(projectId, { SegmentService.create(projectId, {
name: 'Invalid Segment', name: 'Invalid Segment',
filters: [ condition: {
{ logic: 'AND',
// Intentionally missing field, cast to bypass compile-time validation groups: [
operator: 'equals', {
value: 'test', filters: [
} as InvalidFilterInput as SegmentFilter, {
], // Intentionally missing field, cast to bypass compile-time validation
operator: 'equals',
value: 'test',
} as InvalidFilterInput as SegmentFilter,
],
},
],
},
}), }),
).rejects.toThrow(/field is required/i); ).rejects.toThrow(/field is required/i);
}); });
@@ -411,14 +423,21 @@ describe('SegmentService', () => {
await expect( await expect(
SegmentService.create(projectId, { SegmentService.create(projectId, {
name: 'Invalid Segment', name: 'Invalid Segment',
filters: [ condition: {
{ logic: 'AND',
field: 'email', groups: [
// Intentionally invalid operator {
operator: 'DROP TABLE contacts;', filters: [
value: 'test', {
} as InvalidFilterInput as SegmentFilter, field: 'email',
], // Intentionally invalid operator
operator: 'DROP TABLE contacts;',
value: 'test',
} as InvalidFilterInput as SegmentFilter,
],
},
],
},
}), }),
).rejects.toThrow(/invalid operator/i); ).rejects.toThrow(/invalid operator/i);
}); });
@@ -427,13 +446,20 @@ describe('SegmentService', () => {
await expect( await expect(
SegmentService.create(projectId, { SegmentService.create(projectId, {
name: 'Invalid Segment', name: 'Invalid Segment',
filters: [ condition: {
{ logic: 'AND',
field: 'email', groups: [
operator: 'equals', {
// Value intentionally omitted filters: [
} as InvalidFilterInput as SegmentFilter, {
], field: 'email',
operator: 'equals',
// Value intentionally omitted
} as InvalidFilterInput as SegmentFilter,
],
},
],
},
}), }),
).rejects.toThrow(/requires a value/i); ).rejects.toThrow(/requires a value/i);
}); });
@@ -441,13 +467,20 @@ describe('SegmentService', () => {
it('should ACCEPT valid filters', async () => { it('should ACCEPT valid filters', async () => {
const segment = await SegmentService.create(projectId, { const segment = await SegmentService.create(projectId, {
name: 'Valid Segment', name: 'Valid Segment',
filters: [ condition: {
{ logic: 'AND',
field: 'subscribed', groups: [
operator: 'equals', {
value: true, filters: [
}, {
], field: 'subscribed',
operator: 'equals',
value: true,
},
],
},
],
},
}); });
expect(segment.id).toBeDefined(); expect(segment.id).toBeDefined();
+20 -9
View File
@@ -1,15 +1,15 @@
import { import {
PrismaClient,
AuthMethod, AuthMethod,
CampaignStatus,
EmailSourceType,
EmailStatus,
Prisma,
PrismaClient,
Role, Role,
TemplateType, TemplateType,
CampaignStatus,
EmailStatus,
EmailSourceType,
WorkflowTriggerType,
WorkflowStepType,
WorkflowExecutionStatus, WorkflowExecutionStatus,
StepExecutionStatus, WorkflowStepType,
WorkflowTriggerType
} from '@plunk/db'; } from '@plunk/db';
import {getPrismaClient} from './database'; import {getPrismaClient} from './database';
import bcrypt from 'bcrypt'; import bcrypt from 'bcrypt';
@@ -513,20 +513,31 @@ export class TestFactories {
/** /**
* Create a segment * Create a segment
* Supports both old format (filters array) and new format (condition object)
*/ */
async createSegment( async createSegment(
projectId: string, projectId: string,
overrides: { overrides: {
name?: string; name?: string;
filters?: unknown; filters?: Array<{field: string; operator: string; value?: unknown; unit?: string}>;
condition?: {
logic: 'AND' | 'OR';
groups: Array<{filters: Array<{field: string; operator: string; value?: unknown; unit?: string}>}>;
};
trackMembership?: boolean; trackMembership?: boolean;
} = {}, } = {},
) { ) {
// Convert filters array to condition format if condition not provided
const condition = overrides.condition || {
logic: 'AND' as const,
groups: [{filters: overrides.filters || []}],
};
return this.prisma.segment.create({ return this.prisma.segment.create({
data: { data: {
projectId, projectId,
name: overrides.name || `Segment ${uniqueId()}`, name: overrides.name || `Segment ${uniqueId()}`,
filters: overrides.filters || [], condition: condition as unknown as Prisma.InputJsonValue,
trackMembership: overrides.trackMembership ?? false, trackMembership: overrides.trackMembership ?? false,
}, },
}); });
+1 -1
View File
@@ -33,7 +33,7 @@ export default defineConfig({
// Run tests sequentially to avoid database cleanup conflicts // Run tests sequentially to avoid database cleanup conflicts
fileParallelism: false, fileParallelism: false,
// Limit concurrent test files to reduce memory pressure // Limit concurrent test files to reduce memory pressure
maxConcurrency: 1, maxConcurrency: 3,
// Only include our test files, not dependency tests // Only include our test files, not dependency tests
include: [ include: [
'apps/**/__tests__/**/*.{test,spec}.{ts,tsx}', 'apps/**/__tests__/**/*.{test,spec}.{ts,tsx}',