From 7819baa83124a4e0cdf40e33e55803a64a1b6282 Mon Sep 17 00:00:00 2001 From: Josh Wulf Date: Thu, 24 Oct 2024 16:04:25 -0500 Subject: [PATCH] fix(modeler): correct HTTP methods for file methods. fixes #269 --- .../modeler/modeler-integration.spec.ts | 158 ++++++++++++++++-- src/modeler/lib/ModelerAPIClient.ts | 36 ++-- src/modeler/lib/ModelerDto.ts | 9 +- 3 files changed, 169 insertions(+), 34 deletions(-) diff --git a/src/__tests__/modeler/modeler-integration.spec.ts b/src/__tests__/modeler/modeler-integration.spec.ts index 2bf334a2..43f58022 100644 --- a/src/__tests__/modeler/modeler-integration.spec.ts +++ b/src/__tests__/modeler/modeler-integration.spec.ts @@ -1,19 +1,149 @@ -import { ModelerApiClient } from '../../modeler/index' +import fs from 'fs' -test('It can get info', async () => { - const modeler = new ModelerApiClient() +import { ModelerApiClient } from '../../modeler' - const res = await modeler.getInfo() - expect(res.version).toBe('v1') -}) +describe('ModelerApiClient', () => { + let modeler: ModelerApiClient + + beforeAll(() => { + modeler = new ModelerApiClient() + }) + + afterAll(async () => { + // Cleanup any remaining test data + const existingProjects = await modeler.searchProjects({ + filter: { name: '__test__' }, + }) + for (const project of existingProjects.items) { + const projectData = await modeler.getProject(project.id) + for (const file of projectData.content.files) { + await modeler.deleteFile(file.id) + } + for (const folder of projectData.content.folders) { + await modeler.deleteFolder(folder.id) + } + await modeler.deleteProject(project.id) + } + }) + + describe('createProject', () => { + it('should create a new project', async () => { + const projectResponse = await modeler.createProject('__test__') + expect(projectResponse.name).toBe('__test__') + }) + }) + + describe('getProject', () => { + it('should retrieve an existing project', async () => { + const projectResponse = await modeler.createProject('__test__') + const retrievedProject = await modeler.getProject(projectResponse.id) + expect(retrievedProject.metadata.name).toBe('__test__') + }) + + it('should throw an error if the project does not exist', async () => { + await expect(modeler.getProject('non-existent-id')).rejects.toThrow() + }) + }) + + describe('updateProject', () => { + it('should update an existing project', async () => { + const projectResponse = await modeler.createProject('__test__') + const updatedProject = await modeler.renameProject( + projectResponse.id, + '__test__ updated' + ) + expect(updatedProject.name).toBe('__test__ updated') + }) + + it('should throw an error if the project does not exist', async () => { + await expect( + modeler.renameProject('non-existent-id', 'Updated name') + ).rejects.toThrow() + }) + }) + + describe('deleteProject', () => { + it('should delete an existing project', async () => { + const projectResponse = await modeler.createProject('__test__') + await modeler.deleteProject(projectResponse.id) + await expect(modeler.getProject(projectResponse.id)).rejects.toThrow() + }) + + it('should throw an error if the project does not exist', async () => { + await expect(modeler.deleteProject('non-existent-id')).rejects.toThrow() + }) + }) + + describe('searchProjects', () => { + it('should return a list of projects matching the filter', async () => { + await modeler.createProject('__test__') + const searchResponse = await modeler.searchProjects({ + filter: { name: '__test__' }, + }) + expect(searchResponse.items.length).toBeGreaterThan(0) + expect(searchResponse.items[0].name).toBe('__test__') + }) + + it('should return an empty list if no projects match the filter', async () => { + const searchResponse = await modeler.searchProjects({ + filter: { name: 'non-existent-project' }, + }) + expect(searchResponse.items.length).toBe(0) + }) + }) + + describe('createFolder', () => { + it('should create a new folder in an existing project', async () => { + const projectResponse = await modeler.createProject('__test__') + const folderResponse = await modeler.createFolder({ + projectId: projectResponse.id, + name: 'Test Folder', + }) + expect(folderResponse.name).toBe('Test Folder') + }) + + it('should throw an error if the project does not exist', async () => { + await expect( + modeler.createFolder({ + projectId: 'non-existent-project-id', + name: 'Test Folder', + }) + ).rejects.toThrow() + }) + }) -test('Can create project', async () => { - const modeler = new ModelerApiClient() + describe('createFile', () => { + it('should create a new file in an existing folder', async () => { + const projectResponse = await modeler.createProject('__test__') + const folderResponse = await modeler.createFolder({ + projectId: projectResponse.id, + name: 'Test Folder', + }) + const fileResponse = await modeler.createFile({ + folderId: folderResponse.id, + projectId: projectResponse.id, + name: 'Test File', + content: fs.readFileSync( + './src/__tests__/testdata/generic-test.bpmn', + 'utf-8' + ), + fileType: 'bpmn', + }) + expect(fileResponse.name).toBe('Test File') + }) - let res - res = await modeler.searchProjects({ filter: { name: '__test__' } }) - if (res.items.length === 0) { - res = await modeler.createProject('__test__') - } - expect(res).toBeTruthy() + it('should throw an error if the folder does not exist', async () => { + await expect( + modeler.createFile({ + folderId: 'non-existent-folder-id', + name: 'Test File', + content: fs.readFileSync( + './src/__tests__/testdata/generic-test.bpmn', + 'utf-8' + ), + fileType: 'bpmn', + }) + ).rejects.toThrow() + }) + }) }) diff --git a/src/modeler/lib/ModelerAPIClient.ts b/src/modeler/lib/ModelerAPIClient.ts index a5c0d103..1715ac74 100644 --- a/src/modeler/lib/ModelerAPIClient.ts +++ b/src/modeler/lib/ModelerAPIClient.ts @@ -213,9 +213,11 @@ export class ModelerApiClient { async deleteFile(fileId: string): Promise { const headers = await this.getHeaders() const rest = await this.rest - return rest(`files/${fileId}`, { - headers, - }).then(this.decodeResponseOrThrow) as Promise + return rest + .delete(`files/${fileId}`, { + headers, + }) + .then(this.decodeResponseOrThrow) as Promise } /** @@ -241,12 +243,14 @@ export class ModelerApiClient { ): Promise { const headers = await this.getHeaders() const rest = await this.rest - return rest(`files/${fileId}`, { - headers, - body: JSON.stringify(update), - }).then((res) => - JSON.parse(this.decodeResponseOrThrow(res)) - ) as Promise + return rest + .patch(`files/${fileId}`, { + headers, + body: JSON.stringify(update), + }) + .then((res) => + JSON.parse(this.decodeResponseOrThrow(res)) + ) as Promise } /** @@ -280,12 +284,14 @@ export class ModelerApiClient { ): Promise { const headers = await this.getHeaders() const rest = await this.rest - return rest(`files/search`, { - headers, - body: JSON.stringify(req), - }).then((res) => - JSON.parse(this.decodeResponseOrThrow(res)) - ) as Promise + return rest + .post(`files/search`, { + headers, + body: JSON.stringify(req), + }) + .then((res) => + JSON.parse(this.decodeResponseOrThrow(res)) + ) as Promise } /** diff --git a/src/modeler/lib/ModelerDto.ts b/src/modeler/lib/ModelerDto.ts index a402f2a5..d9c2d1f6 100644 --- a/src/modeler/lib/ModelerDto.ts +++ b/src/modeler/lib/ModelerDto.ts @@ -43,12 +43,11 @@ export interface CreateFileDto { /** maxLength: 255, minLength: 1 */ name: string /** maxLength: 255, minLength: 1 */ - folderId: string + folderId?: string /** maxLength: 255, minLength: 1 */ - projectId: string + projectId?: string content: string - fileType: string - pattern: 'bpmn' | 'dmn' | 'form' | 'connector_template' + fileType: 'bpmn' | 'dmn' | 'form' | 'connector_template' } export interface PathElementDto { @@ -112,7 +111,7 @@ export interface CreateFolderDto { /** maxLength: 255 minLength: 1 */ projectId: string /** maxLength: 255 minLength: 1 */ - parentId: string + parentId?: string } export interface FolderMetadataDto {