+/* eslint-disable camelcase */
( function ( mw, $ ) {
QUnit.module( 'mediawiki.rcfilters - FiltersViewModel', QUnit.newMwEnvironment( {
messages: {
type: 'send_unselected_if_any',
filters: [
{
- name: 'group1filter1',
+ name: 'filter1',
label: 'Group 1: Filter 1',
description: 'Description of Filter 1 in Group 1'
},
{
- name: 'group1filter2',
+ name: 'filter2',
label: 'Group 1: Filter 2',
description: 'Description of Filter 2 in Group 1'
}
type: 'send_unselected_if_any',
filters: [
{
- name: 'group2filter1',
+ name: 'filter1',
label: 'Group 2: Filter 1',
description: 'Description of Filter 1 in Group 2'
},
{
- name: 'group2filter2',
+ name: 'filter2',
label: 'Group 2: Filter 2',
description: 'Description of Filter 2 in Group 2'
}
type: 'string_options',
filters: [
{
- name: 'group3filter1',
+ name: 'filter1',
label: 'Group 3: Filter 1',
description: 'Description of Filter 1 in Group 3'
},
{
- name: 'group3filter2',
+ name: 'filter2',
label: 'Group 3: Filter 2',
description: 'Description of Filter 2 in Group 3'
}
model.initializeFilters( definition );
assert.ok(
- model.getItemByName( 'group1filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
- model.getItemByName( 'group1filter2' ) instanceof mw.rcfilters.dm.FilterItem &&
- model.getItemByName( 'group2filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
- model.getItemByName( 'group2filter2' ) instanceof mw.rcfilters.dm.FilterItem &&
- model.getItemByName( 'group3filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
- model.getItemByName( 'group3filter2' ) instanceof mw.rcfilters.dm.FilterItem,
+ model.getItemByName( 'group1__filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
+ model.getItemByName( 'group1__filter2' ) instanceof mw.rcfilters.dm.FilterItem &&
+ model.getItemByName( 'group2__filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
+ model.getItemByName( 'group2__filter2' ) instanceof mw.rcfilters.dm.FilterItem &&
+ model.getItemByName( 'group3__filter1' ) instanceof mw.rcfilters.dm.FilterItem &&
+ model.getItemByName( 'group3__filter2' ) instanceof mw.rcfilters.dm.FilterItem,
'Filters instantiated and stored correctly'
);
assert.deepEqual(
model.getSelectedState(),
{
- group1filter1: false,
- group1filter2: false,
- group2filter1: false,
- group2filter2: false,
- group3filter1: false,
- group3filter2: false
+ group1__filter1: false,
+ group1__filter2: false,
+ group2__filter1: false,
+ group2__filter2: false,
+ group3__filter1: false,
+ group3__filter2: false
},
'Initial state of filters'
);
model.toggleFiltersSelected( {
- group1filter1: true,
- group2filter2: true,
- group3filter1: true
+ group1__filter1: true,
+ group2__filter2: true,
+ group3__filter1: true
} );
assert.deepEqual(
model.getSelectedState(),
{
- group1filter1: true,
- group1filter2: false,
- group2filter1: false,
- group2filter2: true,
- group3filter1: true,
- group3filter2: false
+ group1__filter1: true,
+ group1__filter2: false,
+ group2__filter1: false,
+ group2__filter2: true,
+ group3__filter1: true,
+ group3__filter2: false
},
'Updating filter states correctly'
);
} );
+ QUnit.test( 'Default filters', function ( assert ) {
+ var definition = [ {
+ name: 'group1',
+ title: 'Group 1',
+ type: 'send_unselected_if_any',
+ filters: [
+ {
+ name: 'hidefilter1',
+ label: 'Show filter 1',
+ description: 'Description of Filter 1 in Group 1',
+ default: true
+ },
+ {
+ name: 'hidefilter2',
+ label: 'Show filter 2',
+ description: 'Description of Filter 2 in Group 1'
+ },
+ {
+ name: 'hidefilter3',
+ label: 'Show filter 3',
+ description: 'Description of Filter 3 in Group 1',
+ default: true
+ }
+ ]
+ }, {
+ name: 'group2',
+ title: 'Group 2',
+ type: 'send_unselected_if_any',
+ filters: [
+ {
+ name: 'hidefilter4',
+ label: 'Show filter 4',
+ description: 'Description of Filter 1 in Group 2'
+ },
+ {
+ name: 'hidefilter5',
+ label: 'Show filter 5',
+ description: 'Description of Filter 2 in Group 2',
+ default: true
+ },
+ {
+ name: 'hidefilter6',
+ label: 'Show filter 6',
+ description: 'Description of Filter 3 in Group 2'
+ }
+ ]
+ }, {
+
+ name: 'group3',
+ title: 'Group 3',
+ type: 'string_options',
+ separator: ',',
+ default: 'filter8',
+ filters: [
+ {
+ name: 'filter7',
+ label: 'Group 3: Filter 1',
+ description: 'Description of Filter 1 in Group 3'
+ },
+ {
+ name: 'filter8',
+ label: 'Group 3: Filter 2',
+ description: 'Description of Filter 2 in Group 3'
+ },
+ {
+ name: 'filter9',
+ label: 'Group 3: Filter 3',
+ description: 'Description of Filter 3 in Group 3'
+ }
+ ]
+ } ],
+ model = new mw.rcfilters.dm.FiltersViewModel();
+
+ model.initializeFilters( definition );
+
+ // Empty query = only default values
+ assert.deepEqual(
+ model.getDefaultParams(),
+ {
+ hidefilter1: '1',
+ hidefilter2: '0',
+ hidefilter3: '1',
+ hidefilter4: '0',
+ hidefilter5: '1',
+ hidefilter6: '0',
+ group3: 'filter8'
+ },
+ 'Default parameters are stored properly per filter and group'
+ );
+ } );
+
QUnit.test( 'Finding matching filters', function ( assert ) {
var matches,
definition = [ {
type: 'send_unselected_if_any',
filters: [
{
- name: 'group1filter1',
+ name: 'filter1',
label: 'group1filter1-label',
description: 'group1filter1-desc'
},
{
- name: 'group1filter2',
+ name: 'filter2',
label: 'group1filter2-label',
description: 'group1filter2-desc'
}
type: 'send_unselected_if_any',
filters: [
{
- name: 'group2filter1',
+ name: 'filter1',
label: 'group2filter1-label',
description: 'group2filter1-desc'
},
{
- name: 'group2filter2',
+ name: 'filter2',
label: 'group2filter2-label',
description: 'group2filter2-desc'
}
{
query: 'group',
expectedMatches: {
- group1: [ 'group1filter1', 'group1filter2' ],
- group2: [ 'group2filter1' ]
+ group1: [ 'group1__filter1', 'group1__filter2' ],
+ group2: [ 'group2__filter1' ]
},
reason: 'Finds filters starting with the query string'
},
{
query: 'filter 2 in group',
expectedMatches: {
- group1: [ 'group1filter2' ],
- group2: [ 'group2filter2' ]
+ group1: [ 'group1__filter2' ],
+ group2: [ 'group2__filter2' ]
},
reason: 'Finds filters containing the query string in their description'
},
{
query: 'title',
expectedMatches: {
- group1: [ 'group1filter1', 'group1filter2' ],
- group2: [ 'group2filter1', 'group2filter2' ]
+ group1: [ 'group1__filter1', 'group1__filter2' ],
+ group2: [ 'group2__filter1', 'group2__filter2' ]
},
reason: 'Finds filters containing the query string in their group title'
}
assert.deepEqual(
model.getParametersFromFilters(),
{
- hidefilter1: 0,
- hidefilter2: 0,
- hidefilter3: 0,
- hidefilter4: 0,
- hidefilter5: 0,
- hidefilter6: 0,
+ hidefilter1: '0',
+ hidefilter2: '0',
+ hidefilter3: '0',
+ hidefilter4: '0',
+ hidefilter5: '0',
+ hidefilter6: '0',
group3: ''
},
'Unselected filters return all parameters falsey or \'\'.'
// Select 1 filter
model.toggleFiltersSelected( {
- hidefilter1: true,
- hidefilter2: false,
- hidefilter3: false,
- hidefilter4: false,
- hidefilter5: false,
- hidefilter6: false
+ group1__hidefilter1: true,
+ group1__hidefilter2: false,
+ group1__hidefilter3: false,
+ group2__hidefilter4: false,
+ group2__hidefilter5: false,
+ group2__hidefilter6: false
} );
// Only one filter in one group
assert.deepEqual(
model.getParametersFromFilters(),
{
// Group 1 (one selected, the others are true)
- hidefilter1: 0,
- hidefilter2: 1,
- hidefilter3: 1,
+ hidefilter1: '0',
+ hidefilter2: '1',
+ hidefilter3: '1',
// Group 2 (nothing is selected, all false)
- hidefilter4: 0,
- hidefilter5: 0,
- hidefilter6: 0,
+ hidefilter4: '0',
+ hidefilter5: '0',
+ hidefilter6: '0',
group3: ''
},
'One filters in one "send_unselected_if_any" group returns the other parameters truthy.'
// Select 2 filters
model.toggleFiltersSelected( {
- hidefilter1: true,
- hidefilter2: true,
- hidefilter3: false,
- hidefilter4: false,
- hidefilter5: false,
- hidefilter6: false
+ group1__hidefilter1: true,
+ group1__hidefilter2: true,
+ group1__hidefilter3: false,
+ group2__hidefilter4: false,
+ group2__hidefilter5: false,
+ group2__hidefilter6: false
} );
// Two selected filters in one group
assert.deepEqual(
model.getParametersFromFilters(),
{
// Group 1 (two selected, the others are true)
- hidefilter1: 0,
- hidefilter2: 0,
- hidefilter3: 1,
+ hidefilter1: '0',
+ hidefilter2: '0',
+ hidefilter3: '1',
// Group 2 (nothing is selected, all false)
- hidefilter4: 0,
- hidefilter5: 0,
- hidefilter6: 0,
+ hidefilter4: '0',
+ hidefilter5: '0',
+ hidefilter6: '0',
group3: ''
},
- 'One filters in one "send_unselected_if_any" group returns the other parameters truthy.'
+ 'Two filters in one "send_unselected_if_any" group returns the other parameters truthy.'
);
// Select 3 filters
model.toggleFiltersSelected( {
- hidefilter1: true,
- hidefilter2: true,
- hidefilter3: true,
- hidefilter4: false,
- hidefilter5: false,
- hidefilter6: false
+ group1__hidefilter1: true,
+ group1__hidefilter2: true,
+ group1__hidefilter3: true,
+ group2__hidefilter4: false,
+ group2__hidefilter5: false,
+ group2__hidefilter6: false
} );
// All filters of the group are selected == this is the same as not selecting any
assert.deepEqual(
model.getParametersFromFilters(),
{
// Group 1 (all selected, all false)
- hidefilter1: 0,
- hidefilter2: 0,
- hidefilter3: 0,
+ hidefilter1: '0',
+ hidefilter2: '0',
+ hidefilter3: '0',
// Group 2 (nothing is selected, all false)
- hidefilter4: 0,
- hidefilter5: 0,
- hidefilter6: 0,
+ hidefilter4: '0',
+ hidefilter5: '0',
+ hidefilter6: '0',
group3: ''
},
'All filters selected in one "send_unselected_if_any" group returns all parameters falsy.'
// Select 1 filter from string_options
model.toggleFiltersSelected( {
- filter7: true,
- filter8: false,
- filter9: false
+ group3__filter7: true,
+ group3__filter8: false,
+ group3__filter9: false
} );
// All filters of the group are selected == this is the same as not selecting any
assert.deepEqual(
model.getParametersFromFilters(),
{
// Group 1 (all selected, all)
- hidefilter1: 0,
- hidefilter2: 0,
- hidefilter3: 0,
+ hidefilter1: '0',
+ hidefilter2: '0',
+ hidefilter3: '0',
// Group 2 (nothing is selected, all false)
- hidefilter4: 0,
- hidefilter5: 0,
- hidefilter6: 0,
+ hidefilter4: '0',
+ hidefilter5: '0',
+ hidefilter6: '0',
group3: 'filter7'
},
'One filter selected in "string_option" group returns that filter in the value.'
// Select 2 filters from string_options
model.toggleFiltersSelected( {
- filter7: true,
- filter8: true,
- filter9: false
+ group3__filter7: true,
+ group3__filter8: true,
+ group3__filter9: false
} );
// All filters of the group are selected == this is the same as not selecting any
assert.deepEqual(
model.getParametersFromFilters(),
{
// Group 1 (all selected, all)
- hidefilter1: 0,
- hidefilter2: 0,
- hidefilter3: 0,
+ hidefilter1: '0',
+ hidefilter2: '0',
+ hidefilter3: '0',
// Group 2 (nothing is selected, all false)
- hidefilter4: 0,
- hidefilter5: 0,
- hidefilter6: 0,
+ hidefilter4: '0',
+ hidefilter5: '0',
+ hidefilter6: '0',
group3: 'filter7,filter8'
},
'Two filters selected in "string_option" group returns those filters in the value.'
// Select 3 filters from string_options
model.toggleFiltersSelected( {
- filter7: true,
- filter8: true,
- filter9: true
+ group3__filter7: true,
+ group3__filter8: true,
+ group3__filter9: true
} );
// All filters of the group are selected == this is the same as not selecting any
assert.deepEqual(
model.getParametersFromFilters(),
{
// Group 1 (all selected, all)
- hidefilter1: 0,
- hidefilter2: 0,
- hidefilter3: 0,
+ hidefilter1: '0',
+ hidefilter2: '0',
+ hidefilter3: '0',
// Group 2 (nothing is selected, all false)
- hidefilter4: 0,
- hidefilter5: 0,
- hidefilter6: 0,
+ hidefilter4: '0',
+ hidefilter5: '0',
+ hidefilter6: '0',
group3: 'all'
},
'All filters selected in "string_option" group returns \'all\'.'
} );
+ QUnit.test( 'getParametersFromFilters (custom object)', function ( assert ) {
+ var originalState,
+ model = new mw.rcfilters.dm.FiltersViewModel(),
+ definition = [ {
+ name: 'group1',
+ title: 'Group 1',
+ type: 'send_unselected_if_any',
+ filters: [
+ { name: 'hidefilter1', label: 'Hide filter 1', description: '' },
+ { name: 'hidefilter2', label: 'Hide filter 2', description: '' },
+ { name: 'hidefilter3', label: 'Hide filter 3', description: '' }
+ ]
+ }, {
+ name: 'group2',
+ title: 'Group 2',
+ type: 'send_unselected_if_any',
+ filters: [
+ { name: 'hidefilter4', label: 'Hide filter 4', description: '' },
+ { name: 'hidefilter5', label: 'Hide filter 5', description: '' },
+ { name: 'hidefilter6', label: 'Hide filter 6', description: '' }
+ ]
+ }, {
+ name: 'group3',
+ title: 'Group 3',
+ type: 'string_options',
+ separator: ',',
+ filters: [
+ { name: 'filter7', label: 'Hide filter 7', description: '' },
+ { name: 'filter8', label: 'Hide filter 8', description: '' },
+ { name: 'filter9', label: 'Hide filter 9', description: '' }
+ ]
+ } ],
+ cases = [
+ {
+ // This is mocking the cases above, both
+ // - 'Two filters in one "send_unselected_if_any" group returns the other parameters truthy.'
+ // - 'Two filters selected in "string_option" group returns those filters in the value.'
+ input: {
+ group1__hidefilter1: true,
+ group1__hidefilter2: true,
+ group1__hidefilter3: false,
+ group2__hidefilter4: false,
+ group2__hidefilter5: false,
+ group2__hidefilter6: false,
+ group3__filter7: true,
+ group3__filter8: true,
+ group3__filter9: false
+ },
+ expected: {
+ // Group 1 (two selected, the others are true)
+ hidefilter1: '0',
+ hidefilter2: '0',
+ hidefilter3: '1',
+ // Group 2 (nothing is selected, all false)
+ hidefilter4: '0',
+ hidefilter5: '0',
+ hidefilter6: '0',
+ group3: 'filter7,filter8'
+ },
+ msg: 'Given an explicit (complete) filter state object, the result is the same as if the object given represented the model state.'
+ },
+ {
+ // This is mocking case above
+ // - 'One filters in one "send_unselected_if_any" group returns the other parameters truthy.'
+ input: {
+ group1__hidefilter1: 1
+ },
+ expected: {
+ // Group 1 (one selected, the others are true)
+ hidefilter1: '0',
+ hidefilter2: '1',
+ hidefilter3: '1',
+ // Group 2 (nothing is selected, all false)
+ hidefilter4: '0',
+ hidefilter5: '0',
+ hidefilter6: '0',
+ group3: ''
+ },
+ msg: 'Given an explicit (incomplete) filter state object, the result is the same as if the object give represented the model state.'
+ }
+ ];
+
+ model.initializeFilters( definition );
+ // Store original state
+ originalState = model.getSelectedState();
+
+ // Test each case
+ cases.forEach( function ( test ) {
+ assert.deepEqual(
+ model.getParametersFromFilters( test.input ),
+ test.expected,
+ test.msg
+ );
+ } );
+
+ // After doing the above tests, make sure the actual state
+ // of the filter stayed the same
+ assert.deepEqual(
+ model.getSelectedState(),
+ originalState,
+ 'Running the method with external definition to parse does not actually change the state of the model'
+ );
+ } );
+
QUnit.test( 'getFiltersFromParameters', function ( assert ) {
var definition = [ {
name: 'group1',
title: 'Group 3',
type: 'string_options',
separator: ',',
+ default: 'filter8',
filters: [
{
name: 'filter7',
{
name: 'filter8',
label: 'Group 3: Filter 2',
- description: 'Description of Filter 2 in Group 3',
- default: true
+ description: 'Description of Filter 2 in Group 3'
},
{
name: 'filter9',
}
]
} ],
- defaultFilterRepresentation = {
- // Group 1 and 2, "send_unselected_if_any", the values of the filters are "flipped" from the values of the parameters
- hidefilter1: false,
- hidefilter2: true,
- hidefilter3: false,
- hidefilter4: true,
- hidefilter5: false,
- hidefilter6: true,
- // Group 3, "string_options", default values correspond to parameters and filters
- filter7: false,
- filter8: true,
- filter9: false
+ baseFilterRepresentation = {
+ group1__hidefilter1: false,
+ group1__hidefilter2: false,
+ group1__hidefilter3: false,
+ group2__hidefilter4: false,
+ group2__hidefilter5: false,
+ group2__hidefilter6: false,
+ group3__filter7: false,
+ group3__filter8: false,
+ group3__filter9: false
},
model = new mw.rcfilters.dm.FiltersViewModel();
// Empty query = only default values
assert.deepEqual(
model.getFiltersFromParameters( {} ),
- defaultFilterRepresentation,
- 'Empty parameter query results in filters in initial default state'
+ baseFilterRepresentation,
+ 'Empty parameter query results in an object representing all filters set to false'
);
assert.deepEqual(
model.getFiltersFromParameters( {
hidefilter2: '1'
} ),
- $.extend( {}, defaultFilterRepresentation, {
- hidefilter1: false, // The text is "show filter 1"
- hidefilter2: false, // The text is "show filter 2"
- hidefilter3: false // The text is "show filter 3"
+ $.extend( {}, baseFilterRepresentation, {
+ group1__hidefilter1: true, // The text is "show filter 1"
+ group1__hidefilter2: false, // The text is "show filter 2"
+ group1__hidefilter3: true // The text is "show filter 3"
} ),
'One truthy parameter in a group whose other parameters are true by default makes the rest of the filters in the group false (unchecked)'
);
hidefilter2: '1',
hidefilter3: '1'
} ),
- $.extend( {}, defaultFilterRepresentation, {
- hidefilter1: false, // The text is "show filter 1"
- hidefilter2: false, // The text is "show filter 2"
- hidefilter3: false // The text is "show filter 3"
+ $.extend( {}, baseFilterRepresentation, {
+ group1__hidefilter1: false, // The text is "show filter 1"
+ group1__hidefilter2: false, // The text is "show filter 2"
+ group1__hidefilter3: false // The text is "show filter 3"
} ),
'All paremeters in the same \'send_unselected_if_any\' group false is equivalent to none are truthy (checked) in the interface'
);
);
// The result here is ignoring the first toggleFiltersSelected call
- // We should receive default values + hidefilter6 as false
assert.deepEqual(
model.getSelectedState(),
- $.extend( {}, defaultFilterRepresentation, {
- hidefilter5: false,
- hidefilter6: false
+ $.extend( {}, baseFilterRepresentation, {
+ group2__hidefilter4: true,
+ group2__hidefilter5: true,
+ group2__hidefilter6: false
} ),
'getFiltersFromParameters does not care about previous or existing state.'
);
model = new mw.rcfilters.dm.FiltersViewModel();
model.initializeFilters( definition );
- model.toggleFiltersSelected(
- model.getFiltersFromParameters( {
- hidefilter1: '0'
- } )
- );
- model.toggleFiltersSelected(
- model.getFiltersFromParameters( {
- hidefilter1: '1'
- } )
- );
-
- // Simulates minor edits being hidden in preferences, then unhidden via URL
- // override.
- assert.deepEqual(
- model.getSelectedState(),
- defaultFilterRepresentation,
- 'After checking and then unchecking a \'send_unselected_if_any\' filter (without touching other filters in that group), results are default'
- );
-
model.toggleFiltersSelected(
model.getFiltersFromParameters( {
group3: 'filter7'
);
assert.deepEqual(
model.getSelectedState(),
- $.extend( {}, defaultFilterRepresentation, {
- filter7: true,
- filter8: false,
- filter9: false
+ $.extend( {}, baseFilterRepresentation, {
+ group3__filter7: true,
+ group3__filter8: false,
+ group3__filter9: false
} ),
'A \'string_options\' parameter containing 1 value, results in the corresponding filter as checked'
);
);
assert.deepEqual(
model.getSelectedState(),
- $.extend( {}, defaultFilterRepresentation, {
- filter7: true,
- filter8: true,
- filter9: false
+ $.extend( {}, baseFilterRepresentation, {
+ group3__filter7: true,
+ group3__filter8: true,
+ group3__filter9: false
} ),
'A \'string_options\' parameter containing 2 values, results in both corresponding filters as checked'
);
);
assert.deepEqual(
model.getSelectedState(),
- $.extend( {}, defaultFilterRepresentation, {
- filter7: false,
- filter8: false,
- filter9: false
+ $.extend( {}, baseFilterRepresentation, {
+ group3__filter7: true,
+ group3__filter8: true,
+ group3__filter9: true
} ),
- 'A \'string_options\' parameter containing all values, results in all filters of the group as unchecked.'
+ 'A \'string_options\' parameter containing all values, results in all filters of the group as checked.'
);
model.toggleFiltersSelected(
);
assert.deepEqual(
model.getSelectedState(),
- $.extend( {}, defaultFilterRepresentation, {
- filter7: false,
- filter8: false,
- filter9: false
+ $.extend( {}, baseFilterRepresentation, {
+ group3__filter7: true,
+ group3__filter8: true,
+ group3__filter9: true
} ),
- 'A \'string_options\' parameter containing the value \'all\', results in all filters of the group as unchecked.'
+ 'A \'string_options\' parameter containing the value \'all\', results in all filters of the group as checked.'
);
model.toggleFiltersSelected(
);
assert.deepEqual(
model.getSelectedState(),
- $.extend( {}, defaultFilterRepresentation, {
- filter7: true,
- filter8: false,
- filter9: true
+ $.extend( {}, baseFilterRepresentation, {
+ group3__filter7: true,
+ group3__filter8: false,
+ group3__filter9: true
} ),
'A \'string_options\' parameter containing an invalid value, results in the invalid value ignored and the valid corresponding filters checked.'
);
);
} );
- QUnit.test( 'setFiltersToDefaults', function ( assert ) {
- var definition = [ {
- name: 'group1',
- title: 'Group 1',
- type: 'send_unselected_if_any',
- filters: [
- {
- name: 'hidefilter1',
- label: 'Show filter 1',
- description: 'Description of Filter 1 in Group 1',
- default: true
- },
- {
- name: 'hidefilter2',
- label: 'Show filter 2',
- description: 'Description of Filter 2 in Group 1'
- },
- {
- name: 'hidefilter3',
- label: 'Show filter 3',
- description: 'Description of Filter 3 in Group 1',
- default: true
- }
- ]
- }, {
- name: 'group2',
- title: 'Group 2',
- type: 'send_unselected_if_any',
- filters: [
- {
- name: 'hidefilter4',
- label: 'Show filter 4',
- description: 'Description of Filter 1 in Group 2'
- },
- {
- name: 'hidefilter5',
- label: 'Show filter 5',
- description: 'Description of Filter 2 in Group 2',
- default: true
- },
- {
- name: 'hidefilter6',
- label: 'Show filter 6',
- description: 'Description of Filter 3 in Group 2'
- }
- ]
- } ],
- defaultFilterRepresentation = {
- // Group 1 and 2, "send_unselected_if_any", the values of the filters are "flipped" from the values of the parameters
- hidefilter1: false,
- hidefilter2: true,
- hidefilter3: false,
- hidefilter4: true,
- hidefilter5: false,
- hidefilter6: true
- },
- model = new mw.rcfilters.dm.FiltersViewModel();
-
- model.initializeFilters( definition );
-
- assert.deepEqual(
- model.getSelectedState(),
- {
- hidefilter1: false,
- hidefilter2: false,
- hidefilter3: false,
- hidefilter4: false,
- hidefilter5: false,
- hidefilter6: false
- },
- 'Initial state: default filters are not selected (controller selects defaults explicitly).'
- );
-
- model.toggleFiltersSelected( {
- hidefilter1: false,
- hidefilter3: false
- } );
-
- model.setFiltersToDefaults();
-
- assert.deepEqual(
- model.getSelectedState(),
- defaultFilterRepresentation,
- 'Changing values of filters and then returning to defaults still results in default filters being selected.'
- );
- } );
-
QUnit.test( 'Filter interaction: subsets', function ( assert ) {
var definition = [ {
name: 'group1',
]
} ],
baseFullState = {
- filter1: { selected: false, conflicted: false, included: false },
- filter2: { selected: false, conflicted: false, included: false },
- filter3: { selected: false, conflicted: false, included: false }
+ group1__filter1: { selected: false, conflicted: false, included: false },
+ group1__filter2: { selected: false, conflicted: false, included: false },
+ group1__filter3: { selected: false, conflicted: false, included: false }
},
model = new mw.rcfilters.dm.FiltersViewModel();
model.initializeFilters( definition );
// Select a filter that has subset with another filter
model.toggleFiltersSelected( {
- filter1: true
+ group1__filter1: true
} );
- model.reassessFilterInteractions( model.getItemByName( 'filter1' ) );
+ model.reassessFilterInteractions( model.getItemByName( 'group1__filter1' ) );
assert.deepEqual(
model.getFullState(),
$.extend( true, {}, baseFullState, {
- filter1: { selected: true },
- filter2: { included: true },
- filter3: { included: true }
+ group1__filter1: { selected: true },
+ group1__filter2: { included: true },
+ group1__filter3: { included: true }
} ),
'Filters with subsets are represented in the model.'
);
// Select another filter that has a subset with the same previous filter
model.toggleFiltersSelected( {
- filter2: true
+ group1__filter2: true
} );
model.reassessFilterInteractions( model.getItemByName( 'filter2' ) );
assert.deepEqual(
model.getFullState(),
$.extend( true, {}, baseFullState, {
- filter1: { selected: true },
- filter2: { selected: true, included: true },
- filter3: { included: true }
+ group1__filter1: { selected: true },
+ group1__filter2: { selected: true, included: true },
+ group1__filter3: { included: true }
} ),
'Filters that have multiple subsets are represented.'
);
- // Remove one filter (but leave the other) that affects filter2
+ // Remove one filter (but leave the other) that affects filter3
model.toggleFiltersSelected( {
- filter1: false
+ group1__filter1: false
} );
- model.reassessFilterInteractions( model.getItemByName( 'filter1' ) );
+ model.reassessFilterInteractions( model.getItemByName( 'group1__filter1' ) );
assert.deepEqual(
model.getFullState(),
$.extend( true, {}, baseFullState, {
- filter2: { selected: true, included: false },
- filter3: { included: true }
+ group1__filter2: { selected: true, included: false },
+ group1__filter3: { included: true }
} ),
'Removing a filter only un-includes its subset if there is no other filter affecting.'
);
model.toggleFiltersSelected( {
- filter2: false
+ group1__filter2: false
} );
- model.reassessFilterInteractions( model.getItemByName( 'filter2' ) );
+ model.reassessFilterInteractions( model.getItemByName( 'group1__filter2' ) );
assert.deepEqual(
model.getFullState(),
baseFullState,
},
getCurrentItemsMutedState = function () {
return {
- filter1: isCapsuleItemMuted( 'filter1' ),
- filter2: isCapsuleItemMuted( 'filter2' ),
- filter3: isCapsuleItemMuted( 'filter3' ),
- filter4: isCapsuleItemMuted( 'filter4' ),
- filter5: isCapsuleItemMuted( 'filter5' ),
- filter6: isCapsuleItemMuted( 'filter6' )
+ group1__filter1: isCapsuleItemMuted( 'group1__filter1' ),
+ group1__filter2: isCapsuleItemMuted( 'group1__filter2' ),
+ group1__filter3: isCapsuleItemMuted( 'group1__filter3' ),
+ group2__filter4: isCapsuleItemMuted( 'group2__filter4' ),
+ group2__filter5: isCapsuleItemMuted( 'group2__filter5' ),
+ group2__filter6: isCapsuleItemMuted( 'group2__filter6' )
};
},
baseMuteState = {
- filter1: false,
- filter2: false,
- filter3: false,
- filter4: false,
- filter5: false,
- filter6: false
+ group1__filter1: false,
+ group1__filter2: false,
+ group1__filter3: false,
+ group2__filter4: false,
+ group2__filter5: false,
+ group2__filter6: false
};
model.initializeFilters( definition );
// Select most (but not all) items in each group
model.toggleFiltersSelected( {
- filter1: true,
- filter2: true,
- filter4: true,
- filter5: true
+ group1__filter1: true,
+ group1__filter2: true,
+ group2__filter4: true,
+ group2__filter5: true
} );
// Both groups have multiple (but not all) items selected, all items are non-muted
// Select all items in 'fullCoverage' group (group2)
model.toggleFiltersSelected( {
- filter6: true
+ group2__filter6: true
} );
// Group2 (full coverage) has all items selected, all its items are muted
assert.deepEqual(
getCurrentItemsMutedState(),
$.extend( {}, baseMuteState, {
- filter4: true,
- filter5: true,
- filter6: true
+ group2__filter4: true,
+ group2__filter5: true,
+ group2__filter6: true
} ),
'All items in \'full coverage\' group are selected - all items in the group are muted'
);
// Select all items in non 'fullCoverage' group (group1)
model.toggleFiltersSelected( {
- filter3: true
+ group1__filter3: true
} );
// Group1 (full coverage) has all items selected, no items in it are muted (non full coverage)
assert.deepEqual(
getCurrentItemsMutedState(),
$.extend( {}, baseMuteState, {
- filter4: true,
- filter5: true,
- filter6: true
+ group2__filter4: true,
+ group2__filter5: true,
+ group2__filter6: true
} ),
'All items in a non \'full coverage\' group are selected - none of the items in the group are muted'
);
// Uncheck an item from each group
model.toggleFiltersSelected( {
- filter3: false,
- filter5: false
+ group1__filter3: false,
+ group2__filter5: false
} );
assert.deepEqual(
getCurrentItemsMutedState(),
name: 'filter1',
label: '1',
description: '1',
- conflicts: [ 'filter2', 'filter4' ]
+ conflicts: [ { group: 'group2' } ]
},
{
name: 'filter2',
label: '2',
description: '2',
- conflicts: [ 'filter6' ]
+ conflicts: [ { group: 'group2', filter: 'filter6' } ]
},
{
name: 'filter3',
name: 'group2',
title: 'Group 2',
type: 'send_unselected_if_any',
+ conflicts: [ { group: 'group1', filter: 'filter1' } ],
filters: [
{
name: 'filter4',
{
name: 'filter5',
label: '5',
- description: '5',
- conflicts: [ 'filter3' ]
+ description: '5'
},
{
name: 'filter6',
label: '6',
- description: '6'
+ description: '6',
+ conflicts: [ { group: 'group1', filter: 'filter2' } ]
}
]
} ],
baseFullState = {
- filter1: { selected: false, conflicted: false, included: false },
- filter2: { selected: false, conflicted: false, included: false },
- filter3: { selected: false, conflicted: false, included: false },
- filter4: { selected: false, conflicted: false, included: false },
- filter5: { selected: false, conflicted: false, included: false },
- filter6: { selected: false, conflicted: false, included: false }
+ group1__filter1: { selected: false, conflicted: false, included: false },
+ group1__filter2: { selected: false, conflicted: false, included: false },
+ group1__filter3: { selected: false, conflicted: false, included: false },
+ group2__filter4: { selected: false, conflicted: false, included: false },
+ group2__filter5: { selected: false, conflicted: false, included: false },
+ group2__filter6: { selected: false, conflicted: false, included: false }
},
model = new mw.rcfilters.dm.FiltersViewModel();
'Initial state: no conflicts because no selections.'
);
- // Select a filter that has a conflict with another
+ // Select a filter that has a conflict with an entire group
model.toggleFiltersSelected( {
- filter1: true // conflicts: filter2, filter4
+ group1__filter1: true // conflicts: entire of group 2 ( filter4, filter5, filter6)
} );
- model.reassessFilterInteractions( model.getItemByName( 'filter1' ) );
+ model.reassessFilterInteractions( model.getItemByName( 'group1__filter1' ) );
assert.deepEqual(
model.getFullState(),
$.extend( true, {}, baseFullState, {
- filter1: { selected: true },
- filter2: { conflicted: true },
- filter4: { conflicted: true }
+ group1__filter1: { selected: true },
+ group2__filter4: { conflicted: true },
+ group2__filter5: { conflicted: true },
+ group2__filter6: { conflicted: true }
} ),
- 'Selecting a filter set its conflicts list as "conflicted".'
+ 'Selecting a filter that conflicts with a group sets all the conflicted group items as "conflicted".'
);
// Select one of the conflicts (both filters are now conflicted and selected)
model.toggleFiltersSelected( {
- filter4: true // conflicts: filter 1
+ group2__filter4: true // conflicts: filter 1
+ } );
+ model.reassessFilterInteractions( model.getItemByName( 'group2__filter4' ) );
+
+ assert.deepEqual(
+ model.getFullState(),
+ $.extend( true, {}, baseFullState, {
+ group1__filter1: { selected: true, conflicted: true },
+ group2__filter4: { selected: true, conflicted: true },
+ group2__filter5: { conflicted: true },
+ group2__filter6: { conflicted: true }
+ } ),
+ 'Selecting a conflicting filter inside a group, sets both sides to conflicted and selected.'
+ );
+
+ // Reset
+ model = new mw.rcfilters.dm.FiltersViewModel();
+ model.initializeFilters( definition );
+
+ // Select a filter that has a conflict with a specific filter
+ model.toggleFiltersSelected( {
+ group1__filter2: true // conflicts: filter6
+ } );
+ model.reassessFilterInteractions( model.getItemByName( 'group1__filter2' ) );
+
+ assert.deepEqual(
+ model.getFullState(),
+ $.extend( true, {}, baseFullState, {
+ group1__filter2: { selected: true },
+ group2__filter6: { conflicted: true }
+ } ),
+ 'Selecting a filter that conflicts with another filter sets the other as "conflicted".'
+ );
+
+ // Select the conflicting filter
+ model.toggleFiltersSelected( {
+ group2__filter6: true // conflicts: filter2
+ } );
+
+ model.reassessFilterInteractions( model.getItemByName( 'group2__filter6' ) );
+
+ assert.deepEqual(
+ model.getFullState(),
+ $.extend( true, {}, baseFullState, {
+ group1__filter2: { selected: true, conflicted: true },
+ group2__filter6: { selected: true, conflicted: true },
+ // This is added to the conflicts because filter6 is part of group2,
+ // who is in conflict with filter1; note that filter2 also conflicts
+ // with filter6 which means that filter1 conflicts with filter6 (because it's in group2)
+ // and also because its **own sibling** (filter2) is **also** in conflict with the
+ // selected items in group2 (filter6)
+ group1__filter1: { conflicted: true }
+ } ),
+ 'Selecting a conflicting filter with an individual filter, sets both sides to conflicted and selected.'
+ );
+
+ // Now choose a non-conflicting filter from the group
+ model.toggleFiltersSelected( {
+ group2__filter5: true
} );
- model.reassessFilterInteractions( model.getItemByName( 'filter4' ) );
+
+ model.reassessFilterInteractions( model.getItemByName( 'group2__filter5' ) );
assert.deepEqual(
model.getFullState(),
$.extend( true, {}, baseFullState, {
- filter1: { selected: true, conflicted: true },
- filter2: { conflicted: true },
- filter4: { selected: true, conflicted: true }
+ group1__filter2: { selected: true },
+ group2__filter6: { selected: true },
+ group2__filter5: { selected: true }
+ // Filter6 and filter1 are no longer in conflict because
+ // filter5, while it is in conflict with filter1, it is
+ // not in conflict with filter2 - and since filter2 is
+ // selected, it removes the conflict bidirectionally
} ),
- 'Selecting a conflicting filter sets both sides to conflicted and selected.'
+ 'Selecting a non-conflicting filter within the group of a conflicting filter removes the conflicts.'
);
- // Select another filter from filter4 group, meaning:
- // now filter1 no longer conflicts with filter4
+ // Followup on the previous test, unselect filter2 so filter1
+ // is now the only one selected in its own group, and since
+ // it is in conflict with the entire of group2, it means
+ // filter1 is once again conflicted
model.toggleFiltersSelected( {
- filter6: true // conflicts: filter2
+ group1__filter2: false
} );
- model.reassessFilterInteractions( model.getItemByName( 'filter6' ) );
+
+ model.reassessFilterInteractions( model.getItemByName( 'group1__filter2' ) );
assert.deepEqual(
model.getFullState(),
$.extend( true, {}, baseFullState, {
- filter1: { selected: true, conflicted: false }, // No longer conflicts (filter4 is not the only in the group)
- filter2: { conflicted: true }, // While not selected, still in conflict with filter1, which is selected
- filter4: { selected: true, conflicted: false }, // No longer conflicts with filter1
- filter6: { selected: true, conflicted: false }
+ group1__filter1: { conflicted: true },
+ group2__filter6: { selected: true },
+ group2__filter5: { selected: true }
} ),
- 'Selecting a non-conflicting filter from a conflicting group removes the conflict'
+ 'Unselecting an item that did not conflict returns the conflict state.'
);
+
+ // Followup #2: Now actually select filter1, and make everything conflicted
+ model.toggleFiltersSelected( {
+ group1__filter1: true
+ } );
+
+ model.reassessFilterInteractions( model.getItemByName( 'group1__filter1' ) );
+
+ assert.deepEqual(
+ model.getFullState(),
+ $.extend( true, {}, baseFullState, {
+ group1__filter1: { selected: true, conflicted: true },
+ group2__filter6: { selected: true, conflicted: true },
+ group2__filter5: { selected: true, conflicted: true },
+ group2__filter4: { conflicted: true } // Not selected but conflicted because it's in group2
+ } ),
+ 'Selecting an item that conflicts with a whole group makes all selections in that group conflicted.'
+ );
+
+ /* Simple case */
+ // Reset
+ model = new mw.rcfilters.dm.FiltersViewModel();
+ model.initializeFilters( definition );
+
+ // Select a filter that has a conflict with a specific filter
+ model.toggleFiltersSelected( {
+ group1__filter2: true // conflicts: filter6
+ } );
+
+ model.reassessFilterInteractions( model.getItemByName( 'group1__filter2' ) );
+
+ assert.deepEqual(
+ model.getFullState(),
+ $.extend( true, {}, baseFullState, {
+ group1__filter2: { selected: true },
+ group2__filter6: { conflicted: true }
+ } ),
+ 'Simple case: Selecting a filter that conflicts with another filter sets the other as "conflicted".'
+ );
+
+ model.toggleFiltersSelected( {
+ group1__filter3: true // conflicts: filter6
+ } );
+
+ model.reassessFilterInteractions( model.getItemByName( 'group1__filter3' ) );
+
+ assert.deepEqual(
+ model.getFullState(),
+ $.extend( true, {}, baseFullState, {
+ group1__filter2: { selected: true },
+ group1__filter3: { selected: true }
+ } ),
+ 'Simple case: Selecting a filter that is not in conflict removes the conflict.'
+ );
+
} );
QUnit.test( 'Filter highlights', function ( assert ) {
'Highlight is enabled on toggle.'
);
- model.setHighlightColor( 'filter1', 'color1' );
- model.setHighlightColor( 'filter2', 'color2' );
+ model.setHighlightColor( 'group1__filter1', 'color1' );
+ model.setHighlightColor( 'group1__filter2', 'color2' );
assert.deepEqual(
model.getHighlightedItems().map( function ( item ) {
return item.getName();
} ),
[
- 'filter1',
- 'filter2'
+ 'group1__filter1',
+ 'group1__filter2'
],
'Highlighted items are highlighted.'
);
assert.equal(
- model.getItemByName( 'filter1' ).getHighlightColor(),
+ model.getItemByName( 'group1__filter1' ).getHighlightColor(),
'color1',
'Item highlight color is set.'
);
- model.setHighlightColor( 'filter1', 'color1changed' );
+ model.setHighlightColor( 'group1__filter1', 'color1changed' );
assert.equal(
- model.getItemByName( 'filter1' ).getHighlightColor(),
+ model.getItemByName( 'group1__filter1' ).getHighlightColor(),
'color1changed',
'Item highlight color is changed on setHighlightColor.'
);
- model.clearHighlightColor( 'filter1' );
+ model.clearHighlightColor( 'group1__filter1' );
assert.deepEqual(
model.getHighlightedItems().map( function ( item ) {
return item.getName();
} ),
[
- 'filter2'
+ 'group1__filter2'
],
'Clear highlight from an item results in the item no longer being highlighted.'
);
model = new mw.rcfilters.dm.FiltersViewModel();
model.initializeFilters( definition );
- model.setHighlightColor( 'filter1', 'color1' );
- model.setHighlightColor( 'filter2', 'color2' );
- model.setHighlightColor( 'filter3', 'color3' );
+ model.setHighlightColor( 'group1__filter1', 'color1' );
+ model.setHighlightColor( 'group1__filter2', 'color2' );
+ model.setHighlightColor( 'group1__filter3', 'color3' );
assert.deepEqual(
model.getHighlightedItems().map( function ( item ) {
return item.getName();
} ),
[
- 'filter1',
- 'filter2',
- 'filter3'
+ 'group1__filter1',
+ 'group1__filter2',
+ 'group1__filter3'
],
'Even if highlights are not enabled, the items remember their highlight state'
// NOTE: When actually displaying the highlights, the UI checks whether
model = new mw.rcfilters.dm.FiltersViewModel();
model.initializeFilters( definition );
- model.setHighlightColor( 'filter1', 'color1' );
- model.setHighlightColor( 'filter6', 'color6' );
+ model.setHighlightColor( 'group1__filter1', 'color1' );
+ model.setHighlightColor( 'group1__filter6', 'color6' );
assert.deepEqual(
model.getHighlightedItems().map( function ( item ) {
return item.getName();
} ),
[
- 'filter1'
+ 'group1__filter1'
],
'Items without a specified class identifier are not highlighted.'
);