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 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 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 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 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 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;

View File

@ -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 => ({

View File

@ -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 => {
@ -70,7 +81,10 @@ module('Acceptance | search', function(hooks) {
assert.equal(currentURL(), `/clients/${otherNode.id}`);
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 +97,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 +124,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) {