diff --git a/ui/lib/open-api-explorer/addon/components/swagger-ui.js b/ui/lib/open-api-explorer/addon/components/swagger-ui.js
index 4910ac6bf1..dae7a86ca0 100644
--- a/ui/lib/open-api-explorer/addon/components/swagger-ui.js
+++ b/ui/lib/open-api-explorer/addon/components/swagger-ui.js
@@ -26,18 +26,24 @@ export default class SwaggerUiComponent extends Component {
return {
fn: {
opsFilter: (taggedOps, phrase) => {
- // map over the options and filter out operations where the path doesn't match what's typed
- return (
- taggedOps
- .map((tagObj) => {
- const operations = tagObj.operations.filter((operationObj) => {
- return operationObj.path.includes(phrase);
- });
- return tagObj.set('operations', operations);
- })
- // then traverse again and remove the top level item if there are no operations left after filtering
- .filter((tagObj) => !!tagObj.operations.size)
- );
+ const filteredOperations = taggedOps.reduce((acc, tagObj) => {
+ const operations = tagObj.get('operations');
+
+ // filter out operations where the path doesn't match search phrase
+ const operationsWithMatchingPath = operations.filter((operationObj) => {
+ const path = operationObj.get('path');
+ return path.includes(phrase);
+ });
+
+ // if there are any operations left after filtering, add the tagObj to the accumulator
+ if (operationsWithMatchingPath.size > 0) {
+ acc.push(tagObj.set('operations', operationsWithMatchingPath));
+ }
+
+ return acc;
+ }, []);
+
+ return filteredOperations;
},
},
};
diff --git a/ui/tests/integration/components/open-api-explorer/swagger-ui-test.js b/ui/tests/integration/components/open-api-explorer/swagger-ui-test.js
index a78cdc3a6e..2c53c0ffa1 100644
--- a/ui/tests/integration/components/open-api-explorer/swagger-ui-test.js
+++ b/ui/tests/integration/components/open-api-explorer/swagger-ui-test.js
@@ -8,31 +8,54 @@ import { setupRenderingTest } from 'vault/tests/helpers';
import { waitUntil, find } from '@ember/test-helpers';
import { setupEngine } from 'ember-engines/test-support';
import { setupMirage } from 'ember-cli-mirage/test-support';
-import { render } from '@ember/test-helpers';
+import { render, fillIn } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
+const SELECTORS = {
+ container: '[data-test-swagger-ui]',
+ searchInput: '.operation-filter-input',
+ apiPathBlock: '.opblock-post',
+};
+
module('Integration | Component | open-api-explorer | swagger-ui', function (hooks) {
setupRenderingTest(hooks);
setupEngine(hooks, 'open-api-explorer');
setupMirage(hooks);
hooks.beforeEach(function () {
this.store = this.owner.lookup('service:store');
- });
- test('it renders', async function (assert) {
- assert.expect(2);
const openApiResponse = this.server.create('open-api-explorer');
this.server.get('sys/internal/specs/openapi', () => {
return openApiResponse;
});
- await render(hbs``, {
- owner: this.engine,
- });
+ this.totalApiPaths = Object.keys(openApiResponse.paths).length;
- await waitUntil(() => find('[data-test-swagger-ui]'));
- assert.dom('[data-test-swagger-ui]').exists('renders component');
- await waitUntil(() => find('.operation-filter-input'));
- assert.dom('.opblock-post').exists({ count: 2 }, 'renders two blocks');
+ this.renderComponent = async () => {
+ await render(hbs``, {
+ owner: this.engine,
+ });
+ };
+ });
+
+ test('it renders', async function (assert) {
+ await this.renderComponent();
+
+ await waitUntil(() => find(SELECTORS.container));
+
+ assert.dom(SELECTORS.container).exists('renders component');
+ assert.dom(SELECTORS.apiPathBlock).exists({ count: this.totalApiPaths }, 'renders all api paths');
+ });
+
+ test('it can search', async function (assert) {
+ await this.renderComponent();
+
+ await waitUntil(() => find(SELECTORS.searchInput));
+ await fillIn(SELECTORS.searchInput, 'token');
+
+ // for some reason search results are not rendered immediately in tests,
+ // so asserting that the search input has the value we expect is the best we can do here
+ // if the search fn breaks, this test will fail
+ assert.dom(SELECTORS.searchInput).hasValue('token', 'search input has value');
});
});