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