Skip to content

Commit fc81ab4

Browse files
committed
feat: unit tests
1 parent 4125a48 commit fc81ab4

File tree

3 files changed

+386
-4
lines changed

3 files changed

+386
-4
lines changed

src/types/strapi.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export interface StrapiComponent {
4343
description: string;
4444
icon: string;
4545
collectionName: string;
46-
attributes: Array<StrapiAttribute>;
46+
attributes: Record<string, StrapiAttribute>;
4747
}
4848
}
4949

src/utils/__tests__/schema.test.ts

Lines changed: 194 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { StrapiSchemaGenerator } from "../schema";
2-
import type { StrapiContentType } from "../../types/strapi";
2+
import type { StrapiContentType, StrapiComponent } from "../../types/strapi";
33

44
describe("StrapiSchemaGenerator", () => {
55
const mockContentType: StrapiContentType = {
@@ -28,14 +28,73 @@ describe("StrapiSchemaGenerator", () => {
2828
type: "uid",
2929
targetField: "title",
3030
},
31+
hero: {
32+
type: "component",
33+
repeatable: false,
34+
component: "layout.hero",
35+
},
36+
testimonials: {
37+
type: "component",
38+
repeatable: true,
39+
component: "content.testimonial",
40+
},
3141
},
3242
},
3343
};
3444

45+
const mockComponents: Array<StrapiComponent> = [
46+
{
47+
uid: "layout.hero",
48+
category: "layout",
49+
apiId: "hero",
50+
schema: {
51+
displayName: "Hero",
52+
description: "Hero section component",
53+
icon: "star",
54+
collectionName: "components_layout_heroes",
55+
attributes: {
56+
title: {
57+
type: "string",
58+
required: true,
59+
},
60+
description: {
61+
type: "text",
62+
required: false,
63+
},
64+
},
65+
},
66+
},
67+
{
68+
uid: "content.testimonial",
69+
category: "content",
70+
apiId: "testimonial",
71+
schema: {
72+
displayName: "Testimonial",
73+
description: "Customer testimonial",
74+
icon: "quote",
75+
collectionName: "components_content_testimonials",
76+
attributes: {
77+
name: {
78+
type: "string",
79+
required: true,
80+
},
81+
content: {
82+
type: "string",
83+
required: true,
84+
},
85+
rating: {
86+
type: "integer",
87+
required: false,
88+
},
89+
},
90+
},
91+
},
92+
];
93+
3594
let generator: StrapiSchemaGenerator;
3695

3796
beforeEach(() => {
38-
generator = new StrapiSchemaGenerator([mockContentType], []);
97+
generator = new StrapiSchemaGenerator([mockContentType], mockComponents);
3998
});
4099

41100
describe("generateSchema", () => {
@@ -61,4 +120,137 @@ describe("StrapiSchemaGenerator", () => {
61120
expect(schemas["articles"].shape).toHaveProperty("title");
62121
});
63122
});
123+
124+
describe("component handling", () => {
125+
it("should generate schema for non-repeatable component", () => {
126+
const schema = generator.generateSchema("article");
127+
expect(schema.shape).toHaveProperty("hero");
128+
129+
// Test that component schema is generated correctly
130+
const heroField = schema.shape.hero;
131+
expect(heroField).toBeDefined();
132+
});
133+
134+
it("should generate schema for repeatable component", () => {
135+
const schema = generator.generateSchema("article");
136+
expect(schema.shape).toHaveProperty("testimonials");
137+
138+
// Test that repeatable component schema is an array
139+
const testimonialsField = schema.shape.testimonials;
140+
expect(testimonialsField).toBeDefined();
141+
});
142+
143+
it("should ignore missing component and log warning", () => {
144+
const contentTypeWithMissingComponent: StrapiContentType = {
145+
apiID: "test",
146+
uid: "api::test.test",
147+
plugin: undefined,
148+
schema: {
149+
uid: "api::test.test",
150+
kind: "collectionType",
151+
collectionName: "tests",
152+
singularName: "test",
153+
pluralName: "tests",
154+
displayName: "Test",
155+
draftAndPublish: true,
156+
pluginOptions: {},
157+
visible: true,
158+
attributes: {
159+
title: {
160+
type: "string",
161+
required: true,
162+
},
163+
missingComponent: {
164+
type: "component",
165+
repeatable: false,
166+
component: "missing.component",
167+
},
168+
},
169+
},
170+
};
171+
172+
const testGenerator = new StrapiSchemaGenerator([contentTypeWithMissingComponent], mockComponents);
173+
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
174+
175+
const schema = testGenerator.generateSchema("test");
176+
177+
// Schema should be generated successfully without the missing component
178+
expect(schema).toBeDefined();
179+
expect(schema.shape).toHaveProperty("title");
180+
expect(schema.shape).not.toHaveProperty("missingComponent");
181+
182+
// Warning should be logged
183+
expect(consoleSpy).toHaveBeenCalledWith(
184+
"Error generating attribute schema",
185+
expect.any(Error)
186+
);
187+
188+
consoleSpy.mockRestore();
189+
});
190+
191+
it("should ignore component type without component name and log warning", () => {
192+
const contentTypeWithInvalidComponent: StrapiContentType = {
193+
apiID: "test",
194+
uid: "api::test.test",
195+
plugin: undefined,
196+
schema: {
197+
uid: "api::test.test",
198+
kind: "collectionType",
199+
collectionName: "tests",
200+
singularName: "test",
201+
pluralName: "tests",
202+
displayName: "Test",
203+
draftAndPublish: true,
204+
pluginOptions: {},
205+
visible: true,
206+
attributes: {
207+
title: {
208+
type: "string",
209+
required: true,
210+
},
211+
invalidComponent: {
212+
type: "component",
213+
repeatable: false,
214+
// missing component property
215+
},
216+
},
217+
},
218+
};
219+
220+
const testGenerator = new StrapiSchemaGenerator([contentTypeWithInvalidComponent], mockComponents);
221+
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
222+
223+
const schema = testGenerator.generateSchema("test");
224+
225+
// Schema should be generated successfully without the invalid component
226+
expect(schema).toBeDefined();
227+
expect(schema.shape).toHaveProperty("title");
228+
expect(schema.shape).not.toHaveProperty("invalidComponent");
229+
230+
// Warning should be logged
231+
expect(consoleSpy).toHaveBeenCalledWith(
232+
"Error generating attribute schema",
233+
expect.any(Error)
234+
);
235+
236+
consoleSpy.mockRestore();
237+
});
238+
});
239+
240+
describe("constructor with components", () => {
241+
it("should initialize with empty components array", () => {
242+
const generatorWithEmptyComponents = new StrapiSchemaGenerator([mockContentType], []);
243+
expect(generatorWithEmptyComponents).toBeDefined();
244+
});
245+
246+
it("should initialize with components array", () => {
247+
const generatorWithComponents = new StrapiSchemaGenerator([mockContentType], mockComponents);
248+
expect(generatorWithComponents).toBeDefined();
249+
});
250+
251+
it("should handle strict mode with components", () => {
252+
const strictGenerator = new StrapiSchemaGenerator([mockContentType], mockComponents, true);
253+
expect(strictGenerator).toBeDefined();
254+
});
255+
});
64256
});

0 commit comments

Comments
 (0)