Skip to content

Commit 355baba

Browse files
authored
Add ActivityMetadata to Campaign entity (safe-global#1546)
Adds ActivityMetadata entity and validation schema. Adds activities array to the Campaign entity.
1 parent 2c0d935 commit 355baba

File tree

5 files changed

+107
-1
lines changed

5 files changed

+107
-1
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { Builder, IBuilder } from '@/__tests__/builder';
2+
import { ActivityMetadata } from '@/domain/locking/entities/activity-metadata.entity';
3+
import { faker } from '@faker-js/faker';
4+
5+
export function activityMetadataBuilder(): IBuilder<ActivityMetadata> {
6+
return new Builder<ActivityMetadata>()
7+
.with('campaignId', faker.string.uuid())
8+
.with('name', faker.word.words())
9+
.with('description', faker.lorem.sentence())
10+
.with('maxPoints', faker.string.numeric());
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { NumericStringSchema } from '@/validation/entities/schemas/numeric-string.schema';
2+
import { z } from 'zod';
3+
4+
export type ActivityMetadata = z.infer<typeof ActivityMetadataSchema>;
5+
6+
export const ActivityMetadataSchema = z.object({
7+
campaignId: z.string(),
8+
name: z.string(),
9+
description: z.string(),
10+
maxPoints: NumericStringSchema,
11+
});

src/domain/locking/entities/campaign.entity.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ActivityMetadataSchema } from '@/domain/locking/entities/activity-metadata.entity';
12
import { z } from 'zod';
23

34
export type Campaign = z.infer<typeof CampaignSchema>;
@@ -9,5 +10,5 @@ export const CampaignSchema = z.object({
910
periodStart: z.coerce.date(),
1011
periodEnd: z.coerce.date(),
1112
lastUpdated: z.coerce.date(),
12-
// TODO: include 'activities' field once the structure is defined.
13+
activities: z.array(ActivityMetadataSchema).nullish().default(null),
1314
});
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { activityMetadataBuilder } from '@/domain/locking/entities/__tests__/activity-metadata.builder';
2+
import { ActivityMetadataSchema } from '@/domain/locking/entities/activity-metadata.entity';
3+
import { faker } from '@faker-js/faker';
4+
import { ZodError } from 'zod';
5+
6+
describe('ActivityMetadataSchema', () => {
7+
it('should validate a valid activity metadata', () => {
8+
const activityMetadata = activityMetadataBuilder().build();
9+
10+
const result = ActivityMetadataSchema.safeParse(activityMetadata);
11+
12+
expect(result.success).toBe(true);
13+
});
14+
15+
it('should not allow a non-numeric string for maxPoints', () => {
16+
const activityMetadata = activityMetadataBuilder()
17+
.with('maxPoints', faker.string.alpha())
18+
.build();
19+
20+
const result = ActivityMetadataSchema.safeParse(activityMetadata);
21+
22+
expect(!result.success && result.error).toStrictEqual(
23+
new ZodError([
24+
{
25+
code: 'custom',
26+
message: 'Invalid base-10 numeric string',
27+
path: ['maxPoints'],
28+
},
29+
]),
30+
);
31+
});
32+
33+
it('should not validate an invalid activity metadata', () => {
34+
const activityMetadata = { invalid: 'activity metadata' };
35+
36+
const result = ActivityMetadataSchema.safeParse(activityMetadata);
37+
38+
expect(!result.success && result.error).toStrictEqual(
39+
new ZodError([
40+
{
41+
code: 'invalid_type',
42+
expected: 'string',
43+
received: 'undefined',
44+
path: ['campaignId'],
45+
message: 'Required',
46+
},
47+
{
48+
code: 'invalid_type',
49+
expected: 'string',
50+
received: 'undefined',
51+
path: ['name'],
52+
message: 'Required',
53+
},
54+
{
55+
code: 'invalid_type',
56+
expected: 'string',
57+
received: 'undefined',
58+
path: ['description'],
59+
message: 'Required',
60+
},
61+
{
62+
code: 'invalid_type',
63+
expected: 'string',
64+
received: 'undefined',
65+
path: ['maxPoints'],
66+
message: 'Required',
67+
},
68+
]),
69+
);
70+
});
71+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { ActivityMetadataSchema } from '@/domain/locking/entities/activity-metadata.entity';
2+
import { z } from 'zod';
3+
4+
export const CampaignSchema = z.object({
5+
campaignId: z.string(),
6+
name: z.string(),
7+
description: z.string(),
8+
periodStart: z.coerce.date(),
9+
periodEnd: z.coerce.date(),
10+
lastUpdated: z.coerce.date(),
11+
activities: z.array(ActivityMetadataSchema).nullish().default(null),
12+
});

0 commit comments

Comments
 (0)