Catrope has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/365430 )

Change subject: Add unit tests for ChangeTags::modifyDisplayQuery()
......................................................................

Add unit tests for ChangeTags::modifyDisplayQuery()

The rest of ChangeTags.php should have tests too, but this is a start.

Also fix up ChangeTags::modifyDisplayQuery() to work when strings
are passed for certain parameters, which its documentation claims
it supports but which leads to errors in practice.

Change-Id: I2fe61bcb716a369a14a45c2843817a6557d44f7c
---
M includes/changetags/ChangeTags.php
A tests/phpunit/includes/changetags/ChangeTagsTest.php
2 files changed, 257 insertions(+), 6 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/30/365430/1

diff --git a/includes/changetags/ChangeTags.php 
b/includes/changetags/ChangeTags.php
index 14c2012..e1f83d5 100644
--- a/includes/changetags/ChangeTags.php
+++ b/includes/changetags/ChangeTags.php
@@ -653,7 +653,7 @@
         * @param string|array $fields Fields used in query, see 
Database::select
         * @param string|array $conds Conditions used in query, see 
Database::select
         * @param array $join_conds Join conditions, see Database::select
-        * @param array $options Options, see Database::select
+        * @param string|array $options Options, see Database::select
         * @param bool|string|array $filter_tag Tag(s) to select on
         *
         * @throws MWException When unable to determine appropriate JOIN 
condition for tagging
@@ -667,18 +667,19 @@
                }
 
                // Figure out which ID field to use
-               if ( in_array( 'recentchanges', $tables ) ) {
+               if ( in_array( 'recentchanges', (array)$tables ) ) {
                        $join_cond = 'ct_rc_id=rc_id';
-               } elseif ( in_array( 'logging', $tables ) ) {
+               } elseif ( in_array( 'logging', (array)$tables ) ) {
                        $join_cond = 'ct_log_id=log_id';
-               } elseif ( in_array( 'revision', $tables ) ) {
+               } elseif ( in_array( 'revision', (array)$tables ) ) {
                        $join_cond = 'ct_rev_id=rev_id';
-               } elseif ( in_array( 'archive', $tables ) ) {
+               } elseif ( in_array( 'archive', (array)$tables ) ) {
                        $join_cond = 'ct_rev_id=ar_rev_id';
                } else {
                        throw new MWException( 'Unable to determine appropriate 
JOIN condition for tagging.' );
                }
 
+               $fields = (array)$fields;
                $fields['ts_tags'] = wfGetDB( DB_REPLICA 
)->buildGroupConcatField(
                        ',', 'change_tag', 'ct_tag', $join_cond
                );
@@ -687,10 +688,13 @@
                        // Somebody wants to filter on a tag.
                        // Add an INNER JOIN on change_tag
 
+                       $tables = (array)$tables;
                        $tables[] = 'change_tag';
                        $join_conds['change_tag'] = [ 'INNER JOIN', $join_cond 
];
+                       $conds = (array)$conds;
                        $conds['ct_tag'] = $filter_tag;
-                       if ( count( $filter_tag ) > 1 && !in_array( 'DISTINCT', 
$options ) ) {
+                       if ( count( $filter_tag ) > 1 && !in_array( 'DISTINCT', 
(array)$options ) ) {
+                               $options = (array)$options;
                                $options[] = 'DISTINCT';
                        }
                }
diff --git a/tests/phpunit/includes/changetags/ChangeTagsTest.php 
b/tests/phpunit/includes/changetags/ChangeTagsTest.php
new file mode 100644
index 0000000..2b5f665
--- /dev/null
+++ b/tests/phpunit/includes/changetags/ChangeTagsTest.php
@@ -0,0 +1,247 @@
+<?php
+
+/**
+ * @covers ChangeTags
+ */
+class ChangeTagsTest extends MediaWikiTestCase {
+
+       // TODO only modifyDisplayQuery is tested, nothing else is
+
+       /** @dataProvider provideModifyDisplayQuery */
+       public function testModifyDisplayQuery( $origQuery, $filter_tag, 
$useTags, $modifiedQuery ) {
+               $this->setMwGlobals( 'wgUseTagFilter', $useTags );
+               // HACK resolve deferred group concats (see comment in 
provideModifyDisplayQuery)
+               if ( isset( $modifiedQuery['fields']['ts_tags'] ) ) {
+                       $modifiedQuery['fields']['ts_tags'] = 
call_user_func_array(
+                               [ wfGetDB( DB_REPLICA ), 
'buildGroupConcatField' ],
+                               $modifiedQuery['fields']['ts_tags']
+                       );
+               }
+               if ( isset( $modifiedQuery['exception'] ) ) {
+                       $this->setExpectedException( 
$modifiedQuery['exception'] );
+               }
+               ChangeTags::modifyDisplayQuery(
+                       $origQuery['tables'],
+                       $origQuery['fields'],
+                       $origQuery['conds'],
+                       $origQuery['join_conds'],
+                       $origQuery['options'],
+                       $filter_tag
+               );
+               if ( !isset( $modifiedQuery['exception'] ) ) {
+                       $this->assertArrayEquals(
+                               $modifiedQuery,
+                               $origQuery,
+                               /* ordered = */ false,
+                               /* named = */ true
+                       );
+               }
+       }
+
+       public function provideModifyDisplayQuery() {
+               // HACK if we call $dbr->buildGroupConcatField() now, it will 
return the wrong table names
+               // We have to have the test runner call it instead
+               $groupConcats = [
+                       'recentchanges' => [ ',', 'change_tag', 'ct_tag', 
'ct_rc_id=rc_id' ],
+                       'logging' => [ ',', 'change_tag', 'ct_tag', 
'ct_log_id=log_id' ],
+                       'revision' => [ ',', 'change_tag', 'ct_tag', 
'ct_rev_id=rev_id' ],
+                       'archive' => [ ',', 'change_tag', 'ct_tag', 
'ct_rev_id=ar_rev_id' ],
+               ];
+
+               return [
+                       'simple recentchanges query' => [
+                               [
+                                       'tables' => [ 'recentchanges' ],
+                                       'fields' => [ 'rc_id', 'rc_timestamp' ],
+                                       'conds' => [ "rc_timestamp > 
'20170714183203'" ],
+                                       'join_conds' => [],
+                                       'options' => [ 'ORDER BY' => 
'rc_timestamp DESC' ],
+                               ],
+                               '', // no tag filter
+                               true, // tag filtering enabled
+                               [
+                                       'tables' => [ 'recentchanges' ],
+                                       'fields' => [ 'rc_id', 'rc_timestamp', 
'ts_tags' => $groupConcats['recentchanges'] ],
+                                       'conds' => [ "rc_timestamp > 
'20170714183203'" ],
+                                       'join_conds' => [],
+                                       'options' => [ 'ORDER BY' => 
'rc_timestamp DESC' ],
+                               ]
+                       ],
+                       'simple query with strings' => [
+                               [
+                                       'tables' => 'recentchanges',
+                                       'fields' => 'rc_id',
+                                       'conds' => "rc_timestamp > 
'20170714183203'",
+                                       'join_conds' => [],
+                                       'options' => 'ORDER BY rc_timestamp 
DESC',
+                               ],
+                               '', // no tag filter
+                               true, // tag filtering enabled
+                               [
+                                       'tables' => 'recentchanges',
+                                       'fields' => [ 'rc_id', 'ts_tags' => 
$groupConcats['recentchanges'] ],
+                                       'conds' => "rc_timestamp > 
'20170714183203'",
+                                       'join_conds' => [],
+                                       'options' => 'ORDER BY rc_timestamp 
DESC',
+                               ]
+                       ],
+                       'recentchanges query with single tag filter' => [
+                               [
+                                       'tables' => [ 'recentchanges' ],
+                                       'fields' => [ 'rc_id', 'rc_timestamp' ],
+                                       'conds' => [ "rc_timestamp > 
'20170714183203'" ],
+                                       'join_conds' => [],
+                                       'options' => [ 'ORDER BY' => 
'rc_timestamp DESC' ],
+                               ],
+                               'foo',
+                               true, // tag filtering enabled
+                               [
+                                       'tables' => [ 'recentchanges', 
'change_tag' ],
+                                       'fields' => [ 'rc_id', 'rc_timestamp', 
'ts_tags' => $groupConcats['recentchanges'] ],
+                                       'conds' => [ "rc_timestamp > 
'20170714183203'", 'ct_tag' => 'foo' ],
+                                       'join_conds' => [ 'change_tag' => [ 
'INNER JOIN', 'ct_rc_id=rc_id' ] ],
+                                       'options' => [ 'ORDER BY' => 
'rc_timestamp DESC' ],
+                               ]
+                       ],
+                       'logging query with single tag filter and strings' => [
+                               [
+                                       'tables' => 'logging',
+                                       'fields' => 'log_id',
+                                       'conds' => "log_timestamp > 
'20170714183203'",
+                                       'join_conds' => [],
+                                       'options' => 'ORDER BY log_timestamp 
DESC',
+                               ],
+                               'foo',
+                               true, // tag filtering enabled
+                               [
+                                       'tables' => [ 'logging', 'change_tag' ],
+                                       'fields' => [ 'log_id', 'ts_tags' => 
$groupConcats['logging'] ],
+                                       'conds' => [ "log_timestamp > 
'20170714183203'", 'ct_tag' => 'foo' ],
+                                       'join_conds' => [ 'change_tag' => [ 
'INNER JOIN', 'ct_log_id=log_id' ] ],
+                                       'options' => 'ORDER BY log_timestamp 
DESC',
+                               ]
+                       ],
+                       'revision query with single tag filter' => [
+                               [
+                                       'tables' => [ 'revision' ],
+                                       'fields' => [ 'rev_id', 'rev_timestamp' 
],
+                                       'conds' => [ "rev_timestamp > 
'20170714183203'" ],
+                                       'join_conds' => [],
+                                       'options' => [ 'ORDER BY' => 
'rev_timestamp DESC' ],
+                               ],
+                               'foo',
+                               true, // tag filtering enabled
+                               [
+                                       'tables' => [ 'revision', 'change_tag' 
],
+                                       'fields' => [ 'rev_id', 
'rev_timestamp', 'ts_tags' => $groupConcats['revision'] ],
+                                       'conds' => [ "rev_timestamp > 
'20170714183203'", 'ct_tag' => 'foo' ],
+                                       'join_conds' => [ 'change_tag' => [ 
'INNER JOIN', 'ct_rev_id=rev_id' ] ],
+                                       'options' => [ 'ORDER BY' => 
'rev_timestamp DESC' ],
+                               ]
+                       ],
+                       'archive query with single tag filter' => [
+                               [
+                                       'tables' => [ 'archive' ],
+                                       'fields' => [ 'ar_id', 'ar_timestamp' ],
+                                       'conds' => [ "ar_timestamp > 
'20170714183203'" ],
+                                       'join_conds' => [],
+                                       'options' => [ 'ORDER BY' => 
'ar_timestamp DESC' ],
+                               ],
+                               'foo',
+                               true, // tag filtering enabled
+                               [
+                                       'tables' => [ 'archive', 'change_tag' ],
+                                       'fields' => [ 'ar_id', 'ar_timestamp', 
'ts_tags' => $groupConcats['archive'] ],
+                                       'conds' => [ "ar_timestamp > 
'20170714183203'", 'ct_tag' => 'foo' ],
+                                       'join_conds' => [ 'change_tag' => [ 
'INNER JOIN', 'ct_rev_id=ar_rev_id' ] ],
+                                       'options' => [ 'ORDER BY' => 
'ar_timestamp DESC' ],
+                               ]
+                       ],
+                       'unsupported table name throws exception (even without 
tag filter)' => [
+                               [
+                                       'tables' => [ 'foobar' ],
+                                       'fields' => [ 'fb_id', 'fb_timestamp' ],
+                                       'conds' => [ "fb_timestamp > 
'20170714183203'" ],
+                                       'join_conds' => [],
+                                       'options' => [ 'ORDER BY' => 
'fb_timestamp DESC' ],
+                               ],
+                               '',
+                               true, // tag filtering enabled
+                               [ 'exception' => MWException::class ]
+                       ],
+                       'tag filter ignored when tag filtering is disabled' => [
+                               [
+                                       'tables' => [ 'archive' ],
+                                       'fields' => [ 'ar_id', 'ar_timestamp' ],
+                                       'conds' => [ "ar_timestamp > 
'20170714183203'" ],
+                                       'join_conds' => [],
+                                       'options' => [ 'ORDER BY' => 
'ar_timestamp DESC' ],
+                               ],
+                               'foo',
+                               false, // tag filtering disabled
+                               [
+                                       'tables' => [ 'archive' ],
+                                       'fields' => [ 'ar_id', 'ar_timestamp', 
'ts_tags' => $groupConcats['archive'] ],
+                                       'conds' => [ "ar_timestamp > 
'20170714183203'" ],
+                                       'join_conds' => [],
+                                       'options' => [ 'ORDER BY' => 
'ar_timestamp DESC' ],
+                               ]
+                       ],
+                       'recentchanges query with multiple tag filter' => [
+                               [
+                                       'tables' => [ 'recentchanges' ],
+                                       'fields' => [ 'rc_id', 'rc_timestamp' ],
+                                       'conds' => [ "rc_timestamp > 
'20170714183203'" ],
+                                       'join_conds' => [],
+                                       'options' => [ 'ORDER BY' => 
'rc_timestamp DESC' ],
+                               ],
+                               [ 'foo', 'bar' ],
+                               true, // tag filtering enabled
+                               [
+                                       'tables' => [ 'recentchanges', 
'change_tag' ],
+                                       'fields' => [ 'rc_id', 'rc_timestamp', 
'ts_tags' => $groupConcats['recentchanges'] ],
+                                       'conds' => [ "rc_timestamp > 
'20170714183203'", 'ct_tag' => [ 'foo', 'bar' ] ],
+                                       'join_conds' => [ 'change_tag' => [ 
'INNER JOIN', 'ct_rc_id=rc_id' ] ],
+                                       'options' => [ 'ORDER BY' => 
'rc_timestamp DESC', 'DISTINCT' ],
+                               ]
+                       ],
+                       'recentchanges query with multiple tag filter that 
already has DISTINCT' => [
+                               [
+                                       'tables' => [ 'recentchanges' ],
+                                       'fields' => [ 'rc_id', 'rc_timestamp' ],
+                                       'conds' => [ "rc_timestamp > 
'20170714183203'" ],
+                                       'join_conds' => [],
+                                       'options' => [ 'DISTINCT', 'ORDER BY' 
=> 'rc_timestamp DESC' ],
+                               ],
+                               [ 'foo', 'bar' ],
+                               true, // tag filtering enabled
+                               [
+                                       'tables' => [ 'recentchanges', 
'change_tag' ],
+                                       'fields' => [ 'rc_id', 'rc_timestamp', 
'ts_tags' => $groupConcats['recentchanges'] ],
+                                       'conds' => [ "rc_timestamp > 
'20170714183203'", 'ct_tag' => [ 'foo', 'bar' ] ],
+                                       'join_conds' => [ 'change_tag' => [ 
'INNER JOIN', 'ct_rc_id=rc_id' ] ],
+                                       'options' => [ 'DISTINCT', 'ORDER BY' 
=> 'rc_timestamp DESC' ],
+                               ]
+                       ],
+                       'recentchanges query with multiple tag filter with 
strings' => [
+                               [
+                                       'tables' => 'recentchanges',
+                                       'fields' => 'rc_id',
+                                       'conds' => "rc_timestamp > 
'20170714183203'",
+                                       'join_conds' => [],
+                                       'options' => 'ORDER BY rc_timestamp 
DESC',
+                               ],
+                               [ 'foo', 'bar' ],
+                               true, // tag filtering enabled
+                               [
+                                       'tables' => [ 'recentchanges', 
'change_tag' ],
+                                       'fields' => [ 'rc_id', 'ts_tags' => 
$groupConcats['recentchanges'] ],
+                                       'conds' => [ "rc_timestamp > 
'20170714183203'", 'ct_tag' => [ 'foo', 'bar' ] ],
+                                       'join_conds' => [ 'change_tag' => [ 
'INNER JOIN', 'ct_rc_id=rc_id' ] ],
+                                       'options' => [ 'ORDER BY rc_timestamp 
DESC', 'DISTINCT' ],
+                               ]
+                       ],
+               ];
+       }
+
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/365430
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2fe61bcb716a369a14a45c2843817a6557d44f7c
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Catrope <r...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to