From b329084a69005ef430d8726e7c5a5106c113d742 Mon Sep 17 00:00:00 2001 From: Jaanus Sellin Date: Fri, 30 Jun 2023 15:22:08 +0300 Subject: [PATCH] chore: openapi docs for archive (#4127) --- src/lib/routes/admin-api/archive.ts | 37 +- .../admin-api/project/project-archive.ts | 20 +- src/test/e2e/api/admin/archive.test.ts | 13 +- .../__snapshots__/openapi.e2e.test.ts.snap | 490 ++++++++++++++++++ 4 files changed, 545 insertions(+), 15 deletions(-) diff --git a/src/lib/routes/admin-api/archive.ts b/src/lib/routes/admin-api/archive.ts index fa13fb54a9..b4ed181ec3 100644 --- a/src/lib/routes/admin-api/archive.ts +++ b/src/lib/routes/admin-api/archive.ts @@ -1,7 +1,6 @@ import { Request, Response } from 'express'; import { IUnleashConfig } from '../../types/option'; import { IUnleashServices } from '../../types'; -import { Logger } from '../../logger'; import Controller from '../controller'; import { extractUsername } from '../../util/extract-user'; import { DELETE_FEATURE, NONE, UPDATE_FEATURE } from '../../types/permissions'; @@ -14,11 +13,12 @@ import { import { serializeDates } from '../../types/serialize-dates'; import { OpenApiService } from '../../services/openapi-service'; import { createResponseSchema } from '../../openapi/util/create-response-schema'; -import { emptyResponse } from '../../openapi/util/standard-responses'; +import { + emptyResponse, + getStandardResponses, +} from '../../openapi/util/standard-responses'; export default class ArchiveController extends Controller { - private readonly logger: Logger; - private featureService: FeatureToggleService; private openApiService: OpenApiService; @@ -31,7 +31,6 @@ export default class ArchiveController extends Controller { }: Pick, ) { super(config); - this.logger = config.getLogger('/admin-api/archive.js'); this.featureService = featureToggleServiceV2; this.openApiService = openApiService; @@ -44,7 +43,11 @@ export default class ArchiveController extends Controller { openApiService.validPath({ tags: ['Archive'], operationId: 'getArchivedFeatures', - responses: { 200: createResponseSchema('featuresSchema') }, + responses: { + 200: createResponseSchema('featuresSchema'), + ...getStandardResponses(401, 403), + }, + deprecated: true, }), ], @@ -59,7 +62,11 @@ export default class ArchiveController extends Controller { openApiService.validPath({ tags: ['Archive'], operationId: 'getArchivedFeaturesByProjectId', - responses: { 200: createResponseSchema('featuresSchema') }, + responses: { + 200: createResponseSchema('featuresSchema'), + ...getStandardResponses(401, 403), + }, + deprecated: true, }), ], @@ -74,8 +81,14 @@ export default class ArchiveController extends Controller { middleware: [ openApiService.validPath({ tags: ['Archive'], + description: + 'This endpoint archives the specified feature.', + summary: 'Archives a feature', operationId: 'deleteFeature', - responses: { 200: emptyResponse }, + responses: { + 200: emptyResponse, + ...getStandardResponses(401, 403), + }, }), ], }); @@ -89,8 +102,14 @@ export default class ArchiveController extends Controller { middleware: [ openApiService.validPath({ tags: ['Archive'], + description: + 'This endpoint revives the specified feature from archive.', + summary: 'Revives a feature', operationId: 'reviveFeature', - responses: { 200: emptyResponse }, + responses: { + 200: emptyResponse, + ...getStandardResponses(400, 401, 403), + }, }), ], }); diff --git a/src/lib/routes/admin-api/project/project-archive.ts b/src/lib/routes/admin-api/project/project-archive.ts index 02450e049a..419bd54bac 100644 --- a/src/lib/routes/admin-api/project/project-archive.ts +++ b/src/lib/routes/admin-api/project/project-archive.ts @@ -12,7 +12,10 @@ import { DELETE_FEATURE } from '../../../types/permissions'; import FeatureToggleService from '../../../services/feature-toggle-service'; import { IAuthRequest } from '../../unleash-types'; import { OpenApiService } from '../../../services/openapi-service'; -import { emptyResponse } from '../../../openapi/util/standard-responses'; +import { + emptyResponse, + getStandardResponses, +} from '../../../openapi/util/standard-responses'; import { BatchFeaturesSchema, createRequestSchema } from '../../../openapi'; import Controller from '../../controller'; @@ -57,7 +60,10 @@ export default class ProjectArchiveController extends Controller { 'This endpoint deletes the specified features, that are in archive.', summary: 'Deletes a list of features', requestBody: createRequestSchema('batchFeaturesSchema'), - responses: { 200: emptyResponse }, + responses: { + 200: emptyResponse, + ...getStandardResponses(400, 401, 403), + }, }), ], }); @@ -76,7 +82,10 @@ export default class ProjectArchiveController extends Controller { 'This endpoint revives the specified features.', summary: 'Revives a list of features', requestBody: createRequestSchema('batchFeaturesSchema'), - responses: { 200: emptyResponse }, + responses: { + 200: emptyResponse, + ...getStandardResponses(400, 401, 403), + }, }), ], }); @@ -94,7 +103,10 @@ export default class ProjectArchiveController extends Controller { 'This endpoint archives the specified features.', summary: 'Archives a list of features', requestBody: createRequestSchema('batchFeaturesSchema'), - responses: { 202: emptyResponse }, + responses: { + 202: emptyResponse, + ...getStandardResponses(400, 401, 403), + }, }), ], }); diff --git a/src/test/e2e/api/admin/archive.test.ts b/src/test/e2e/api/admin/archive.test.ts index 653ecfa40a..daad050e1d 100644 --- a/src/test/e2e/api/admin/archive.test.ts +++ b/src/test/e2e/api/admin/archive.test.ts @@ -1,5 +1,8 @@ import dbInit, { ITestDb } from '../../helpers/database-init'; -import { IUnleashTest, setupApp } from '../../helpers/test-helper'; +import { + IUnleashTest, + setupAppWithCustomConfig, +} from '../../helpers/test-helper'; import getLogger from '../../../fixtures/no-logger'; let app: IUnleashTest; @@ -7,7 +10,13 @@ let db: ITestDb; beforeAll(async () => { db = await dbInit('archive_test_serial', getLogger); - app = await setupApp(db.stores); + app = await setupAppWithCustomConfig(db.stores, { + experimental: { + flags: { + strictSchemaValidation: true, + }, + }, + }); }); afterAll(async () => { diff --git a/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap b/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap index a1a2073394..bfe4933426 100644 --- a/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap +++ b/src/test/e2e/api/openapi/__snapshots__/openapi.e2e.test.ts.snap @@ -6746,6 +6746,60 @@ Note: passing \`null\` as a value for the description property will set it to an }, "description": "featuresSchema", }, + "401": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You must log in to use Unleash. Your request had no authorization header, so we could not authorize you. Try logging in at /auth/simple/login.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "AuthenticationRequired", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "Authorization information is missing or invalid. Provide a valid API token as the \`authorization\` header, e.g. \`authorization:*.*.my-admin-token\`.", + }, + "403": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You need the "UPDATE_ADDON" permission to perform this action in the "development" environment.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "NoAccessError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "User credentials are valid but does not have enough privileges to execute this operation", + }, }, "tags": [ "Archive", @@ -6777,6 +6831,60 @@ Note: passing \`null\` as a value for the description property will set it to an }, "description": "featuresSchema", }, + "401": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You must log in to use Unleash. Your request had no authorization header, so we could not authorize you. Try logging in at /auth/simple/login.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "AuthenticationRequired", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "Authorization information is missing or invalid. Provide a valid API token as the \`authorization\` header, e.g. \`authorization:*.*.my-admin-token\`.", + }, + "403": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You need the "UPDATE_ADDON" permission to perform this action in the "development" environment.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "NoAccessError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "User credentials are valid but does not have enough privileges to execute this operation", + }, }, "tags": [ "Archive", @@ -6785,6 +6893,7 @@ Note: passing \`null\` as a value for the description property will set it to an }, "/api/admin/archive/revive/{featureName}": { "post": { + "description": "This endpoint revives the specified feature from archive.", "operationId": "reviveFeature", "parameters": [ { @@ -6800,7 +6909,89 @@ Note: passing \`null\` as a value for the description property will set it to an "200": { "description": "This response has no body.", }, + "400": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "The request payload you provided doesn't conform to the schema. The .parameters property should be object. You sent [].", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "ValidationError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "The request data does not match what we expect.", + }, + "401": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You must log in to use Unleash. Your request had no authorization header, so we could not authorize you. Try logging in at /auth/simple/login.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "AuthenticationRequired", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "Authorization information is missing or invalid. Provide a valid API token as the \`authorization\` header, e.g. \`authorization:*.*.my-admin-token\`.", + }, + "403": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You need the "UPDATE_ADDON" permission to perform this action in the "development" environment.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "NoAccessError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "User credentials are valid but does not have enough privileges to execute this operation", + }, }, + "summary": "Revives a feature", "tags": [ "Archive", ], @@ -6808,6 +6999,7 @@ Note: passing \`null\` as a value for the description property will set it to an }, "/api/admin/archive/{featureName}": { "delete": { + "description": "This endpoint archives the specified feature.", "operationId": "deleteFeature", "parameters": [ { @@ -6823,7 +7015,62 @@ Note: passing \`null\` as a value for the description property will set it to an "200": { "description": "This response has no body.", }, + "401": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You must log in to use Unleash. Your request had no authorization header, so we could not authorize you. Try logging in at /auth/simple/login.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "AuthenticationRequired", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "Authorization information is missing or invalid. Provide a valid API token as the \`authorization\` header, e.g. \`authorization:*.*.my-admin-token\`.", + }, + "403": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You need the "UPDATE_ADDON" permission to perform this action in the "development" environment.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "NoAccessError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "User credentials are valid but does not have enough privileges to execute this operation", + }, }, + "summary": "Archives a feature", "tags": [ "Archive", ], @@ -10349,6 +10596,87 @@ true,false,"[{""range"":""allTime"",""count"":15},{""range"":""30d"",""count"":9 "202": { "description": "This response has no body.", }, + "400": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "The request payload you provided doesn't conform to the schema. The .parameters property should be object. You sent [].", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "ValidationError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "The request data does not match what we expect.", + }, + "401": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You must log in to use Unleash. Your request had no authorization header, so we could not authorize you. Try logging in at /auth/simple/login.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "AuthenticationRequired", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "Authorization information is missing or invalid. Provide a valid API token as the \`authorization\` header, e.g. \`authorization:*.*.my-admin-token\`.", + }, + "403": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You need the "UPDATE_ADDON" permission to perform this action in the "development" environment.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "NoAccessError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "User credentials are valid but does not have enough privileges to execute this operation", + }, }, "summary": "Archives a list of features", "tags": [ @@ -10473,6 +10801,87 @@ true,false,"[{""range"":""allTime"",""count"":15},{""range"":""30d"",""count"":9 "200": { "description": "This response has no body.", }, + "400": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "The request payload you provided doesn't conform to the schema. The .parameters property should be object. You sent [].", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "ValidationError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "The request data does not match what we expect.", + }, + "401": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You must log in to use Unleash. Your request had no authorization header, so we could not authorize you. Try logging in at /auth/simple/login.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "AuthenticationRequired", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "Authorization information is missing or invalid. Provide a valid API token as the \`authorization\` header, e.g. \`authorization:*.*.my-admin-token\`.", + }, + "403": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You need the "UPDATE_ADDON" permission to perform this action in the "development" environment.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "NoAccessError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "User credentials are valid but does not have enough privileges to execute this operation", + }, }, "summary": "Deletes a list of features", "tags": [ @@ -12311,6 +12720,87 @@ true,false,"[{""range"":""allTime"",""count"":15},{""range"":""30d"",""count"":9 "200": { "description": "This response has no body.", }, + "400": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "The request payload you provided doesn't conform to the schema. The .parameters property should be object. You sent [].", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "ValidationError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "The request data does not match what we expect.", + }, + "401": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You must log in to use Unleash. Your request had no authorization header, so we could not authorize you. Try logging in at /auth/simple/login.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "AuthenticationRequired", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "Authorization information is missing or invalid. Provide a valid API token as the \`authorization\` header, e.g. \`authorization:*.*.my-admin-token\`.", + }, + "403": { + "content": { + "application/json": { + "schema": { + "properties": { + "id": { + "description": "The ID of the error instance", + "example": "9c40958a-daac-400e-98fb-3bb438567008", + "type": "string", + }, + "message": { + "description": "A description of what went wrong.", + "example": "You need the "UPDATE_ADDON" permission to perform this action in the "development" environment.", + "type": "string", + }, + "name": { + "description": "The name of the error kind", + "example": "NoAccessError", + "type": "string", + }, + }, + "type": "object", + }, + }, + }, + "description": "User credentials are valid but does not have enough privileges to execute this operation", + }, }, "summary": "Revives a list of features", "tags": [