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