From e354f68d98b955fb0da9fce157b252fb9c7839ef Mon Sep 17 00:00:00 2001 From: Jai Bhagat Date: Mon, 26 Jul 2021 17:23:21 -0400 Subject: [PATCH] edit fuzzy search callback logic Namespaces are set-up in Nomad to be an object that has an id property. However, namespaces actually don't have that shape. Our search was expecting a namespace object, but we actually don't have a namespace assigned to jobs in our config and namespace is set to null. Normally, these namespaces would be set to default, but that would require us to refactor our Mirage config if we wanted to assert that namespaces are 'default' and not null. So this is a bandaid solution. --- ui/app/components/global-search/control.js | 83 ++++++++++++++-------- ui/mirage/config.js | 4 +- ui/tests/acceptance/search-test.js | 51 +++++++++---- 3 files changed, 92 insertions(+), 46 deletions(-) diff --git a/ui/app/components/global-search/control.js b/ui/app/components/global-search/control.js index 5a100ded4d37..653617cdd162 100644 --- a/ui/app/components/global-search/control.js +++ b/ui/app/components/global-search/control.js @@ -58,32 +58,40 @@ export default class GlobalSearchControl extends Component { const allTaskGroupResults = results.Matches.groups || []; const allCSIPluginResults = results.Matches.plugins || []; - const jobResults = allJobResults.slice(0, MAXIMUM_RESULTS).map(({ ID: name, Scope: [ namespace, id ]}) => ({ - type: 'job', - id, - namespace, - label: `${name} @ ${namespace}`, - })); - - const nodeResults = allNodeResults.slice(0, MAXIMUM_RESULTS).map(({ ID: name, Scope: [ id ]}) => ({ - type: 'node', - id, - label: name, - })); - - const allocationResults = allAllocationResults.slice(0, MAXIMUM_RESULTS).map(({ ID: name, Scope: [ namespace, id ]}) => ({ - type: 'allocation', - id, - label: `${name} @ ${namespace}`, - })); - - const taskGroupResults = allTaskGroupResults.slice(0, MAXIMUM_RESULTS).map(({ ID: id, Scope: [ namespace, jobId ]}) => ({ - type: 'task-group', - id, - namespace, - jobId, - label: id, - })); + const jobResults = allJobResults + .slice(0, MAXIMUM_RESULTS) + .map(({ ID: name, Scope: [namespace, id] }) => ({ + type: 'job', + id, + namespace, + label: `${name} > ${namespace}`, + })); + + const nodeResults = allNodeResults + .slice(0, MAXIMUM_RESULTS) + .map(({ ID: name, Scope: [id] }) => ({ + type: 'node', + id, + label: name, + })); + + const allocationResults = allAllocationResults + .slice(0, MAXIMUM_RESULTS) + .map(({ ID: name, Scope: [namespace, id] }) => ({ + type: 'allocation', + id, + label: `${name} > ${namespace}`, + })); + + const taskGroupResults = allTaskGroupResults + .slice(0, MAXIMUM_RESULTS) + .map(({ ID: id, Scope: [namespace, jobId] }) => ({ + type: 'task-group', + id, + namespace, + jobId, + label: id, + })); const csiPluginResults = allCSIPluginResults.slice(0, MAXIMUM_RESULTS).map(({ ID: id }) => ({ type: 'plugin', @@ -109,17 +117,32 @@ export default class GlobalSearchControl extends Component { options: nodeResults, }, { - groupName: resultsGroupLabel('Allocations', allocationResults, allAllocationResults, allocationsTruncated), + groupName: resultsGroupLabel( + 'Allocations', + allocationResults, + allAllocationResults, + allocationsTruncated + ), options: allocationResults, }, { - groupName: resultsGroupLabel('Task Groups', taskGroupResults, allTaskGroupResults, taskGroupsTruncated), + groupName: resultsGroupLabel( + 'Task Groups', + taskGroupResults, + allTaskGroupResults, + taskGroupsTruncated + ), options: taskGroupResults, }, { - groupName: resultsGroupLabel('CSI Plugins', csiPluginResults, allCSIPluginResults, csiPluginsTruncated), + groupName: resultsGroupLabel( + 'CSI Plugins', + csiPluginResults, + allCSIPluginResults, + csiPluginsTruncated + ), options: csiPluginResults, - } + }, ]; }) search; diff --git a/ui/mirage/config.js b/ui/mirage/config.js index 3e26e3bf2b9f..e1ce1847c154 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -612,7 +612,7 @@ export default function() { const transformedAllocs = matchedAllocs.models.map(alloc => ({ ID: alloc.name, - Scope: [(alloc.namespace || {}).id, alloc.id], + Scope: [alloc.namespace || 'default', alloc.id], })); const transformedGroups = matchedGroups.models.map(group => ({ @@ -622,7 +622,7 @@ export default function() { const transformedJobs = matchedJobs.models.map(job => ({ ID: job.name, - Scope: [job.namespace, job.id], + Scope: [job.namespace || 'default', job.id], })); const transformedNodes = matchedNodes.models.map(node => ({ diff --git a/ui/tests/acceptance/search-test.js b/ui/tests/acceptance/search-test.js index c1380f218d71..d6e950ac6cf5 100644 --- a/ui/tests/acceptance/search-test.js +++ b/ui/tests/acceptance/search-test.js @@ -16,8 +16,19 @@ module('Acceptance | search', function(hooks) { server.create('node', { name: 'xyz' }); const otherNode = server.create('node', { name: 'ghi' }); - server.create('job', { id: 'vwxyz', namespaceId: 'default', groupsCount: 1, groupTaskCount: 1 }); - server.create('job', { id: 'xyz', name: 'xyz job', namespaceId: 'default', groupsCount: 1, groupTaskCount: 1 }); + server.create('job', { + id: 'vwxyz', + namespaceId: 'default', + groupsCount: 1, + groupTaskCount: 1, + }); + server.create('job', { + id: 'xyz', + name: 'xyz job', + namespaceId: 'default', + groupsCount: 1, + groupTaskCount: 1, + }); server.create('job', { id: 'abc', namespaceId: 'default', groupsCount: 1, groupTaskCount: 1 }); const firstAllocation = server.schema.allocations.all().models[0]; @@ -35,8 +46,8 @@ module('Acceptance | search', function(hooks) { search.groups[0].as(jobs => { assert.equal(jobs.name, 'Jobs (2)'); assert.equal(jobs.options.length, 2); - assert.equal(jobs.options[0].text, 'vwxyz @ default'); - assert.equal(jobs.options[1].text, 'xyz job @ default'); + assert.equal(jobs.options[0].text, 'vwxyz > default'); + assert.equal(jobs.options[1].text, 'xyz job > default'); }); search.groups[1].as(clients => { @@ -69,8 +80,12 @@ module('Acceptance | search', function(hooks) { await Layout.navbar.search.groups[1].options[0].click(); assert.equal(currentURL(), `/clients/${otherNode.id}`); + await this.pauseTest(); await selectSearch(Layout.navbar.search.scope, firstAllocation.name); - assert.equal(Layout.navbar.search.groups[2].options[0].text, `${firstAllocation.name} @ ${firstAllocation.namespace}`); + assert.equal( + Layout.navbar.search.groups[2].options[0].text, + `${firstAllocation.name} > ${firstAllocation.namespace}` + ); await Layout.navbar.search.groups[2].options[0].click(); assert.equal(currentURL(), `/allocations/${firstAllocation.id}`); @@ -83,20 +98,24 @@ module('Acceptance | search', function(hooks) { await Layout.navbar.search.groups[4].options[0].click(); assert.equal(currentURL(), '/csi/plugins/xyz-plugin'); - const fuzzySearchQueries = server.pretender.handledRequests - .filterBy('url', '/v1/search/fuzzy'); + const fuzzySearchQueries = server.pretender.handledRequests.filterBy('url', '/v1/search/fuzzy'); - const featureDetectionQueries = fuzzySearchQueries - .filter(request => request.requestBody.includes('feature-detection-query')); + const featureDetectionQueries = fuzzySearchQueries.filter(request => + request.requestBody.includes('feature-detection-query') + ); - assert.ok(featureDetectionQueries.length, 1, 'expect the feature detection query to only run once'); + assert.ok( + featureDetectionQueries.length, + 1, + 'expect the feature detection query to only run once' + ); const realFuzzySearchQuery = fuzzySearchQueries[1]; assert.deepEqual(JSON.parse(realFuzzySearchQuery.requestBody), { - 'Context': 'all', - 'Namespace': '*', - 'Text': 'xy' + Context: 'all', + Namespace: '*', + Text: 'xy', }); }); @@ -106,7 +125,11 @@ module('Acceptance | search', function(hooks) { await selectSearch(Layout.navbar.search.scope, 'q'); assert.ok(Layout.navbar.search.noOptionsShown); - assert.equal(server.pretender.handledRequests.filterBy('url', '/v1/search/fuzzy').length, 1, 'expect the feature detection query'); + assert.equal( + server.pretender.handledRequests.filterBy('url', '/v1/search/fuzzy').length, + 1, + 'expect the feature detection query' + ); }); test('when fuzzy search is disabled on the server, the search control is hidden', async function(assert) {