RCFilters: Ignore 'invert' model if there are no namespaces in saved queries
authorMoriel Schottlender <moriel@gmail.com>
Sat, 18 Nov 2017 01:43:37 +0000 (17:43 -0800)
committerMoriel Schottlender <moriel@gmail.com>
Fri, 1 Dec 2017 00:42:24 +0000 (16:42 -0800)
When comparing and when saving the query, normalize the 'invert'
state so that it represents the **effective** state of the filters.
If there are no namespaces, then 'invert' is irrelevant.

Make sure we ignore that state when it is irrelevant when we save
saved queries and when we compare the current state to a saved query.

Change-Id: If80b50c3d2b90b5116b6b0018a8d56bce2deb7c4

resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.FiltersViewModel.js
resources/src/mediawiki.rcfilters/dm/mw.rcfilters.dm.SavedQueriesModel.js
tests/qunit/suites/resources/mediawiki.rcfilters/dm.SavedQueriesModel.test.js

index d959540..e9e495a 100644 (file)
                } );
        };
 
+       /**
+        * Check whether the invert state is a valid one. A valid invert state is one where
+        * there are actual namespaces selected.
+        *
+        * This is done to compare states to previous ones that may have had the invert model
+        * selected but effectively had no namespaces, so are not effectively different than
+        * ones where invert is not selected.
+        *
+        * @return {boolean} Invert is effectively selected
+        */
+       mw.rcfilters.dm.FiltersViewModel.prototype.areNamespacesEffectivelyInverted = function () {
+               return this.getInvertModel().isSelected() &&
+                       this.getSelectedItems().some( function ( itemModel ) {
+                               return itemModel.getGroupModel().getView() === 'namespace';
+                       } );
+       };
+
        /**
         * Get the item that matches the given name
         *
index 1d7934f..49d9bf7 100644 (file)
                                // the given data, if they exist
                                normalizedData.params = model.filtersModel.removeExcludedParams( normalizedData.params );
 
+                               // Correct the invert state for effective selection
+                               if ( normalizedData.params.invert && !normalizedData.params.namespaces ) {
+                                       delete normalizedData.params.invert;
+                               }
+
                                model.cleanupHighlights( normalizedData );
 
                                id = String( id );
                        }
                } );
 
+               // Correct the invert state for effective selection
+               if ( normalizedData.params.invert && !this.filtersModel.areNamespacesEffectivelyInverted() ) {
+                       delete normalizedData.params.invert;
+               }
+
                // Add item
                this.addItems( [
                        new mw.rcfilters.dm.SavedQueryItemModel(
                // Minimize before comparison
                fullQueryComparison = this.filtersModel.getMinimizedParamRepresentation( fullQueryComparison );
 
+               // Correct the invert state for effective selection
+               if ( fullQueryComparison.invert && !this.filtersModel.areNamespacesEffectivelyInverted() ) {
+                       delete fullQueryComparison.invert;
+               }
+
                return this.getItems().filter( function ( item ) {
                        return OO.compare(
                                item.getCombinedData(),
index 58524ec..bf8ab1e 100644 (file)
                                                        label: 'label2',
                                                        data: {
                                                                params: {
-                                                                       filter1: '1',
-                                                                       invert: '1'
+                                                                       filter1: '1' // Invert will be dropped because there are no namespaces
                                                                },
                                                                highlights: {
                                                                        group1__filter1_color: 'c3'
                        data: {
                                params: {
                                        filter1: '1',
-                                       filter2: '1',
-                                       invert: '1'
+                                       filter2: '1'
                                },
                                highlights: {}
                        }
                                group2: 'filter5',
                                filter1: '0',
                                filter2: '0',
-                               invert: '0',
                                group1__filter1_color: 'c5',
                                group3__group3option1_color: 'c1'
                        }
                        'Finding matching item by "dirty" state with 0-base values'
                );
        } );
+
+       QUnit.test( 'Testing invert property', function ( assert ) {
+               var itemID, item,
+                       filtersModel = new mw.rcfilters.dm.FiltersViewModel(),
+                       queriesModel = new mw.rcfilters.dm.SavedQueriesModel( filtersModel ),
+                       viewsDefinition = {
+                               namespace: {
+                                       label: 'Namespaces',
+                                       trigger: ':',
+                                       groups: [ {
+                                               name: 'namespace',
+                                               label: 'Namespaces',
+                                               type: 'string_options',
+                                               separator: ';',
+                                               filters: [
+                                                       { name: 0, label: 'Main', cssClass: 'namespace-0' },
+                                                       { name: 1, label: 'Talk', cssClass: 'namespace-1' },
+                                                       { name: 2, label: 'User', cssClass: 'namespace-2' },
+                                                       { name: 3, label: 'User talk', cssClass: 'namespace-3' }
+                                               ]
+                                       } ]
+                               }
+                       };
+
+               filtersModel.initializeFilters( filterDefinition, viewsDefinition );
+
+               // Start with an empty saved queries model
+               queriesModel.initialize( {} );
+
+               filtersModel.toggleFiltersSelected( {
+                       group1__filter3: true,
+                       invertGroup__invert: true
+               } );
+               itemID = queriesModel.addNewQuery(
+                       'label1', // Label
+                       filtersModel.getMinimizedParamRepresentation(),
+                       true, // isDefault
+                       '2345' // ID
+               );
+               item = queriesModel.getItemByID( itemID );
+
+               assert.deepEqual(
+                       item.getState(),
+                       {
+                               label: 'label1',
+                               data: {
+                                       params: {
+                                               filter1: '1',
+                                               filter2: '1'
+                                       },
+                                       highlights: {}
+                               }
+                       },
+                       'Invert parameter is not saved if there are no namespaces.'
+               );
+
+               // Reset
+               filtersModel.initializeFilters( filterDefinition, viewsDefinition );
+               filtersModel.toggleFiltersSelected( {
+                       group1__filter3: true,
+                       invertGroup__invert: true,
+                       namespace__1: true
+               } );
+               itemID = queriesModel.addNewQuery(
+                       'label1', // Label
+                       filtersModel.getMinimizedParamRepresentation(),
+                       true, // isDefault
+                       '1234' // ID
+               );
+               item = queriesModel.getItemByID( itemID );
+
+               assert.deepEqual(
+                       item.getState(),
+                       {
+                               label: 'label1',
+                               data: {
+                                       params: {
+                                               filter1: '1',
+                                               filter2: '1',
+                                               invert: '1',
+                                               namespace: '1'
+                                       },
+                                       highlights: {}
+                               }
+                       },
+                       'Invert parameter saved if there are namespaces.'
+               );
+       } );
 }( mediaWiki ) );