UNPKG

@jungvonmatt/sb-migrate

Version:

CLI tool for managing Storyblok schema and content migrations

365 lines 15.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const storyblok_1 = require("../../utils/storyblok"); const api_1 = require("../../utils/api"); const fs_1 = __importDefault(require("fs")); // Mock the API modules vitest_1.vi.mock("../../utils/api", () => ({ components: { getAll: vitest_1.vi.fn(), }, datasources: { has: vitest_1.vi.fn(), get: vitest_1.vi.fn(), create: vitest_1.vi.fn(), }, datasourceEntries: { getAll: vitest_1.vi.fn(), create: vitest_1.vi.fn(), delete: vitest_1.vi.fn(), }, })); // Mock fs module vitest_1.vi.mock("fs", () => ({ default: { existsSync: vitest_1.vi.fn(), mkdirSync: vitest_1.vi.fn(), unlinkSync: vitest_1.vi.fn(), writeFileSync: vitest_1.vi.fn(), }, existsSync: vitest_1.vi.fn(), mkdirSync: vitest_1.vi.fn(), unlinkSync: vitest_1.vi.fn(), writeFileSync: vitest_1.vi.fn(), })); (0, vitest_1.describe)("Storyblok Utils", () => { (0, vitest_1.beforeEach)(() => { vitest_1.vi.clearAllMocks(); }); (0, vitest_1.describe)("getTranslatableComponentFields", () => { (0, vitest_1.it)("should return translatable fields for a specific component", async () => { // Arrange const mockComponents = { data: { components: [ { name: "component1", schema: { field1: { type: "text", translatable: true }, field2: { type: "text", translatable: false }, }, }, ], }, }; api_1.components.getAll.mockResolvedValue(mockComponents); // Act const result = await (0, storyblok_1.getTranslatableComponentFields)("component1"); // Assert (0, vitest_1.expect)(result).toEqual(["field1"]); }); (0, vitest_1.it)("should return empty array for non-existent component", async () => { // Arrange const mockComponents = { data: { components: [ { name: "component1", schema: { field1: { type: "text", translatable: true }, }, }, ], }, }; api_1.components.getAll.mockResolvedValue(mockComponents); // Act const result = await (0, storyblok_1.getTranslatableComponentFields)("nonExistent"); // Assert (0, vitest_1.expect)(result).toEqual([]); }); }); (0, vitest_1.describe)("addOrUpdateDatasource", () => { (0, vitest_1.it)("should create new datasource if it doesn't exist", async () => { // Arrange const mockDatasource = { id: 123, name: "test", slug: "test", dimensions: [], created_at: "2024-03-20T00:00:00.000Z", updated_at: "2024-03-20T00:00:00.000Z", }; api_1.datasources.has.mockResolvedValue(false); api_1.datasources.create.mockResolvedValue({ data: { datasource: mockDatasource }, }); api_1.datasourceEntries.getAll.mockResolvedValue({ data: { datasource_entries: [] }, }); api_1.datasourceEntries.create.mockResolvedValue({ data: { datasource: { id: 456 } }, }); // Act const [datasource, entries] = await (0, storyblok_1.addOrUpdateDatasource)("test", [ { name: "entry1", value: "value1" }, ]); // Assert (0, vitest_1.expect)(datasource).toEqual(mockDatasource); (0, vitest_1.expect)(entries).toHaveLength(1); (0, vitest_1.expect)(api_1.datasources.create).toHaveBeenCalledWith({ slug: "test", name: "test", }); }); (0, vitest_1.it)("should update existing datasource", async () => { // Arrange const mockDatasource = { id: 123, name: "test", slug: "test", dimensions: [], created_at: "2024-03-20T00:00:00.000Z", updated_at: "2024-03-20T00:00:00.000Z", }; const mockEntry = { id: 456, name: "entry1", value: "value1", }; api_1.datasources.has.mockResolvedValue(true); api_1.datasources.get.mockResolvedValue({ data: { datasource: mockDatasource }, }); api_1.datasourceEntries.getAll.mockResolvedValue({ data: { datasource_entries: [mockEntry] }, }); // Act const [datasource, entries] = await (0, storyblok_1.addOrUpdateDatasource)("test", [ { name: "entry1", value: "value1" }, ]); // Assert (0, vitest_1.expect)(datasource).toEqual(mockDatasource); (0, vitest_1.expect)(entries).toHaveLength(1); (0, vitest_1.expect)(api_1.datasources.get).toHaveBeenCalledWith("test"); }); }); (0, vitest_1.describe)("Tab Management Functions", () => { const mockComponent = { name: "test", id: 123, created_at: "2024-03-20T00:00:00.000Z", schema: { "tab-content": { type: "tab", display_name: "Content", keys: ["field1", "field2"], }, "tab-settings": { type: "tab", display_name: "Settings", keys: ["field3"], }, }, }; (0, vitest_1.describe)("resetTab", () => { (0, vitest_1.it)("should reset keys in an existing tab", () => { // Act const result = (0, storyblok_1.resetTab)(mockComponent, "Content"); // Assert const tab = result?.schema?.["tab-content"]; (0, vitest_1.expect)(tab.keys).toEqual([]); }); (0, vitest_1.it)("should create new tab if it doesn't exist", () => { // Act const result = (0, storyblok_1.resetTab)(mockComponent, "New Tab"); // Assert const tab = result?.schema?.["tab-New Tab"]; (0, vitest_1.expect)(tab).toBeDefined(); (0, vitest_1.expect)(tab.keys).toEqual([]); }); }); (0, vitest_1.describe)("moveToTab", () => { (0, vitest_1.it)("should move fields to an existing tab", () => { // Act const result = (0, storyblok_1.moveToTab)(mockComponent, "Content", [ "field4", "field5", ]); // Assert const tab = result?.schema?.["tab-content"]; (0, vitest_1.expect)(tab.keys).toEqual(["field4", "field5"]); }); (0, vitest_1.it)("should create new tab if it doesn't exist", () => { // Act const result = (0, storyblok_1.moveToTab)(mockComponent, "New Tab", [ "field4", "field5", ]); // Assert const tab = result?.schema?.["tab-New Tab"]; (0, vitest_1.expect)(tab).toBeDefined(); (0, vitest_1.expect)(tab.keys).toEqual(["field4", "field5"]); }); }); (0, vitest_1.describe)("getDeprecatedTab", () => { (0, vitest_1.it)("should return existing deprecated tab", () => { const componentWithDeprecated = { ...mockComponent, schema: { ...mockComponent.schema, "tab-deprecated": { type: "tab", display_name: "Deprecated", keys: ["oldField"], }, }, }; // Act const [key, tab] = (0, storyblok_1.getDeprecatedTab)(componentWithDeprecated); // Assert (0, vitest_1.expect)(key).toBe("tab-deprecated"); (0, vitest_1.expect)(tab.display_name).toBe("Deprecated"); }); (0, vitest_1.it)("should create new deprecated tab if it doesn't exist", () => { // Act const [key, tab] = (0, storyblok_1.getDeprecatedTab)(mockComponent); // Assert (0, vitest_1.expect)(key).toBe("tab-deprecated"); (0, vitest_1.expect)(tab.display_name).toBe("deprecated"); }); }); (0, vitest_1.describe)("moveToDeprecated", () => { (0, vitest_1.it)("should move fields to deprecated tab", () => { // Act const result = (0, storyblok_1.moveToDeprecated)(mockComponent, [ "oldField1", "oldField2", ]); // Assert const tab = result?.schema?.["tab-deprecated"]; (0, vitest_1.expect)(tab.keys).toEqual(["oldField1", "oldField2"]); }); }); (0, vitest_1.describe)("moveToSettings", () => { (0, vitest_1.it)("should move fields to settings tab", () => { // Act const result = (0, storyblok_1.moveToSettings)(mockComponent, ["setting1", "setting2"]); // Assert const tab = result?.schema?.["tab-settings"]; (0, vitest_1.expect)(tab.keys).toEqual(["setting1", "setting2"]); }); }); }); (0, vitest_1.describe)("addOrUpdateFields", () => { (0, vitest_1.it)("should add new fields to component schema", () => { // Arrange const component = { name: "test", id: 123, created_at: "2024-03-20T00:00:00.000Z", schema: { field1: { type: "text", display_name: "Field 1" }, }, }; const newFields = { field2: { type: "text", display_name: "Field 2" }, field3: { type: "text", display_name: "Field 3" }, }; // Act const result = (0, storyblok_1.addOrUpdateFields)(component, newFields); // Assert (0, vitest_1.expect)(result.schema).toEqual({ ...newFields, ...component.schema, ...newFields, }); }); }); (0, vitest_1.describe)("createRollbackFile", () => { (0, vitest_1.it)("should create rollback file with correct data", async () => { // Arrange const rollbackData = [{ id: 1, name: "test" }]; const mockDate = "2024-03-20"; vitest_1.vi.spyOn(Date.prototype, "toISOString").mockReturnValue(`${mockDate}T00:00:00.000Z`); fs_1.default.existsSync.mockReturnValue(false); // Act const result = await (0, storyblok_1.createRollbackFile)(rollbackData, "test", "field"); // Assert (0, vitest_1.expect)(result).toEqual({ component: "test", created: true }); (0, vitest_1.expect)(fs_1.default.mkdirSync).toHaveBeenCalledWith(vitest_1.expect.stringContaining("migrations/rollback"), { recursive: true }); (0, vitest_1.expect)(fs_1.default.writeFileSync).toHaveBeenCalledWith(vitest_1.expect.stringContaining(`${mockDate}_rollback_test_field.json`), JSON.stringify(rollbackData, null, 2)); }); (0, vitest_1.it)("should handle existing rollback file", async () => { // Arrange const rollbackData = [{ id: 1, name: "test" }]; fs_1.default.existsSync.mockReturnValue(true); // Act const result = await (0, storyblok_1.createRollbackFile)(rollbackData, "test", "field"); // Assert (0, vitest_1.expect)(result).toEqual({ component: "test", created: true }); (0, vitest_1.expect)(fs_1.default.unlinkSync).toHaveBeenCalled(); }); }); (0, vitest_1.describe)("processMigration", () => { (0, vitest_1.it)("should process matching component", async () => { // Arrange const content = { component: "test", field1: "value1", }; const migrationFn = vitest_1.vi.fn(); // Act await (0, storyblok_1.processMigration)(content, "test", migrationFn, "test-story"); // Assert (0, vitest_1.expect)(migrationFn).toHaveBeenCalledWith(content); }); (0, vitest_1.it)("should process nested components", async () => { // Arrange const content = { component: "parent", blocks: [ { component: "test", field1: "value1", }, ], }; const migrationFn = vitest_1.vi.fn(); // Act await (0, storyblok_1.processMigration)(content, "test", migrationFn, "test-story"); // Assert (0, vitest_1.expect)(migrationFn).toHaveBeenCalledWith(content.blocks[0]); }); (0, vitest_1.it)("should process rich text bloks", async () => { // Arrange const content = { component: "parent", content: { type: "doc", content: [ { type: "blok", attrs: { body: { component: "test", field1: "value1", }, }, }, ], }, }; const migrationFn = vitest_1.vi.fn(); // Act await (0, storyblok_1.processMigration)(content, "test", migrationFn, "test-story"); // Assert (0, vitest_1.expect)(migrationFn).toHaveBeenCalledWith(content.content.content[0].attrs.body); }); }); }); //# sourceMappingURL=storyblok.test.js.map