diff --git a/packages/backend/src/controllers/api/v1/apps/get-action-substeps.js b/packages/backend/src/controllers/api/v1/apps/get-action-substeps.js new file mode 100644 index 00000000..6b985bdc --- /dev/null +++ b/packages/backend/src/controllers/api/v1/apps/get-action-substeps.js @@ -0,0 +1,11 @@ +import App from '../../../../models/app.js'; +import { renderObject } from '../../../../helpers/renderer.js'; + +export default async (request, response) => { + const substeps = await App.findActionSubsteps( + request.params.appKey, + request.params.actionKey + ); + + renderObject(response, substeps); +}; diff --git a/packages/backend/src/controllers/api/v1/apps/get-action-substeps.test.js b/packages/backend/src/controllers/api/v1/apps/get-action-substeps.test.js new file mode 100644 index 00000000..44676d9e --- /dev/null +++ b/packages/backend/src/controllers/api/v1/apps/get-action-substeps.test.js @@ -0,0 +1,52 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import request from 'supertest'; +import App from '../../../../models/app'; +import app from '../../../../app.js'; +import createAuthTokenByUserId from '../../../../helpers/create-auth-token-by-user-id'; +import { createUser } from '../../../../../test/factories/user'; +import getActionSubstepsMock from '../../../../../test/mocks/rest/api/v1/apps/get-action-substeps.js'; + +describe('GET /api/v1/apps/:appKey/actions/:actionKey/substeps', () => { + let currentUser, exampleApp, token; + + beforeEach(async () => { + currentUser = await createUser(); + token = createAuthTokenByUserId(currentUser.id); + exampleApp = await App.findOneByKey('github'); + }); + + it('should return the app auth info', async () => { + const actions = await App.findActionsByKey('github'); + const exampleAction = actions.find( + (action) => action.key === 'createIssue' + ); + + const endpointUrl = `/api/v1/apps/${exampleApp.key}/actions/${exampleAction.key}/substeps`; + + const response = await request(app) + .get(endpointUrl) + .set('Authorization', token) + .expect(200); + + const expectedPayload = getActionSubstepsMock(exampleAction.substeps); + expect(response.body).toEqual(expectedPayload); + }); + + it('should return not found response for invalid app key', async () => { + await request(app) + .get('/api/v1/apps/invalid-app-key/actions/invalid-actions-key/substeps') + .set('Authorization', token) + .expect(404); + }); + + it('should return empty array for invalid action key', async () => { + const endpointUrl = `/api/v1/apps/${exampleApp.key}/actions/invalid-action-key/substeps`; + + const response = await request(app) + .get(endpointUrl) + .set('Authorization', token) + .expect(200); + + expect(response.body.data).toEqual([]); + }); +}); diff --git a/packages/backend/src/routes/api/v1/apps.js b/packages/backend/src/routes/api/v1/apps.js index 399cd71c..0167032e 100644 --- a/packages/backend/src/routes/api/v1/apps.js +++ b/packages/backend/src/routes/api/v1/apps.js @@ -7,6 +7,7 @@ import getAuthAction from '../../../controllers/api/v1/apps/get-auth.js'; import getTriggersAction from '../../../controllers/api/v1/apps/get-triggers.js'; import getTriggerSubstepsAction from '../../../controllers/api/v1/apps/get-trigger-substeps.js'; import getActionsAction from '../../../controllers/api/v1/apps/get-actions.js'; +import getActionSubstepsAction from '../../../controllers/api/v1/apps/get-action-substeps.js'; const router = Router(); @@ -32,4 +33,10 @@ router.get( asyncHandler(getActionsAction) ); +router.get( + '/:appKey/actions/:actionKey/substeps', + authenticateUser, + asyncHandler(getActionSubstepsAction) +); + export default router; diff --git a/packages/backend/test/mocks/rest/api/v1/apps/get-action-substeps.js b/packages/backend/test/mocks/rest/api/v1/apps/get-action-substeps.js new file mode 100644 index 00000000..29c5f5be --- /dev/null +++ b/packages/backend/test/mocks/rest/api/v1/apps/get-action-substeps.js @@ -0,0 +1,14 @@ +const getActionSubstepsMock = (substeps) => { + return { + data: substeps, + meta: { + count: substeps.length, + currentPage: null, + isArray: true, + totalPages: null, + type: 'Object', + }, + }; +}; + +export default getActionSubstepsMock;