github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/tests/acceptance/search-test.js (about) 1 /* eslint-disable ember-a11y-testing/a11y-audit-called */ 2 /* eslint-disable qunit/require-expect */ 3 import { module, test } from 'qunit'; 4 import { currentURL, triggerEvent, visit } from '@ember/test-helpers'; 5 import { setupApplicationTest } from 'ember-qunit'; 6 import { setupMirage } from 'ember-cli-mirage/test-support'; 7 import Layout from 'nomad-ui/tests/pages/layout'; 8 import JobsList from 'nomad-ui/tests/pages/jobs/list'; 9 import { selectSearch } from 'ember-power-select/test-support'; 10 import Response from 'ember-cli-mirage/response'; 11 12 module('Acceptance | search', function (hooks) { 13 setupApplicationTest(hooks); 14 setupMirage(hooks); 15 16 test('search exposes and navigates to results from the fuzzy search endpoint', async function (assert) { 17 server.create('node', { name: 'xyz' }); 18 const otherNode = server.create('node', { name: 'ghi' }); 19 20 server.create('job', { 21 id: 'vwxyz', 22 namespaceId: 'default', 23 groupsCount: 1, 24 groupTaskCount: 1, 25 }); 26 server.create('job', { 27 id: 'xyz', 28 name: 'xyz job', 29 namespaceId: 'default', 30 groupsCount: 1, 31 groupTaskCount: 1, 32 }); 33 server.create('job', { 34 id: 'abc', 35 namespaceId: 'default', 36 groupsCount: 1, 37 groupTaskCount: 1, 38 }); 39 40 const firstAllocation = server.schema.allocations.all().models[0]; 41 const firstTaskGroup = server.schema.taskGroups.all().models[0]; 42 43 server.create('csi-plugin', { id: 'xyz-plugin', createVolumes: false }); 44 45 await visit('/'); 46 47 await selectSearch(Layout.navbar.search.scope, 'xy'); 48 49 Layout.navbar.search.as((search) => { 50 assert.equal(search.groups.length, 5); 51 52 search.groups[0].as((jobs) => { 53 assert.equal(jobs.name, 'Jobs (2)'); 54 assert.equal(jobs.options.length, 2); 55 assert.equal(jobs.options[0].text, 'default > vwxyz'); 56 assert.equal(jobs.options[1].text, 'default > xyz job'); 57 }); 58 59 search.groups[1].as((clients) => { 60 assert.equal(clients.name, 'Clients (1)'); 61 assert.equal(clients.options.length, 1); 62 assert.equal(clients.options[0].text, 'xyz'); 63 }); 64 65 search.groups[2].as((allocs) => { 66 assert.equal(allocs.name, 'Allocations (0)'); 67 assert.equal(allocs.options.length, 0); 68 }); 69 70 search.groups[3].as((groups) => { 71 assert.equal(groups.name, 'Task Groups (0)'); 72 assert.equal(groups.options.length, 0); 73 }); 74 75 search.groups[4].as((plugins) => { 76 assert.equal(plugins.name, 'CSI Plugins (1)'); 77 assert.equal(plugins.options.length, 1); 78 assert.equal(plugins.options[0].text, 'xyz-plugin'); 79 }); 80 }); 81 82 await Layout.navbar.search.groups[0].options[1].click(); 83 assert.equal(currentURL(), '/jobs/xyz'); 84 85 await selectSearch(Layout.navbar.search.scope, otherNode.name); 86 await Layout.navbar.search.groups[1].options[0].click(); 87 assert.equal(currentURL(), `/clients/${otherNode.id}`); 88 89 await selectSearch(Layout.navbar.search.scope, firstAllocation.name); 90 assert.equal( 91 Layout.navbar.search.groups[2].options[0].text, 92 `${firstAllocation.namespace} > ${firstAllocation.name}` 93 ); 94 await Layout.navbar.search.groups[2].options[0].click(); 95 assert.equal(currentURL(), `/allocations/${firstAllocation.id}`); 96 97 await selectSearch(Layout.navbar.search.scope, firstTaskGroup.name); 98 assert.equal( 99 Layout.navbar.search.groups[3].options[0].text, 100 `default > vwxyz > ${firstTaskGroup.name}` 101 ); 102 await Layout.navbar.search.groups[3].options[0].click(); 103 assert.equal(currentURL(), `/jobs/vwxyz/${firstTaskGroup.name}`); 104 105 await selectSearch(Layout.navbar.search.scope, 'xy'); 106 await Layout.navbar.search.groups[4].options[0].click(); 107 assert.equal(currentURL(), '/csi/plugins/xyz-plugin'); 108 109 const fuzzySearchQueries = server.pretender.handledRequests.filterBy( 110 'url', 111 '/v1/search/fuzzy' 112 ); 113 114 const featureDetectionQueries = fuzzySearchQueries.filter((request) => 115 request.requestBody.includes('feature-detection-query') 116 ); 117 118 assert.equal( 119 featureDetectionQueries.length, 120 1, 121 'expect the feature detection query to only run once' 122 ); 123 124 const realFuzzySearchQuery = fuzzySearchQueries[1]; 125 126 assert.deepEqual(JSON.parse(realFuzzySearchQuery.requestBody), { 127 Context: 'all', 128 Namespace: '*', 129 Text: 'xy', 130 }); 131 }); 132 133 test('search does not perform a request when only one character has been entered', async function (assert) { 134 await visit('/'); 135 136 await selectSearch(Layout.navbar.search.scope, 'q'); 137 138 assert.ok(Layout.navbar.search.noOptionsShown); 139 assert.equal( 140 server.pretender.handledRequests.filterBy('url', '/v1/search/fuzzy') 141 .length, 142 1, 143 'expect the feature detection query' 144 ); 145 }); 146 147 test('when fuzzy search is disabled on the server, the search control is hidden', async function (assert) { 148 server.post('/search/fuzzy', function () { 149 return new Response(500, {}, ''); 150 }); 151 152 await visit('/'); 153 154 assert.ok(Layout.navbar.search.isHidden); 155 }); 156 157 test('results are truncated at 10 per group', async function (assert) { 158 server.create('node', { name: 'xyz' }); 159 160 for (let i = 0; i < 11; i++) { 161 server.create('job', { id: `job-${i}`, namespaceId: 'default' }); 162 } 163 164 await visit('/'); 165 166 await selectSearch(Layout.navbar.search.scope, 'job'); 167 168 Layout.navbar.search.as((search) => { 169 search.groups[0].as((jobs) => { 170 assert.equal(jobs.name, 'Jobs (showing 10 of 11)'); 171 assert.equal(jobs.options.length, 10); 172 }); 173 }); 174 }); 175 176 test('server-side truncation is indicated in the group label', async function (assert) { 177 server.create('node', { name: 'xyz' }); 178 179 for (let i = 0; i < 21; i++) { 180 server.create('job', { id: `job-${i}`, namespaceId: 'default' }); 181 } 182 183 await visit('/'); 184 185 await selectSearch(Layout.navbar.search.scope, 'job'); 186 187 Layout.navbar.search.as((search) => { 188 search.groups[0].as((jobs) => { 189 assert.equal(jobs.name, 'Jobs (showing 10 of 20+)'); 190 }); 191 }); 192 }); 193 194 test('clicking the search field starts search immediately', async function (assert) { 195 await visit('/'); 196 197 assert.notOk(Layout.navbar.search.field.isPresent); 198 199 await Layout.navbar.search.click(); 200 201 assert.ok(Layout.navbar.search.field.isPresent); 202 }); 203 204 test('pressing slash starts a search', async function (assert) { 205 await visit('/'); 206 207 assert.notOk(Layout.navbar.search.field.isPresent); 208 209 await triggerEvent('.page-layout', 'keydown', { key: '/' }); 210 211 assert.ok(Layout.navbar.search.field.isPresent); 212 }); 213 214 test('pressing slash when an input element is focused does not start a search', async function (assert) { 215 server.create('node'); 216 server.create('job'); 217 218 await visit('/'); 219 220 assert.notOk(Layout.navbar.search.field.isPresent); 221 222 await JobsList.search.click(); 223 await JobsList.search.keydown({ key: '/' }); 224 225 assert.notOk(Layout.navbar.search.field.isPresent); 226 }); 227 });