From 28f8f4099a07f9446eee553dfa7343cae5b95baf Mon Sep 17 00:00:00 2001 From: Andrea Tabone Date: Mon, 30 May 2022 12:15:12 +0200 Subject: [PATCH 1/2] Include utils folder for coverage Signed-off-by: at670475 --- .../src/components/Swagger/SwaggerUI.jsx | 5 +- .../frontend/src/utils/filterApis.js | 47 +++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 api-catalog-ui/frontend/src/utils/filterApis.js diff --git a/api-catalog-ui/frontend/src/components/Swagger/SwaggerUI.jsx b/api-catalog-ui/frontend/src/components/Swagger/SwaggerUI.jsx index 17a66d264d..0a82b7f154 100644 --- a/api-catalog-ui/frontend/src/components/Swagger/SwaggerUI.jsx +++ b/api-catalog-ui/frontend/src/components/Swagger/SwaggerUI.jsx @@ -14,6 +14,7 @@ import './Swagger.css'; import InstanceInfo from '../ServiceTab/InstanceInfo'; import getBaseUrl from '../../helpers/urls'; import { BasicSnippedGenerator } from '../../utils/generateSnippets'; +import { AdvancedFilterPlugin } from '../../utils/filterApis'; function transformSwaggerToCurrentHost(swagger) { swagger.host = window.location.host; @@ -101,7 +102,7 @@ export default class SwaggerUI extends Component { spec: swagger, presets: [SwaggerUi.presets.apis], requestSnippetsEnabled: true, - plugins: [this.customPlugins, BasicSnippedGenerator], + plugins: [this.customPlugins, BasicSnippedGenerator, AdvancedFilterPlugin], filter: true, }); } @@ -113,7 +114,7 @@ export default class SwaggerUI extends Component { url, presets: [SwaggerUi.presets.apis], requestSnippetsEnabled: true, - plugins: [this.customPlugins, BasicSnippedGenerator], + plugins: [this.customPlugins, BasicSnippedGenerator, AdvancedFilterPlugin], filter: true, responseInterceptor: (res) => { // response.text field is used to render the swagger diff --git a/api-catalog-ui/frontend/src/utils/filterApis.js b/api-catalog-ui/frontend/src/utils/filterApis.js new file mode 100644 index 0000000000..ecd20d9f1a --- /dev/null +++ b/api-catalog-ui/frontend/src/utils/filterApis.js @@ -0,0 +1,47 @@ +/* + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + */ +/** + * Custom Plugin which extends the SwaggerUI filter functionality to filter APIs by tag, summary and description + */ +// eslint-disable-next-line import/prefer-default-export +export const AdvancedFilterPlugin = function (system) { + return { + fn: { + opsFilter: (taggedOps, phrase) => { + // eslint-disable-next-line no-param-reassign + phrase = phrase.toLowerCase(); + const normalTaggedOps = JSON.parse(JSON.stringify(taggedOps)); + Object.keys(normalTaggedOps).forEach((tagObj) => { + const { operations } = normalTaggedOps[tagObj]; + let i = operations.length; + // eslint-disable-next-line no-plusplus + while (i--) { + const { operation } = operations[i]; + if ( + operations[i].path.toLowerCase().indexOf(phrase) === -1 && + operation.summary !== undefined && + operation.description !== undefined && + operation.summary.toLowerCase().indexOf(phrase) === -1 && + operation.description.toLowerCase().indexOf(phrase) === -1 + ) { + operations.splice(i, 1); + } + } + if (operations.length === 0) { + delete normalTaggedOps[tagObj]; + } else { + normalTaggedOps[tagObj].operations = operations; + } + }); + return system.Im.fromJS(normalTaggedOps); + }, + }, + }; +}; From be2cfed671a66c3878acce2a281c227beda359d4 Mon Sep 17 00:00:00 2001 From: Andrea Tabone Date: Mon, 30 May 2022 14:30:05 +0200 Subject: [PATCH 2/2] refactoring and test Signed-off-by: at670475 --- .../frontend/src/utils/filterApis.js | 67 ++++++++------- .../frontend/src/utils/filterApis.test.js | 84 +++++++++++++++++++ 2 files changed, 123 insertions(+), 28 deletions(-) create mode 100644 api-catalog-ui/frontend/src/utils/filterApis.test.js diff --git a/api-catalog-ui/frontend/src/utils/filterApis.js b/api-catalog-ui/frontend/src/utils/filterApis.js index ecd20d9f1a..0a20e344ab 100644 --- a/api-catalog-ui/frontend/src/utils/filterApis.js +++ b/api-catalog-ui/frontend/src/utils/filterApis.js @@ -7,6 +7,44 @@ * * Copyright Contributors to the Zowe Project. */ + +/** + * Extend the filter by allowing to search not only by tags, but also by description and summary. + * The filter is also case-insensitive. + * @param phrase the search input + * @param taggedOps the API doc + * @param system the system + * @returns {*} the filtered API operation + */ +export function extendFilter(phrase, taggedOps, system) { + // eslint-disable-next-line no-param-reassign + phrase = phrase.toLowerCase(); + const normalTaggedOps = JSON.parse(JSON.stringify(taggedOps)); + Object.keys(normalTaggedOps).forEach((tagObj) => { + const { operations } = normalTaggedOps[tagObj]; + let i = operations.length; + // eslint-disable-next-line no-plusplus + while (i--) { + const { operation } = operations[i]; + if ( + operations[i].path.toLowerCase().indexOf(phrase) === -1 && + operation.summary !== undefined && + operation.description !== undefined && + operation.summary.toLowerCase().indexOf(phrase) === -1 && + operation.description.toLowerCase().indexOf(phrase) === -1 + ) { + operations.splice(i, 1); + } + } + if (operations.length === 0) { + delete normalTaggedOps[tagObj]; + } else { + normalTaggedOps[tagObj].operations = operations; + } + }); + return system.Im.fromJS(normalTaggedOps); +} + /** * Custom Plugin which extends the SwaggerUI filter functionality to filter APIs by tag, summary and description */ @@ -14,34 +52,7 @@ export const AdvancedFilterPlugin = function (system) { return { fn: { - opsFilter: (taggedOps, phrase) => { - // eslint-disable-next-line no-param-reassign - phrase = phrase.toLowerCase(); - const normalTaggedOps = JSON.parse(JSON.stringify(taggedOps)); - Object.keys(normalTaggedOps).forEach((tagObj) => { - const { operations } = normalTaggedOps[tagObj]; - let i = operations.length; - // eslint-disable-next-line no-plusplus - while (i--) { - const { operation } = operations[i]; - if ( - operations[i].path.toLowerCase().indexOf(phrase) === -1 && - operation.summary !== undefined && - operation.description !== undefined && - operation.summary.toLowerCase().indexOf(phrase) === -1 && - operation.description.toLowerCase().indexOf(phrase) === -1 - ) { - operations.splice(i, 1); - } - } - if (operations.length === 0) { - delete normalTaggedOps[tagObj]; - } else { - normalTaggedOps[tagObj].operations = operations; - } - }); - return system.Im.fromJS(normalTaggedOps); - }, + opsFilter: (taggedOps, phrase) => extendFilter(phrase, taggedOps, system), }, }; }; diff --git a/api-catalog-ui/frontend/src/utils/filterApis.test.js b/api-catalog-ui/frontend/src/utils/filterApis.test.js new file mode 100644 index 0000000000..cfc68c9550 --- /dev/null +++ b/api-catalog-ui/frontend/src/utils/filterApis.test.js @@ -0,0 +1,84 @@ +/* + * This program and the accompanying materials are made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Copyright Contributors to the Zowe Project. + */ +import { extendFilter } from './filterApis'; + +describe('>>> Filter APIs', () => { + it('should filter the operation', () => { + const system = { + Im: { + fromJS: (obj) => obj, + }, + }; + const spec = { + 'API Catalog': { + tagDetails: { + name: 'API Catalog', + description: 'Api Catalog Controller', + }, + operations: [ + { + path: '/containers', + method: 'get', + operation: { + tags: ['API Catalog'], + summary: 'Lists catalog dashboard tiles', + description: 'Returns a list of tiles including status and tile description', + operationId: 'getAllAPIContainersUsingGET', + produces: ['application/json'], + parameters: [], + responses: { + 200: { + description: 'OK', + schema: { + type: 'array', + items: { + $ref: '#/definitions/APIContainer', + }, + }, + }, + }, + }, + id: 'get-/containers', + }, + { + path: '/containers/{id}', + method: 'get', + operation: { + tags: ['API Catalog'], + summary: 'Retrieves a specific dashboard tile information', + description: + 'Returns information for a specific tile {id} including status and tile description', + operationId: 'getAPIContainerByIdUsingGET', + parameters: [ + { + name: 'id', + }, + ], + responses: { + 200: { + description: 'OK', + schema: { + type: 'array', + items: { + $ref: '#/definitions/APIContainer', + }, + }, + }, + }, + }, + id: 'get-/containers/{id}', + }, + ], + }, + }; + const filteredApi = extendFilter('Lists catalog', spec, system); + expect(filteredApi['API Catalog'].operations[0].operation.summary).toEqual('Lists catalog dashboard tiles'); + }); +});