diff --git a/packages/backend/src/controllers/api/v1/apps/get-auth.test.js b/packages/backend/src/controllers/api/v1/apps/get-auth.test.js index b846e607..5955ef21 100644 --- a/packages/backend/src/controllers/api/v1/apps/get-auth.test.js +++ b/packages/backend/src/controllers/api/v1/apps/get-auth.test.js @@ -28,7 +28,7 @@ describe('GET /api/v1/apps/:appKey/auth', () => { it('should return not found response for invalid app key', async () => { await request(app) - .get('/api/v1/apps/invalid-app-key') + .get('/api/v1/apps/invalid-app-key/auth') .set('Authorization', token) .expect(404); }); diff --git a/packages/backend/src/controllers/api/v1/apps/get-trigger-substeps.js b/packages/backend/src/controllers/api/v1/apps/get-trigger-substeps.js new file mode 100644 index 00000000..96e542f4 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/apps/get-trigger-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.findTriggerSubsteps( + request.params.appKey, + request.params.triggerKey + ); + + renderObject(response, substeps); +}; diff --git a/packages/backend/src/controllers/api/v1/apps/get-trigger-substeps.test.js b/packages/backend/src/controllers/api/v1/apps/get-trigger-substeps.test.js new file mode 100644 index 00000000..9dc2cfb0 --- /dev/null +++ b/packages/backend/src/controllers/api/v1/apps/get-trigger-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 getTriggerSubstepsMock from '../../../../../test/mocks/rest/api/v1/apps/get-trigger-substeps.js'; + +describe('GET /api/v1/apps/:appKey/triggers/:triggerKey/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 triggers = await App.findTriggersByKey('github'); + const exampleTrigger = triggers.find( + (trigger) => trigger.key === 'newIssues' + ); + + const endpointUrl = `/api/v1/apps/${exampleApp.key}/triggers/${exampleTrigger.key}/substeps`; + + const response = await request(app) + .get(endpointUrl) + .set('Authorization', token) + .expect(200); + + const expectedPayload = getTriggerSubstepsMock(exampleTrigger.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/triggers/invalid-trigger-key/substeps') + .set('Authorization', token) + .expect(404); + }); + + it('should return empty array for invalid trigger key', async () => { + const endpointUrl = `/api/v1/apps/${exampleApp.key}/triggers/invalid-trigger-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/models/app.js b/packages/backend/src/models/app.js index ccd71c09..b53c347c 100644 --- a/packages/backend/src/models/app.js +++ b/packages/backend/src/models/app.js @@ -53,6 +53,17 @@ class App { return appData?.triggers || []; } + static async findTriggerSubsteps(appKey, triggerKey, stripFuncs = false) { + const rawAppData = await getApp(appKey, stripFuncs); + const appData = appInfoConverter(rawAppData); + + const trigger = appData?.triggers?.find( + (trigger) => trigger.key === triggerKey + ); + + return trigger?.substeps || []; + } + static async checkAppAndAction(appKey, actionKey) { const app = await this.findOneByKey(appKey); diff --git a/packages/backend/src/routes/api/v1/apps.js b/packages/backend/src/routes/api/v1/apps.js index fd681426..82da4e65 100644 --- a/packages/backend/src/routes/api/v1/apps.js +++ b/packages/backend/src/routes/api/v1/apps.js @@ -5,6 +5,7 @@ import getAppAction from '../../../controllers/api/v1/apps/get-app.js'; import getAppsAction from '../../../controllers/api/v1/apps/get-apps.js'; 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'; const router = Router(); @@ -18,4 +19,10 @@ router.get( asyncHandler(getTriggersAction) ); +router.get( + '/:appKey/triggers/:triggerKey/substeps', + authenticateUser, + asyncHandler(getTriggerSubstepsAction) +); + export default router; diff --git a/packages/backend/test/mocks/rest/api/v1/apps/get-trigger-substeps.js b/packages/backend/test/mocks/rest/api/v1/apps/get-trigger-substeps.js new file mode 100644 index 00000000..baad19d1 --- /dev/null +++ b/packages/backend/test/mocks/rest/api/v1/apps/get-trigger-substeps.js @@ -0,0 +1,14 @@ +const getTriggerSubstepsMock = (substeps) => { + return { + data: substeps, + meta: { + count: substeps.length, + currentPage: null, + isArray: true, + totalPages: null, + type: 'Object', + }, + }; +}; + +export default getTriggerSubstepsMock;