github.com/hernad/nomad@v1.6.112/ui/tests/unit/mixins/searchable-test.js (about)

     1  /**
     2   * Copyright (c) HashiCorp, Inc.
     3   * SPDX-License-Identifier: MPL-2.0
     4   */
     5  
     6  import { alias } from '@ember/object/computed';
     7  import EmberObject, { computed } from '@ember/object';
     8  import { module, test } from 'qunit';
     9  import { setupTest } from 'ember-qunit';
    10  import Searchable from 'nomad-ui/mixins/searchable';
    11  
    12  module('Unit | Mixin | Searchable', function (hooks) {
    13    setupTest(hooks);
    14  
    15    hooks.beforeEach(function () {
    16      this.subject = function () {
    17        // eslint-disable-next-line ember/no-new-mixins
    18        const SearchableObject = EmberObject.extend(Searchable, {
    19          source: null,
    20          searchProps: computed(function () {
    21            return ['id', 'name'];
    22          }),
    23          listToSearch: alias('source'),
    24        });
    25  
    26        this.owner.register('test-container:searchable-object', SearchableObject);
    27        return this.owner.lookup('test-container:searchable-object');
    28      };
    29    });
    30  
    31    test('the searchable mixin does nothing when there is no search term', function (assert) {
    32      const subject = this.subject();
    33      subject.set('source', [
    34        { id: '1', name: 'hello' },
    35        { id: '2', name: 'world' },
    36      ]);
    37  
    38      assert.deepEqual(subject.get('listSearched'), subject.get('source'));
    39    });
    40  
    41    test('the searchable mixin allows for regex search', function (assert) {
    42      const subject = this.subject();
    43      subject.set('source', [
    44        { id: '1', name: 'hello' },
    45        { id: '2', name: 'world' },
    46        { id: '3', name: 'oranges' },
    47      ]);
    48  
    49      subject.set('searchTerm', '.+l+[A-Z]$');
    50      assert.deepEqual(
    51        subject.get('listSearched'),
    52        [
    53          { id: '1', name: 'hello' },
    54          { id: '2', name: 'world' },
    55        ],
    56        'hello and world matched for regex'
    57      );
    58    });
    59  
    60    test('the searchable mixin only searches the declared search props', function (assert) {
    61      const subject = this.subject();
    62      subject.set('source', [
    63        { id: '1', name: 'United States of America', continent: 'North America' },
    64        { id: '2', name: 'Canada', continent: 'North America' },
    65        { id: '3', name: 'Mexico', continent: 'North America' },
    66      ]);
    67  
    68      subject.set('searchTerm', 'America');
    69      assert.deepEqual(
    70        subject.get('listSearched'),
    71        [
    72          {
    73            id: '1',
    74            name: 'United States of America',
    75            continent: 'North America',
    76          },
    77        ],
    78        'Only USA matched, since continent is not a search prop'
    79      );
    80    });
    81  
    82    test('the fuzzy search mode is off by default', function (assert) {
    83      const subject = this.subject();
    84      subject.set('source', [
    85        { id: '1', name: 'United States of America', continent: 'North America' },
    86        { id: '2', name: 'Canada', continent: 'North America' },
    87        { id: '3', name: 'Mexico', continent: 'North America' },
    88      ]);
    89  
    90      subject.set('searchTerm', 'Ameerica');
    91      assert.deepEqual(
    92        subject.get('listSearched'),
    93        [],
    94        'Nothing is matched since America is spelled incorrectly'
    95      );
    96    });
    97  
    98    test('the fuzzy search mode can be enabled', function (assert) {
    99      const subject = this.subject();
   100      subject.set('source', [
   101        { id: '1', name: 'United States of America', continent: 'North America' },
   102        { id: '2', name: 'Canada', continent: 'North America' },
   103        { id: '3', name: 'Mexico', continent: 'North America' },
   104      ]);
   105  
   106      subject.set('fuzzySearchEnabled', true);
   107      subject.set('searchTerm', 'Ameerica');
   108      assert.deepEqual(
   109        subject.get('listSearched'),
   110        [
   111          {
   112            id: '1',
   113            name: 'United States of America',
   114            continent: 'North America',
   115          },
   116        ],
   117        'America is matched due to fuzzy matching'
   118      );
   119    });
   120  
   121    test('the fuzzy search can include match results', function (assert) {
   122      const subject = this.subject();
   123      subject.set('source', [
   124        EmberObject.create({
   125          id: '1',
   126          name: 'United States of America',
   127          continent: 'North America',
   128        }),
   129        EmberObject.create({
   130          id: '2',
   131          name: 'Canada',
   132          continent: 'North America',
   133        }),
   134        EmberObject.create({
   135          id: '3',
   136          name: 'Mexico',
   137          continent: 'North America',
   138        }),
   139      ]);
   140  
   141      subject.set('fuzzySearchEnabled', true);
   142      subject.set('includeFuzzySearchMatches', true);
   143      subject.set('searchTerm', 'Ameerica');
   144      assert.deepEqual(
   145        subject
   146          .get('listSearched')
   147          .map((object) =>
   148            object.getProperties('id', 'name', 'continent', 'fuzzySearchMatches')
   149          ),
   150        [
   151          {
   152            id: '1',
   153            name: 'United States of America',
   154            continent: 'North America',
   155            fuzzySearchMatches: [
   156              {
   157                indices: [
   158                  [2, 2],
   159                  [4, 4],
   160                  [9, 9],
   161                  [11, 11],
   162                  [17, 23],
   163                ],
   164                value: 'United States of America',
   165                key: 'name',
   166              },
   167            ],
   168          },
   169        ],
   170        'America is matched due to fuzzy matching'
   171      );
   172    });
   173  
   174    test('the exact match search mode can be disabled', function (assert) {
   175      const subject = this.subject();
   176      subject.set('source', [
   177        { id: '1', name: 'United States of America', continent: 'North America' },
   178        { id: '2', name: 'Canada', continent: 'North America' },
   179        { id: '3', name: 'Mexico', continent: 'North America' },
   180      ]);
   181  
   182      subject.set('regexSearchProps', []);
   183      subject.set('searchTerm', 'Mexico');
   184  
   185      assert.deepEqual(
   186        subject.get('listSearched'),
   187        [{ id: '3', name: 'Mexico', continent: 'North America' }],
   188        'Mexico is matched exactly'
   189      );
   190  
   191      subject.set('exactMatchEnabled', false);
   192  
   193      assert.deepEqual(
   194        subject.get('listSearched'),
   195        [],
   196        'Nothing is matched now that exactMatch is disabled'
   197      );
   198    });
   199  
   200    test('the regex search mode can be disabled', function (assert) {
   201      const subject = this.subject();
   202      subject.set('source', [
   203        { id: '1', name: 'United States of America', continent: 'North America' },
   204        { id: '2', name: 'Canada', continent: 'North America' },
   205        { id: '3', name: 'Mexico', continent: 'North America' },
   206      ]);
   207  
   208      subject.set('searchTerm', '^.{6}$');
   209      assert.deepEqual(
   210        subject.get('listSearched'),
   211        [
   212          { id: '2', name: 'Canada', continent: 'North America' },
   213          { id: '3', name: 'Mexico', continent: 'North America' },
   214        ],
   215        'Canada and Mexico meet the regex criteria'
   216      );
   217  
   218      subject.set('regexEnabled', false);
   219  
   220      assert.deepEqual(
   221        subject.get('listSearched'),
   222        [],
   223        'Nothing is matched now that regex is disabled'
   224      );
   225    });
   226  
   227    test('each search mode has independent search props', function (assert) {
   228      const subject = this.subject();
   229      subject.set('source', [
   230        { id: '1', name: 'United States of America', continent: 'North America' },
   231        { id: '2', name: 'Canada', continent: 'North America' },
   232        { id: '3', name: 'Mexico', continent: 'North America' },
   233      ]);
   234  
   235      subject.set('fuzzySearchEnabled', true);
   236      subject.set('regexSearchProps', ['id']);
   237      subject.set('exactMatchSearchProps', ['continent']);
   238      subject.set('fuzzySearchProps', ['name']);
   239  
   240      subject.set('searchTerm', 'Nor America');
   241      assert.deepEqual(
   242        subject.get('listSearched'),
   243        [],
   244        'Not an exact match on continent, not a matchAllTokens match on fuzzy, not a regex match on id'
   245      );
   246  
   247      subject.set('searchTerm', 'America States');
   248      assert.deepEqual(
   249        subject.get('listSearched'),
   250        [
   251          {
   252            id: '1',
   253            name: 'United States of America',
   254            continent: 'North America',
   255          },
   256        ],
   257        'Fuzzy match on one country, but not an exact match on continent'
   258      );
   259  
   260      subject.set('searchTerm', '^(.a){3}$');
   261      assert.deepEqual(
   262        subject.get('listSearched'),
   263        [],
   264        'Canada is not matched by the regex because only id is looked at for regex search'
   265      );
   266    });
   267  
   268    test('the resetPagination method is a no-op', function (assert) {
   269      const subject = this.subject();
   270      assert.strictEqual(
   271        subject.get('currentPage'),
   272        undefined,
   273        'No currentPage value set'
   274      );
   275      subject.resetPagination();
   276      assert.strictEqual(
   277        subject.get('currentPage'),
   278        undefined,
   279        'Still no currentPage value set'
   280      );
   281    });
   282  });
   283  
   284  module('Unit | Mixin | Searchable (with pagination)', function (hooks) {
   285    setupTest(hooks);
   286  
   287    hooks.beforeEach(function () {
   288      this.subject = function () {
   289        // eslint-disable-next-line ember/no-new-mixins
   290        const SearchablePaginatedObject = EmberObject.extend(Searchable, {
   291          source: null,
   292          searchProps: computed(function () {
   293            return ['id', 'name'];
   294          }),
   295          listToSearch: alias('source'),
   296          currentPage: 1,
   297        });
   298  
   299        this.owner.register(
   300          'test-container:searchable-paginated-object',
   301          SearchablePaginatedObject
   302        );
   303        return this.owner.lookup('test-container:searchable-paginated-object');
   304      };
   305    });
   306  
   307    test('the resetPagination method sets the currentPage to 1', function (assert) {
   308      const subject = this.subject();
   309      subject.set('currentPage', 5);
   310      assert.equal(
   311        subject.get('currentPage'),
   312        5,
   313        'Current page is something other than 1'
   314      );
   315      subject.resetPagination();
   316      assert.equal(subject.get('currentPage'), 1, 'Current page gets reset to 1');
   317    });
   318  });