Merge "Revert "ApiSandbox: Display params as JSON on request page""
[lhc/web/wiklou.git] / tests / qunit / suites / resources / mediawiki.rcfilters / dm.FiltersViewModel.test.js
1 ( function ( mw, $ ) {
2 QUnit.module( 'mediawiki.rcfilters - FiltersViewModel' );
3
4 QUnit.test( 'Setting up filters', function ( assert ) {
5 var definition = {
6 group1: {
7 title: 'Group 1',
8 type: 'send_unselected_if_any',
9 filters: [
10 {
11 name: 'group1filter1',
12 label: 'Group 1: Filter 1',
13 description: 'Description of Filter 1 in Group 1'
14 },
15 {
16 name: 'group1filter2',
17 label: 'Group 1: Filter 2',
18 description: 'Description of Filter 2 in Group 1'
19 }
20 ]
21 },
22 group2: {
23 title: 'Group 2',
24 type: 'send_unselected_if_any',
25 filters: [
26 {
27 name: 'group2filter1',
28 label: 'Group 2: Filter 1',
29 description: 'Description of Filter 1 in Group 2'
30 },
31 {
32 name: 'group2filter2',
33 label: 'Group 2: Filter 2',
34 description: 'Description of Filter 2 in Group 2'
35 }
36 ]
37 },
38 group3: {
39 title: 'Group 3',
40 type: 'string_options',
41 filters: [
42 {
43 name: 'group3filter1',
44 label: 'Group 3: Filter 1',
45 description: 'Description of Filter 1 in Group 3'
46 },
47 {
48 name: 'group3filter2',
49 label: 'Group 3: Filter 2',
50 description: 'Description of Filter 2 in Group 3'
51 }
52 ]
53 }
54 },
55 model = new mw.rcfilters.dm.FiltersViewModel();
56
57 model.initializeFilters( definition );
58
59 assert.ok(
60 model.getItemByName( 'group1filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
61 model.getItemByName( 'group1filter2' ) instanceof mw.rcfilters.dm.FilterItem &&
62 model.getItemByName( 'group2filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
63 model.getItemByName( 'group2filter2' ) instanceof mw.rcfilters.dm.FilterItem &&
64 model.getItemByName( 'group3filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
65 model.getItemByName( 'group3filter2' ) instanceof mw.rcfilters.dm.FilterItem,
66 'Filters instantiated and stored correctly'
67 );
68
69 assert.deepEqual(
70 model.getState(),
71 {
72 group1filter1: false,
73 group1filter2: false,
74 group2filter1: false,
75 group2filter2: false,
76 group3filter1: false,
77 group3filter2: false
78 },
79 'Initial state of filters'
80 );
81
82 model.updateFilters( {
83 group1filter1: true,
84 group2filter2: true,
85 group3filter1: true
86 } );
87 assert.deepEqual(
88 model.getState(),
89 {
90 group1filter1: true,
91 group1filter2: false,
92 group2filter1: false,
93 group2filter2: true,
94 group3filter1: true,
95 group3filter2: false
96 },
97 'Updating filter states correctly'
98 );
99 } );
100
101 QUnit.test( 'Finding matching filters', function ( assert ) {
102 var matches,
103 definition = {
104 group1: {
105 title: 'Group 1',
106 type: 'send_unselected_if_any',
107 filters: [
108 {
109 name: 'group1filter1',
110 label: 'Group 1: Filter 1',
111 description: 'Description of Filter 1 in Group 1'
112 },
113 {
114 name: 'group1filter2',
115 label: 'Group 1: Filter 2',
116 description: 'Description of Filter 2 in Group 1'
117 }
118 ]
119 },
120 group2: {
121 title: 'Group 2',
122 type: 'send_unselected_if_any',
123 filters: [
124 {
125 name: 'group2filter1',
126 label: 'Group 2: Filter 1',
127 description: 'Description of Filter 1 in Group 2'
128 },
129 {
130 name: 'group2filter2',
131 label: 'Group 2: Filter 2',
132 description: 'Description of Filter 2 in Group 2'
133 }
134 ]
135 }
136 },
137 model = new mw.rcfilters.dm.FiltersViewModel();
138
139 model.initializeFilters( definition );
140
141 matches = model.findMatches( 'group 1' );
142 assert.equal(
143 matches.group1.length,
144 2,
145 'findMatches finds correct group with correct number of results'
146 );
147
148 assert.deepEqual(
149 matches.group1.map( function ( item ) { return item.getName(); } ),
150 [ 'group1filter1', 'group1filter2' ],
151 'findMatches finds the correct items within a single group'
152 );
153
154 matches = model.findMatches( 'filter 1' );
155 assert.ok(
156 matches.group1.length === 1 && matches.group2.length === 1,
157 'findMatches finds correct number of results in multiple groups'
158 );
159
160 assert.deepEqual(
161 [
162 matches.group1.map( function ( item ) { return item.getName(); } ),
163 matches.group2.map( function ( item ) { return item.getName(); } )
164 ],
165 [
166 [ 'group1filter1' ],
167 [ 'group2filter1' ]
168 ],
169 'findMatches finds the correct items within multiple groups'
170 );
171
172 matches = model.findMatches( 'foo' );
173 assert.ok(
174 $.isEmptyObject( matches ),
175 'findMatches returns an empty object when no results found'
176 );
177 } );
178
179 QUnit.test( 'getParametersFromFilters', function ( assert ) {
180 var definition = {
181 group1: {
182 title: 'Group 1',
183 type: 'send_unselected_if_any',
184 filters: [
185 {
186 name: 'hidefilter1',
187 label: 'Group 1: Filter 1',
188 description: 'Description of Filter 1 in Group 1'
189 },
190 {
191 name: 'hidefilter2',
192 label: 'Group 1: Filter 2',
193 description: 'Description of Filter 2 in Group 1'
194 },
195 {
196 name: 'hidefilter3',
197 label: 'Group 1: Filter 3',
198 description: 'Description of Filter 3 in Group 1'
199 }
200 ]
201 },
202 group2: {
203 title: 'Group 2',
204 type: 'send_unselected_if_any',
205 filters: [
206 {
207 name: 'hidefilter4',
208 label: 'Group 2: Filter 1',
209 description: 'Description of Filter 1 in Group 2'
210 },
211 {
212 name: 'hidefilter5',
213 label: 'Group 2: Filter 2',
214 description: 'Description of Filter 2 in Group 2'
215 },
216 {
217 name: 'hidefilter6',
218 label: 'Group 2: Filter 3',
219 description: 'Description of Filter 3 in Group 2'
220 }
221 ]
222 },
223 group3: {
224 title: 'Group 3',
225 type: 'string_options',
226 separator: ',',
227 filters: [
228 {
229 name: 'filter7',
230 label: 'Group 3: Filter 1',
231 description: 'Description of Filter 1 in Group 3'
232 },
233 {
234 name: 'filter8',
235 label: 'Group 3: Filter 2',
236 description: 'Description of Filter 2 in Group 3'
237 },
238 {
239 name: 'filter9',
240 label: 'Group 3: Filter 3',
241 description: 'Description of Filter 3 in Group 3'
242 }
243 ]
244 }
245 },
246 model = new mw.rcfilters.dm.FiltersViewModel();
247
248 model.initializeFilters( definition );
249
250 // Starting with all filters unselected
251 assert.deepEqual(
252 model.getParametersFromFilters(),
253 {
254 hidefilter1: 0,
255 hidefilter2: 0,
256 hidefilter3: 0,
257 hidefilter4: 0,
258 hidefilter5: 0,
259 hidefilter6: 0,
260 group3: 'all',
261 },
262 'Unselected filters return all parameters falsey or \'all\'.'
263 );
264
265 // Select 1 filter
266 model.updateFilters( {
267 hidefilter1: true,
268 hidefilter2: false,
269 hidefilter3: false,
270 hidefilter4: false,
271 hidefilter5: false,
272 hidefilter6: false
273 } );
274 // Only one filter in one group
275 assert.deepEqual(
276 model.getParametersFromFilters(),
277 {
278 // Group 1 (one selected, the others are true)
279 hidefilter1: 0,
280 hidefilter2: 1,
281 hidefilter3: 1,
282 // Group 2 (nothing is selected, all false)
283 hidefilter4: 0,
284 hidefilter5: 0,
285 hidefilter6: 0,
286 group3: 'all'
287 },
288 'One filters in one "send_unselected_if_any" group returns the other parameters truthy.'
289 );
290
291 // Select 2 filters
292 model.updateFilters( {
293 hidefilter1: true,
294 hidefilter2: true,
295 hidefilter3: false,
296 hidefilter4: false,
297 hidefilter5: false,
298 hidefilter6: false
299 } );
300 // Two selected filters in one group
301 assert.deepEqual(
302 model.getParametersFromFilters(),
303 {
304 // Group 1 (two selected, the others are true)
305 hidefilter1: 0,
306 hidefilter2: 0,
307 hidefilter3: 1,
308 // Group 2 (nothing is selected, all false)
309 hidefilter4: 0,
310 hidefilter5: 0,
311 hidefilter6: 0,
312 group3: 'all'
313 },
314 'One filters in one "send_unselected_if_any" group returns the other parameters truthy.'
315 );
316
317 // Select 3 filters
318 model.updateFilters( {
319 hidefilter1: true,
320 hidefilter2: true,
321 hidefilter3: true,
322 hidefilter4: false,
323 hidefilter5: false,
324 hidefilter6: false
325 } );
326 // All filters of the group are selected == this is the same as not selecting any
327 assert.deepEqual(
328 model.getParametersFromFilters(),
329 {
330 // Group 1 (all selected, all false)
331 hidefilter1: 0,
332 hidefilter2: 0,
333 hidefilter3: 0,
334 // Group 2 (nothing is selected, all false)
335 hidefilter4: 0,
336 hidefilter5: 0,
337 hidefilter6: 0,
338 group3: 'all'
339 },
340 'All filters selected in one "send_unselected_if_any" group returns all parameters falsy.'
341 );
342
343 // Select 1 filter from string_options
344 model.updateFilters( {
345 filter7: true,
346 filter8: false,
347 filter9: false
348 } );
349 // All filters of the group are selected == this is the same as not selecting any
350 assert.deepEqual(
351 model.getParametersFromFilters(),
352 {
353 // Group 1 (all selected, all)
354 hidefilter1: 0,
355 hidefilter2: 0,
356 hidefilter3: 0,
357 // Group 2 (nothing is selected, all false)
358 hidefilter4: 0,
359 hidefilter5: 0,
360 hidefilter6: 0,
361 group3: 'filter7'
362 },
363 'One filter selected in "string_option" group returns that filter in the value.'
364 );
365
366 // Select 2 filters from string_options
367 model.updateFilters( {
368 filter7: true,
369 filter8: true,
370 filter9: false
371 } );
372 // All filters of the group are selected == this is the same as not selecting any
373 assert.deepEqual(
374 model.getParametersFromFilters(),
375 {
376 // Group 1 (all selected, all)
377 hidefilter1: 0,
378 hidefilter2: 0,
379 hidefilter3: 0,
380 // Group 2 (nothing is selected, all false)
381 hidefilter4: 0,
382 hidefilter5: 0,
383 hidefilter6: 0,
384 group3: 'filter7,filter8'
385 },
386 'Two filters selected in "string_option" group returns those filters in the value.'
387 );
388
389 // Select 3 filters from string_options
390 model.updateFilters( {
391 filter7: true,
392 filter8: true,
393 filter9: true
394 } );
395 // All filters of the group are selected == this is the same as not selecting any
396 assert.deepEqual(
397 model.getParametersFromFilters(),
398 {
399 // Group 1 (all selected, all)
400 hidefilter1: 0,
401 hidefilter2: 0,
402 hidefilter3: 0,
403 // Group 2 (nothing is selected, all false)
404 hidefilter4: 0,
405 hidefilter5: 0,
406 hidefilter6: 0,
407 group3: 'all'
408 },
409 'All filters selected in "string_option" group returns \'all\'.'
410 );
411
412 } );
413
414 QUnit.test( 'getFiltersFromParameters', function ( assert ) {
415 var definition = {
416 group1: {
417 title: 'Group 1',
418 type: 'send_unselected_if_any',
419 filters: [
420 {
421 name: 'hidefilter1',
422 label: 'Show filter 1',
423 description: 'Description of Filter 1 in Group 1'
424 },
425 {
426 name: 'hidefilter2',
427 label: 'Show filter 2',
428 description: 'Description of Filter 2 in Group 1'
429 },
430 {
431 name: 'hidefilter3',
432 label: 'Show filter 3',
433 description: 'Description of Filter 3 in Group 1'
434 }
435 ]
436 },
437 group2: {
438 title: 'Group 2',
439 type: 'send_unselected_if_any',
440 filters: [
441 {
442 name: 'hidefilter4',
443 label: 'Show filter 4',
444 description: 'Description of Filter 1 in Group 2'
445 },
446 {
447 name: 'hidefilter5',
448 label: 'Show filter 5',
449 description: 'Description of Filter 2 in Group 2'
450 },
451 {
452 name: 'hidefilter6',
453 label: 'Show filter 6',
454 description: 'Description of Filter 3 in Group 2'
455 }
456 ]
457 },
458 group3: {
459 title: 'Group 3',
460 type: 'string_options',
461 separator: ',',
462 filters: [
463 {
464 name: 'filter7',
465 label: 'Group 3: Filter 1',
466 description: 'Description of Filter 1 in Group 3'
467 },
468 {
469 name: 'filter8',
470 label: 'Group 3: Filter 2',
471 description: 'Description of Filter 2 in Group 3'
472 },
473 {
474 name: 'filter9',
475 label: 'Group 3: Filter 3',
476 description: 'Description of Filter 3 in Group 3'
477 }
478 ]
479 }
480 },
481 model = new mw.rcfilters.dm.FiltersViewModel();
482
483 model.initializeFilters( definition );
484
485 // Empty query = empty filter definition
486 assert.deepEqual(
487 model.getFiltersFromParameters( {} ),
488 {
489 hidefilter1: false, // The text is "show filter 1"
490 hidefilter2: false, // The text is "show filter 2"
491 hidefilter3: false, // The text is "show filter 3"
492 hidefilter4: false, // The text is "show filter 4"
493 hidefilter5: false, // The text is "show filter 5"
494 hidefilter6: false, // The text is "show filter 6"
495 filter7: false,
496 filter8: false,
497 filter9: false
498 },
499 'Empty parameter query results in filters in initial state'
500 );
501
502 assert.deepEqual(
503 model.getFiltersFromParameters( {
504 hidefilter1: '1'
505 } ),
506 {
507 hidefilter1: false, // The text is "show filter 1"
508 hidefilter2: true, // The text is "show filter 2"
509 hidefilter3: true, // The text is "show filter 3"
510 hidefilter4: false, // The text is "show filter 4"
511 hidefilter5: false, // The text is "show filter 5"
512 hidefilter6: false, // The text is "show filter 6"
513 filter7: false,
514 filter8: false,
515 filter9: false
516 },
517 'One falsey parameter in a group makes the rest of the filters in the group truthy (checked) in the interface'
518 );
519
520 assert.deepEqual(
521 model.getFiltersFromParameters( {
522 hidefilter1: '1',
523 hidefilter2: '1'
524 } ),
525 {
526 hidefilter1: false, // The text is "show filter 1"
527 hidefilter2: false, // The text is "show filter 2"
528 hidefilter3: true, // The text is "show filter 3"
529 hidefilter4: false, // The text is "show filter 4"
530 hidefilter5: false, // The text is "show filter 5"
531 hidefilter6: false, // The text is "show filter 6"
532 filter7: false,
533 filter8: false,
534 filter9: false
535 },
536 'Two falsey parameters in a \'send_unselected_if_any\' group makes the rest of the filters in the group truthy (checked) in the interface'
537 );
538
539 assert.deepEqual(
540 model.getFiltersFromParameters( {
541 hidefilter1: '1',
542 hidefilter2: '1',
543 hidefilter3: '1'
544 } ),
545 {
546 // TODO: This will have to be represented as a different state, though.
547 hidefilter1: false, // The text is "show filter 1"
548 hidefilter2: false, // The text is "show filter 2"
549 hidefilter3: false, // The text is "show filter 3"
550 hidefilter4: false, // The text is "show filter 4"
551 hidefilter5: false, // The text is "show filter 5"
552 hidefilter6: false, // The text is "show filter 6"
553 filter7: false,
554 filter8: false,
555 filter9: false
556 },
557 'All paremeters in the same \'send_unselected_if_any\' group false is equivalent to none are truthy (checked) in the interface'
558 );
559
560 // The ones above don't update the model, so we have a clean state.
561
562 model.updateFilters(
563 model.getFiltersFromParameters( {
564 hidefilter1: '1'
565 } )
566 );
567
568 model.updateFilters(
569 model.getFiltersFromParameters( {
570 hidefilter3: '1'
571 } )
572 );
573
574 // 1 and 3 are separately unchecked via hide parameters, 2 should still be
575 // checked.
576 // This can simulate separate filters in the same group being hidden different
577 // ways (e.g. preferences and URL).
578 assert.deepEqual(
579 model.getState(),
580 {
581 hidefilter1: false, // The text is "show filter 1"
582 hidefilter2: true, // The text is "show filter 2"
583 hidefilter3: false, // The text is "show filter 3"
584 hidefilter4: false, // The text is "show filter 4"
585 hidefilter5: false, // The text is "show filter 5"
586 hidefilter6: false, // The text is "show filter 6"
587 filter7: false,
588 filter8: false,
589 filter9: false
590 },
591 'After unchecking 2 of 3 \'send_unselected_if_any\' filters via separate updateFilters calls, only the remaining one is still checked.'
592 );
593
594 // Reset
595 model = new mw.rcfilters.dm.FiltersViewModel();
596 model.initializeFilters( definition );
597
598 model.updateFilters(
599 model.getFiltersFromParameters( {
600 hidefilter1: '1'
601 } )
602 );
603 model.updateFilters(
604 model.getFiltersFromParameters( {
605 hidefilter1: '0'
606 } )
607 );
608
609 // Simulates minor edits being hidden in preferences, then unhidden via URL
610 // override.
611 assert.deepEqual(
612 model.getState(),
613 {
614 hidefilter1: false, // The text is "show filter 1"
615 hidefilter2: false, // The text is "show filter 2"
616 hidefilter3: false, // The text is "show filter 3"
617 hidefilter4: false, // The text is "show filter 4"
618 hidefilter5: false, // The text is "show filter 5"
619 hidefilter6: false, // The text is "show filter 6"
620 filter7: false,
621 filter8: false,
622 filter9: false
623 },
624 'After unchecking then checking a \'send_unselected_if_any\' filter (without touching other filters in that group), all are checked'
625 );
626
627 model.updateFilters(
628 model.getFiltersFromParameters( {
629 group3: 'filter7'
630 } )
631 );
632 assert.deepEqual(
633 model.getState(),
634 {
635 hidefilter1: false, // The text is "show filter 1"
636 hidefilter2: false, // The text is "show filter 2"
637 hidefilter3: false, // The text is "show filter 3"
638 hidefilter4: false, // The text is "show filter 4"
639 hidefilter5: false, // The text is "show filter 5"
640 hidefilter6: false, // The text is "show filter 6"
641 filter7: true,
642 filter8: false,
643 filter9: false
644 },
645 'A \'string_options\' parameter containing 1 value, results in the corresponding filter as checked'
646 );
647
648 model.updateFilters(
649 model.getFiltersFromParameters( {
650 group3: 'filter7,filter8'
651 } )
652 );
653 assert.deepEqual(
654 model.getState(),
655 {
656 hidefilter1: false, // The text is "show filter 1"
657 hidefilter2: false, // The text is "show filter 2"
658 hidefilter3: false, // The text is "show filter 3"
659 hidefilter4: false, // The text is "show filter 4"
660 hidefilter5: false, // The text is "show filter 5"
661 hidefilter6: false, // The text is "show filter 6"
662 filter7: true,
663 filter8: true,
664 filter9: false
665 },
666 'A \'string_options\' parameter containing 2 values, results in both corresponding filters as checked'
667 );
668
669 model.updateFilters(
670 model.getFiltersFromParameters( {
671 group3: 'filter7,filter8,filter9'
672 } )
673 );
674 assert.deepEqual(
675 model.getState(),
676 {
677 hidefilter1: false, // The text is "show filter 1"
678 hidefilter2: false, // The text is "show filter 2"
679 hidefilter3: false, // The text is "show filter 3"
680 hidefilter4: false, // The text is "show filter 4"
681 hidefilter5: false, // The text is "show filter 5"
682 hidefilter6: false, // The text is "show filter 6"
683 filter7: false,
684 filter8: false,
685 filter9: false
686 },
687 'A \'string_options\' parameter containing all values, results in all filters of the group as unchecked.'
688 );
689
690 model.updateFilters(
691 model.getFiltersFromParameters( {
692 group3: 'filter7,filter8,filter9'
693 } )
694 );
695 assert.deepEqual(
696 model.getState(),
697 {
698 hidefilter1: false, // The text is "show filter 1"
699 hidefilter2: false, // The text is "show filter 2"
700 hidefilter3: false, // The text is "show filter 3"
701 hidefilter4: false, // The text is "show filter 4"
702 hidefilter5: false, // The text is "show filter 5"
703 hidefilter6: false, // The text is "show filter 6"
704 filter7: false,
705 filter8: false,
706 filter9: false
707 },
708 'A \'string_options\' parameter containing the value \'all\', results in all filters of the group as unchecked.'
709 );
710
711 model.updateFilters(
712 model.getFiltersFromParameters( {
713 group3: 'filter7,foo,filter9'
714 } )
715 );
716 assert.deepEqual(
717 model.getState(),
718 {
719 hidefilter1: false, // The text is "show filter 1"
720 hidefilter2: false, // The text is "show filter 2"
721 hidefilter3: false, // The text is "show filter 3"
722 hidefilter4: false, // The text is "show filter 4"
723 hidefilter5: false, // The text is "show filter 5"
724 hidefilter6: false, // The text is "show filter 6"
725 filter7: true,
726 filter8: false,
727 filter9: true
728 },
729 'A \'string_options\' parameter containing an invalid value, results in the invalid value ignored and the valid corresponding filters checked.'
730 );
731 } );
732
733 QUnit.test( 'sanitizeStringOptionGroup', function ( assert ) {
734 var definition = {
735 group1: {
736 title: 'Group 1',
737 type: 'string_options',
738 filters: [
739 {
740 name: 'filter1',
741 label: 'Show filter 1',
742 description: 'Description of Filter 1 in Group 1'
743 },
744 {
745 name: 'filter2',
746 label: 'Show filter 2',
747 description: 'Description of Filter 2 in Group 1'
748 },
749 {
750 name: 'filter3',
751 label: 'Show filter 3',
752 description: 'Description of Filter 3 in Group 1'
753 }
754 ]
755 }
756 },
757 model = new mw.rcfilters.dm.FiltersViewModel();
758
759 model.initializeFilters( definition );
760
761 assert.deepEqual(
762 model.sanitizeStringOptionGroup( 'group1', [ 'filter1', 'filter1', 'filter2' ] ),
763 [ 'filter1', 'filter2' ],
764 'Remove duplicate values'
765 );
766
767 assert.deepEqual(
768 model.sanitizeStringOptionGroup( 'group1', [ 'filter1', 'foo', 'filter2' ] ),
769 [ 'filter1', 'filter2' ],
770 'Remove invalid values'
771 );
772
773 assert.deepEqual(
774 model.sanitizeStringOptionGroup( 'group1', [ 'filter1', 'all', 'filter2' ] ),
775 [ 'all' ],
776 'If any value is "all", the only value is "all".'
777 );
778 } );
779 }( mediaWiki, jQuery ) );