UNPKG

@jungvonmatt/sb-migrate

Version:

CLI tool for managing Storyblok schema and content migrations

412 lines 16.1 kB
"use strict"; /** * @file migration-handlers.test.ts * @description Integration tests for individual migration handlers. * * This test suite focuses on testing the behavior of individual migration handlers * in isolation, ensuring that each handler correctly implements its specific * functionality and properly interacts with the Storyblok API. * * Key aspects tested: * 1. Individual handler behaviors (create, update, delete operations) * 2. Handler-specific error cases and edge conditions * 3. API interaction patterns for each handler type * 4. Data transformation and validation * * The suite is organized by handler type: * - Component Handlers: Testing component CRUD operations * - Component Group Handlers: Testing group management * - Story Handlers: Testing story content operations * - Datasource Handlers: Testing datasource and entry management * - Transform Entries Handler: Testing content transformation * * This suite complements migration-flow.test.ts by providing detailed coverage * of individual handler behaviors. While migration-flow.test.ts focuses on * end-to-end flows, this suite ensures each handler works correctly in isolation. * * @see migration-flow.test.ts for end-to-end flow testing */ Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const api_1 = require("../../utils/api"); const handlers_1 = require("../../handlers"); // Mock the external API calls vitest_1.vi.mock("../../utils/api", () => { const components = { getAll: vitest_1.vi.fn(), get: vitest_1.vi.fn(), create: vitest_1.vi.fn(), update: vitest_1.vi.fn(), delete: vitest_1.vi.fn(), }; const componentGroups = { getAll: vitest_1.vi.fn(), create: vitest_1.vi.fn(), update: vitest_1.vi.fn(), delete: vitest_1.vi.fn(), }; const stories = { getAll: vitest_1.vi.fn(), get: vitest_1.vi.fn(), getBySlug: vitest_1.vi.fn(), create: vitest_1.vi.fn(), update: vitest_1.vi.fn(), delete: vitest_1.vi.fn(), }; const datasources = { getAll: vitest_1.vi.fn(), get: vitest_1.vi.fn(), create: vitest_1.vi.fn(), update: vitest_1.vi.fn(), delete: vitest_1.vi.fn(), has: vitest_1.vi.fn(), }; const datasourceEntries = { getAll: vitest_1.vi.fn(), create: vitest_1.vi.fn(), update: vitest_1.vi.fn(), delete: vitest_1.vi.fn(), }; return { // Export the api object api: { components, componentGroups, stories, datasources, datasourceEntries, }, components, componentGroups, stories, datasources, datasourceEntries, }; }); (0, vitest_1.describe)("Integration Tests: Migration Handlers", () => { const mockComponent = { name: "test-component", display_name: "Test Component", schema: { title: { type: "text", display_name: "Title", required: true }, }, created_at: "2024-01-01T00:00:00.000Z", id: 1, }; const mockStory = { id: 1, name: "Test Story", slug: "test-story", full_slug: "test-story", content: { component: "test-component", title: "Test Title", }, created_at: "2024-01-01T00:00:00.000Z", published_at: "2024-01-01T00:00:00.000Z", }; const mockDatasource = { id: 1, name: "Test Datasource", slug: "test-datasource", dimensions: [], created_at: "2024-01-01T00:00:00.000Z", updated_at: "2024-01-01T00:00:00.000Z", }; (0, vitest_1.beforeEach)(() => { vitest_1.vi.clearAllMocks(); // Mock API responses api_1.api.components.getAll.mockResolvedValue({ data: { components: [] }, }); api_1.api.components.create.mockResolvedValue({ data: { component: mockComponent }, }); api_1.api.components.update.mockResolvedValue({ data: { component: mockComponent }, }); api_1.api.components.delete.mockResolvedValue({ data: {}, }); api_1.api.componentGroups.getAll.mockResolvedValue({ data: { component_groups: [] }, }); api_1.api.componentGroups.create.mockResolvedValue({ data: { component_group: { id: 1, name: "test-group" } }, }); api_1.api.componentGroups.update.mockResolvedValue({ data: { component_group: { id: 1, name: "test-group" } }, }); api_1.api.componentGroups.delete.mockResolvedValue({ data: {}, }); api_1.api.stories.getAll.mockResolvedValue({ data: { stories: [] }, }); api_1.api.stories.get.mockResolvedValue({ data: { story: mockStory }, }); api_1.api.stories.getBySlug.mockResolvedValue(mockStory); api_1.api.stories.create.mockResolvedValue({ data: { story: mockStory }, }); api_1.api.stories.update.mockResolvedValue({ data: { story: mockStory }, }); api_1.api.stories.delete.mockResolvedValue({ data: {}, }); api_1.api.datasources.getAll.mockResolvedValue({ data: { datasources: [] }, }); api_1.api.datasources.get.mockResolvedValue({ data: { datasource: mockDatasource }, }); api_1.api.datasources.create.mockResolvedValue({ data: { datasource: mockDatasource }, }); api_1.api.datasources.update.mockResolvedValue({ data: { datasource: mockDatasource }, }); api_1.api.datasources.delete.mockResolvedValue({ data: {}, }); }); (0, vitest_1.afterEach)(() => { vitest_1.vi.resetAllMocks(); }); (0, vitest_1.describe)("Component Handlers", () => { (0, vitest_1.it)("should handle component creation flow", async () => { await (0, handlers_1.handleCreateComponent)({ schema: { name: "test-component", display_name: "Test Component", schema: { title: { type: "text", display_name: "Title", required: true }, }, }, }, { isDryrun: false }); (0, vitest_1.expect)(api_1.api.components.create).toHaveBeenCalled(); (0, vitest_1.expect)(api_1.api.components.update).toHaveBeenCalled(); }); (0, vitest_1.it)("should handle component update flow", async () => { api_1.api.components.getAll.mockResolvedValue({ data: { components: [mockComponent] }, }); await (0, handlers_1.handleUpdateComponent)({ schema: { name: "test-component", display_name: "Updated Component", schema: { title: { type: "text", display_name: "Title", required: true }, description: { type: "text", display_name: "Description" }, }, }, }, { isDryrun: false }); (0, vitest_1.expect)(api_1.api.components.update).toHaveBeenCalled(); }); (0, vitest_1.it)("should handle component deletion flow", async () => { api_1.api.components.getAll.mockResolvedValue({ data: { components: [mockComponent] }, }); await (0, handlers_1.handleDeleteComponent)({ name: "test-component" }, { isDryrun: false }); (0, vitest_1.expect)(api_1.api.components.delete).toHaveBeenCalled(); }); }); (0, vitest_1.describe)("Component Group Handlers", () => { (0, vitest_1.it)("should handle component group creation flow", async () => { await (0, handlers_1.handleCreateComponentGroup)({ groups: [{ name: "test-group" }], }, { isDryrun: false }); (0, vitest_1.expect)(api_1.api.componentGroups.create).toHaveBeenCalled(); }); (0, vitest_1.it)("should handle component group update flow", async () => { api_1.api.componentGroups.getAll.mockResolvedValue({ data: { component_groups: [{ id: 1, name: "test-group", uuid: "123" }], }, }); await (0, handlers_1.handleUpdateComponentGroup)({ id: 1, group: { name: "updated-group" }, }, { isDryrun: false }); (0, vitest_1.expect)(api_1.api.componentGroups.update).toHaveBeenCalled(); }); (0, vitest_1.it)("should handle component group deletion flow", async () => { api_1.api.componentGroups.getAll.mockResolvedValue({ data: { component_groups: [{ id: 1, name: "test-group" }], }, }); await (0, handlers_1.handleDeleteComponentGroup)({ id: 1 }, { isDryrun: false }); (0, vitest_1.expect)(api_1.api.componentGroups.delete).toHaveBeenCalled(); }); }); (0, vitest_1.describe)("Story Handlers", () => { (0, vitest_1.it)("should handle story creation flow", async () => { await (0, handlers_1.handleCreateStory)({ story: { name: "Test Story", content: { component: "test-component", title: "Test Title", }, }, }, { isDryrun: false }); (0, vitest_1.expect)(api_1.api.stories.create).toHaveBeenCalled(); }); (0, vitest_1.it)("should handle story update flow", async () => { await (0, handlers_1.handleUpdateStory)({ id: 1, story: { name: "Updated Story", content: { component: "test-component", title: "Updated Title", }, }, }, { isDryrun: false }); (0, vitest_1.expect)(api_1.api.stories.update).toHaveBeenCalled(); }); }); (0, vitest_1.describe)("Datasource Handlers", () => { (0, vitest_1.it)("should handle datasource creation flow without errors", async () => { vitest_1.vi.clearAllMocks(); // Create a spy to track if handlers log error messages const errorSpy = vitest_1.vi.spyOn(console, "error"); api_1.api.datasources.getAll.mockResolvedValue({ data: { datasources: [] }, }); api_1.api.datasources.has.mockResolvedValue(false); api_1.api.datasources.create.mockResolvedValue({ data: { datasource: mockDatasource, }, }); api_1.api.datasourceEntries.getAll.mockResolvedValue({ data: { datasource_entries: [] }, }); api_1.api.datasourceEntries.create.mockResolvedValue({ data: { datasource_entry: { id: 1, name: "Test Entry", value: "test-value" }, }, }); await (0, handlers_1.handleCreateDatasource)({ datasource: { name: "Test Datasource", slug: "test-datasource", }, entries: [ { name: "Test Entry", value: "test-value", }, ], }, { isDryrun: false }); (0, vitest_1.expect)(errorSpy).not.toHaveBeenCalled(); }); (0, vitest_1.it)("should handle datasource update flow", async () => { await (0, handlers_1.handleUpdateDatasource)({ id: 1, datasource: { name: "Updated Datasource", }, entries: [ { name: "Updated Entry", value: "updated-value", }, ], }, { isDryrun: false }); (0, vitest_1.expect)(api_1.api.datasources.update).toHaveBeenCalled(); }); }); (0, vitest_1.describe)("Transform Entries Handler", () => { (0, vitest_1.it)("should handle transform entries flow without errors", async () => { vitest_1.vi.clearAllMocks(); const errorSpy = vitest_1.vi.spyOn(console, "error"); api_1.api.components.getAll.mockResolvedValue({ data: { components: [mockComponent] }, }); api_1.api.components.get.mockResolvedValue({ data: { component: mockComponent }, }); api_1.api.components.update.mockResolvedValue({ data: { component: mockComponent }, }); api_1.api.stories.getAll.mockResolvedValue({ data: { stories: [ { id: 1, full_slug: "test-story", content: { component: "test-component", title: "Original Title", }, }, ], }, }); api_1.api.stories.get.mockResolvedValue({ data: { story: { id: 1, full_slug: "test-story", content: { component: "test-component", title: "Original Title", }, }, }, }); api_1.api.stories.update.mockResolvedValue({ data: { story: { id: 1, full_slug: "test-story", content: { component: "test-component", title: "Transformed Title", }, }, }, }); await (0, handlers_1.handleTransformEntries)({ type: "transform-entries", component: "test-component", transform: (entry) => ({ ...entry, title: "Transformed Title", }), }, { isDryrun: false }); (0, vitest_1.expect)(errorSpy).not.toHaveBeenCalled(); }); }); (0, vitest_1.describe)("Error Handling", () => { (0, vitest_1.it)("should handle API errors gracefully in component creation", async () => { api_1.api.components.create.mockRejectedValue(new Error("API Error")); await (0, vitest_1.expect)((0, handlers_1.handleCreateComponent)({ schema: { name: "error-test", display_name: "Error Test", schema: { title: { type: "text", display_name: "Title", required: true }, }, }, }, { isDryrun: false })).rejects.toThrow("API Error"); }); (0, vitest_1.it)("should handle not found errors in component update", async () => { api_1.api.components.getAll.mockResolvedValue({ data: { components: [] }, }); await (0, vitest_1.expect)((0, handlers_1.handleUpdateComponent)({ schema: { name: "non-existent", display_name: "Non Existent", }, }, { isDryrun: false })).rejects.toThrow(); }); }); }); //# sourceMappingURL=migration-handlers.test.js.map