Skip to content

Commit

Permalink
feat(validators): add optional displayName to ComponentTreeNode [ALT-780
Browse files Browse the repository at this point in the history
] (#590)
  • Loading branch information
primeinteger authored Apr 29, 2024
1 parent 8541e97 commit 44f51b0
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 15 deletions.
1 change: 1 addition & 0 deletions packages/validators/src/schemas/v2023_09_28/experience.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const UnboundValuesSchema = z.record(
// Use helper schema to define a recursive schema with its type correctly below
const BaseComponentTreeNodeSchema = z.object({
definitionId: DefinitionPropertyKeySchema,
displayName: z.string().optional(),
variables: z.record(propertyKeySchema, ComponentPropertyValueSchema),
});
export type ComponentTreeNode = z.infer<typeof BaseComponentTreeNodeSchema> & {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export const experience = {
children: [
{
definitionId: 'contentful-container',
displayName: 'Container 1',
variables: {
cfVerticalAlignment: {
type: 'DesignValue',
Expand Down Expand Up @@ -196,6 +197,7 @@ export const experience = {
children: [
{
definitionId: 'heading',
displayName: 'Heading 1',
variables: {
text: {
type: 'UnboundValue',
Expand Down Expand Up @@ -244,6 +246,7 @@ export const experience = {
},
{
definitionId: 'button',
// Component node without optional `displayName`.
variables: {
label: {
path: '/5J8rtZN_nOJUx5YGdFuF0/fields/name/~locale',
Expand Down
57 changes: 42 additions & 15 deletions packages/validators/test/v2023_09_28/componentTree.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { validateExperienceFields } from '../../src/validators';
import { experience } from '../__fixtures__/v2023_09_28';
import { describe, it, expect } from 'vitest';
import { SafeParseError, ZodInvalidUnionIssue } from 'zod';

const schemaVersion = '2023-09-28' as const;
const locale = 'en-US';
Expand Down Expand Up @@ -183,6 +182,7 @@ describe('componentTree', () => {
expect(error?.details).toBe('The property "schemaVersion" is required here');
});
});

it(`fails if unrecognised attribute is provided`, () => {
const componentTree = experience.fields.componentTree[locale];
const updatedExperience = {
Expand Down Expand Up @@ -221,15 +221,46 @@ describe('componentTree', () => {
expect(error?.details).toBe('The type of "children" is incorrect, expected type: array');
});

it.each(['definitionId', 'variables', 'children'] as const)(
`fails if %s is missing`,
(attribute) => {
const componentTree = experience.fields.componentTree[locale];
// child includes all attributes except the one we want to test
const { [attribute]: _, ...child } = {
definitionId: 'test',
variables: {},
children: [],
};

const updatedExperience = {
...experience,
fields: {
...experience.fields,
componentTree: { [locale]: { ...componentTree, children: [child] } },
},
};
const result = validateExperienceFields(updatedExperience, schemaVersion);

const expectedError = {
name: 'required',
value: 'undefined',
path: ['componentTree', 'en-US', 'children', 0, attribute],
details: `The property "${attribute}" is required here`,
};
expect(result.success).toBe(false);
expect(result.errors).toEqual([expectedError]);
},
);

it.each([
['definitionId', 'string'],
['variables', 'object'],
['children', 'array'],
] as const)(`fails if %s is missing`, (attribute, type) => {
'Test', // displayName provided
undefined, // displayName not provided
])('succeeds if displayName is %s', (displayName) => {
const componentTree = experience.fields.componentTree[locale];
// child includes all attributes except the one we want to test
const { [attribute]: _, ...child } = {
// child includes all attributes, with displayName either provided or not
const child = {
definitionId: 'test',
displayName,
variables: {},
children: [],
};
Expand All @@ -243,14 +274,10 @@ describe('componentTree', () => {
};
const result = validateExperienceFields(updatedExperience, schemaVersion);

const expectedError = {
name: 'required',
value: 'undefined',
path: ['componentTree', 'en-US', 'children', 0, attribute],
details: `The property "${attribute}" is required here`,
};
expect(result.success).toBe(false);
expect(result.errors).toEqual([expectedError]);
// Since displayName is optional, we expect the validation to succeed
expect(result.success).toBe(true);
// And we expect no errors
expect(result.errors).toBeUndefined();
});

describe('variables name', () => {
Expand Down

0 comments on commit 44f51b0

Please sign in to comment.