diff --git a/src/lib/routes/admin-api/archive.ts b/src/lib/routes/admin-api/archive.ts index b4ed181ec3..f0048d7ae5 100644 --- a/src/lib/routes/admin-api/archive.ts +++ b/src/lib/routes/admin-api/archive.ts @@ -42,6 +42,9 @@ export default class ArchiveController extends Controller { middleware: [ openApiService.validPath({ tags: ['Archive'], + summary: 'Get archived features', + description: + 'Retrieve a list of all [archived feature toggles](https://docs.getunleash.io/reference/archived-toggles).', operationId: 'getArchivedFeatures', responses: { 200: createResponseSchema('featuresSchema'), @@ -62,6 +65,9 @@ export default class ArchiveController extends Controller { openApiService.validPath({ tags: ['Archive'], operationId: 'getArchivedFeaturesByProjectId', + summary: 'Get archived features in project', + description: + 'Retrieves a list of archived features that belong to the provided project.', responses: { 200: createResponseSchema('featuresSchema'), ...getStandardResponses(401, 403), diff --git a/src/lib/routes/admin-api/client-metrics.ts b/src/lib/routes/admin-api/client-metrics.ts index 223b7ac304..e459c20b64 100644 --- a/src/lib/routes/admin-api/client-metrics.ts +++ b/src/lib/routes/admin-api/client-metrics.ts @@ -59,8 +59,9 @@ class ClientMetricsController extends Controller { openApiService.validPath({ operationId: 'getRawFeatureMetrics', tags: ['Metrics'], - summary: - 'Feature usage metrics for the last 48 hours, grouped by hour', + summary: 'Get feature metrics', + description: + 'Get usage metrics for a specific feature for the last 48 hours, grouped by hour', responses: { 200: createResponseSchema('featureMetricsSchema'), ...getStandardResponses(401, 403, 404), diff --git a/src/lib/routes/admin-api/project/environments.ts b/src/lib/routes/admin-api/project/environments.ts index 9231609afc..0e9bcd5cd9 100644 --- a/src/lib/routes/admin-api/project/environments.ts +++ b/src/lib/routes/admin-api/project/environments.ts @@ -99,6 +99,7 @@ export default class EnvironmentsController extends Controller { openApiService.validPath({ tags: ['Projects'], operationId: 'addDefaultStrategyToProjectEnvironment', + summary: 'Set environment-default strategy', description: 'Adds a default strategy for this environment. Unleash will use this strategy by default when enabling a toggle. Use the wild card "*" for `:environment` to add to all environments. ', requestBody: createRequestSchema( diff --git a/src/lib/routes/admin-api/project/project-features.ts b/src/lib/routes/admin-api/project/project-features.ts index d3b9327d15..7a8aa97a7e 100644 --- a/src/lib/routes/admin-api/project/project-features.ts +++ b/src/lib/routes/admin-api/project/project-features.ts @@ -325,8 +325,10 @@ export default class ProjectFeaturesController extends Controller { middleware: [ openApiService.validPath({ tags: ['Features'], - summary: 'Set the order of strategies on the list', operationId: 'setStrategySortOrder', + summary: 'Set strategy sort order', + description: + 'Set the sort order of the provided list of strategies.', requestBody: createRequestSchema( 'setStrategySortOrderSchema', ), diff --git a/src/lib/routes/admin-api/public-signup.ts b/src/lib/routes/admin-api/public-signup.ts index a7c2381e9c..3ae135e9da 100644 --- a/src/lib/routes/admin-api/public-signup.ts +++ b/src/lib/routes/admin-api/public-signup.ts @@ -74,7 +74,8 @@ export class PublicSignupController extends Controller { middleware: [ openApiService.validPath({ tags: ['Public signup tokens'], - summary: 'Retrieve all existing public signup tokens', + summary: 'Get public signup tokens', + description: 'Retrieves all existing public signup tokens.', operationId: 'getAllPublicSignupTokens', responses: { 200: createResponseSchema('publicSignupTokensSchema'), diff --git a/src/lib/routes/public-invite.ts b/src/lib/routes/public-invite.ts index 0cc91f3c4d..8f95507420 100644 --- a/src/lib/routes/public-invite.ts +++ b/src/lib/routes/public-invite.ts @@ -52,7 +52,8 @@ export class PublicInviteController extends Controller { openApiService.validPath({ tags: ['Public signup tokens'], operationId: 'validatePublicSignupToken', - summary: `Check whether a public sign-up token exists, has not expired and is enabled`, + summary: `Validate signup token`, + description: `Check whether the provided public sign-up token exists, has not expired and is enabled`, responses: { 200: emptyResponse, ...getStandardResponses(400), diff --git a/src/test/e2e/api/openapi/openapi.e2e.test.ts b/src/test/e2e/api/openapi/openapi.e2e.test.ts index a54a196f19..9477e7fffb 100644 --- a/src/test/e2e/api/openapi/openapi.e2e.test.ts +++ b/src/test/e2e/api/openapi/openapi.e2e.test.ts @@ -192,3 +192,33 @@ test('all tags are listed in the root "tags" list', async () => { } expect(invalidTags).toStrictEqual({}); }); + +test('all API operations have summaries and descriptions', async () => { + const { body: spec } = await app.request + .get('/docs/openapi.json') + .expect('Content-Type', /json/) + .expect(200); + + const anomalies = Object.entries(spec.paths).flatMap(([path, data]) => { + return Object.entries(data) + .map(([verb, operationDescription]) => { + if ( + 'summary' in operationDescription && + 'description' in operationDescription + ) { + return undefined; + } else { + return [verb, operationDescription.operationId]; + } + }) + .filter(Boolean) + .map( + ([verb, operationId]) => + `${verb.toUpperCase()} ${path} (operation ID: ${operationId})`, + ); + }); + + // any items left in the anomalies list is missing either a summary, or a + // description, or both. + expect(anomalies).toStrictEqual([]); +});