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.
This commit is contained in:
Jai Bhagat 2021-07-26 17:23:21 -04:00
parent 1440b562e0
commit e7f0cd28f3
3 changed files with 88 additions and 43 deletions

View File

@ -58,32 +58,40 @@ export default class GlobalSearchControl extends Component {
const allTaskGroupResults = results.Matches.groups || []; const allTaskGroupResults = results.Matches.groups || [];
const allCSIPluginResults = results.Matches.plugins || []; const allCSIPluginResults = results.Matches.plugins || [];
const jobResults = allJobResults.slice(0, MAXIMUM_RESULTS).map(({ ID: name, Scope: [ namespace, id ]}) => ({ const jobResults = allJobResults
type: 'job', .slice(0, MAXIMUM_RESULTS)
id, .map(({ ID: name, Scope: [namespace, id] }) => ({
namespace, type: 'job',
label: `${name} @ ${namespace}`, id,
})); namespace,
label: `${name} > ${namespace}`,
}));
const nodeResults = allNodeResults.slice(0, MAXIMUM_RESULTS).map(({ ID: name, Scope: [ id ]}) => ({ const nodeResults = allNodeResults
type: 'node', .slice(0, MAXIMUM_RESULTS)
id, .map(({ ID: name, Scope: [id] }) => ({
label: name, type: 'node',
})); id,
label: name,
}));
const allocationResults = allAllocationResults.slice(0, MAXIMUM_RESULTS).map(({ ID: name, Scope: [ namespace, id ]}) => ({ const allocationResults = allAllocationResults
type: 'allocation', .slice(0, MAXIMUM_RESULTS)
id, .map(({ ID: name, Scope: [namespace, id] }) => ({
label: `${name} @ ${namespace}`, type: 'allocation',
})); id,
label: `${name} > ${namespace}`,
}));
const taskGroupResults = allTaskGroupResults.slice(0, MAXIMUM_RESULTS).map(({ ID: id, Scope: [ namespace, jobId ]}) => ({ const taskGroupResults = allTaskGroupResults
type: 'task-group', .slice(0, MAXIMUM_RESULTS)
id, .map(({ ID: id, Scope: [namespace, jobId] }) => ({
namespace, type: 'task-group',
jobId, id,
label: id, namespace,
})); jobId,
label: id,
}));
const csiPluginResults = allCSIPluginResults.slice(0, MAXIMUM_RESULTS).map(({ ID: id }) => ({ const csiPluginResults = allCSIPluginResults.slice(0, MAXIMUM_RESULTS).map(({ ID: id }) => ({
type: 'plugin', type: 'plugin',
@ -109,17 +117,32 @@ export default class GlobalSearchControl extends Component {
options: nodeResults, options: nodeResults,
}, },
{ {
groupName: resultsGroupLabel('Allocations', allocationResults, allAllocationResults, allocationsTruncated), groupName: resultsGroupLabel(
'Allocations',
allocationResults,
allAllocationResults,
allocationsTruncated
),
options: allocationResults, options: allocationResults,
}, },
{ {
groupName: resultsGroupLabel('Task Groups', taskGroupResults, allTaskGroupResults, taskGroupsTruncated), groupName: resultsGroupLabel(
'Task Groups',
taskGroupResults,
allTaskGroupResults,
taskGroupsTruncated
),
options: taskGroupResults, options: taskGroupResults,
}, },
{ {
groupName: resultsGroupLabel('CSI Plugins', csiPluginResults, allCSIPluginResults, csiPluginsTruncated), groupName: resultsGroupLabel(
'CSI Plugins',
csiPluginResults,
allCSIPluginResults,
csiPluginsTruncated
),
options: csiPluginResults, options: csiPluginResults,
} },
]; ];
}) })
search; search;

View File

@ -612,7 +612,7 @@ export default function() {
const transformedAllocs = matchedAllocs.models.map(alloc => ({ const transformedAllocs = matchedAllocs.models.map(alloc => ({
ID: alloc.name, ID: alloc.name,
Scope: [(alloc.namespace || {}).id, alloc.id], Scope: [alloc.namespace || 'default', alloc.id],
})); }));
const transformedGroups = matchedGroups.models.map(group => ({ const transformedGroups = matchedGroups.models.map(group => ({
@ -622,7 +622,7 @@ export default function() {
const transformedJobs = matchedJobs.models.map(job => ({ const transformedJobs = matchedJobs.models.map(job => ({
ID: job.name, ID: job.name,
Scope: [job.namespace, job.id], Scope: [job.namespace || 'default', job.id],
})); }));
const transformedNodes = matchedNodes.models.map(node => ({ const transformedNodes = matchedNodes.models.map(node => ({

View File

@ -16,8 +16,19 @@ module('Acceptance | search', function(hooks) {
server.create('node', { name: 'xyz' }); server.create('node', { name: 'xyz' });
const otherNode = server.create('node', { name: 'ghi' }); const otherNode = server.create('node', { name: 'ghi' });
server.create('job', { id: 'vwxyz', namespaceId: 'default', groupsCount: 1, groupTaskCount: 1 }); server.create('job', {
server.create('job', { id: 'xyz', name: 'xyz job', namespaceId: 'default', groupsCount: 1, groupTaskCount: 1 }); 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 }); server.create('job', { id: 'abc', namespaceId: 'default', groupsCount: 1, groupTaskCount: 1 });
const firstAllocation = server.schema.allocations.all().models[0]; const firstAllocation = server.schema.allocations.all().models[0];
@ -35,8 +46,8 @@ module('Acceptance | search', function(hooks) {
search.groups[0].as(jobs => { search.groups[0].as(jobs => {
assert.equal(jobs.name, 'Jobs (2)'); assert.equal(jobs.name, 'Jobs (2)');
assert.equal(jobs.options.length, 2); assert.equal(jobs.options.length, 2);
assert.equal(jobs.options[0].text, 'vwxyz @ default'); assert.equal(jobs.options[0].text, 'vwxyz > default');
assert.equal(jobs.options[1].text, 'xyz job @ default'); assert.equal(jobs.options[1].text, 'xyz job > default');
}); });
search.groups[1].as(clients => { search.groups[1].as(clients => {
@ -70,7 +81,10 @@ module('Acceptance | search', function(hooks) {
assert.equal(currentURL(), `/clients/${otherNode.id}`); assert.equal(currentURL(), `/clients/${otherNode.id}`);
await selectSearch(Layout.navbar.search.scope, firstAllocation.name); 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(); await Layout.navbar.search.groups[2].options[0].click();
assert.equal(currentURL(), `/allocations/${firstAllocation.id}`); assert.equal(currentURL(), `/allocations/${firstAllocation.id}`);
@ -83,20 +97,24 @@ module('Acceptance | search', function(hooks) {
await Layout.navbar.search.groups[4].options[0].click(); await Layout.navbar.search.groups[4].options[0].click();
assert.equal(currentURL(), '/csi/plugins/xyz-plugin'); assert.equal(currentURL(), '/csi/plugins/xyz-plugin');
const fuzzySearchQueries = server.pretender.handledRequests const fuzzySearchQueries = server.pretender.handledRequests.filterBy('url', '/v1/search/fuzzy');
.filterBy('url', '/v1/search/fuzzy');
const featureDetectionQueries = fuzzySearchQueries const featureDetectionQueries = fuzzySearchQueries.filter(request =>
.filter(request => request.requestBody.includes('feature-detection-query')); 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]; const realFuzzySearchQuery = fuzzySearchQueries[1];
assert.deepEqual(JSON.parse(realFuzzySearchQuery.requestBody), { assert.deepEqual(JSON.parse(realFuzzySearchQuery.requestBody), {
'Context': 'all', Context: 'all',
'Namespace': '*', Namespace: '*',
'Text': 'xy' Text: 'xy',
}); });
}); });
@ -106,7 +124,11 @@ module('Acceptance | search', function(hooks) {
await selectSearch(Layout.navbar.search.scope, 'q'); await selectSearch(Layout.navbar.search.scope, 'q');
assert.ok(Layout.navbar.search.noOptionsShown); 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) { test('when fuzzy search is disabled on the server, the search control is hidden', async function(assert) {