Enable email settings for ApiBlockTest::testBlockWithEmailBlock
[lhc/web/wiklou.git] / tests / phpunit / includes / OutputPageTest.php
index aa14124..ef8766a 100644 (file)
@@ -12,6 +12,14 @@ class OutputPageTest extends MediaWikiTestCase {
        const SCREEN_MEDIA_QUERY = 'screen and (min-width: 982px)';
        const SCREEN_ONLY_MEDIA_QUERY = 'only screen and (min-width: 982px)';
 
+       // @codingStandardsIgnoreStart Generic.Files.LineLength
+       const RSS_RC_LINK = '<link rel="alternate" type="application/rss+xml" title=" RSS feed" href="/w/index.php?title=Special:RecentChanges&amp;feed=rss"/>';
+       const ATOM_RC_LINK = '<link rel="alternate" type="application/atom+xml" title=" Atom feed" href="/w/index.php?title=Special:RecentChanges&amp;feed=atom"/>';
+
+       const RSS_TEST_LINK = '<link rel="alternate" type="application/rss+xml" title="&quot;Test&quot; RSS feed" href="fake-link"/>';
+       const ATOM_TEST_LINK = '<link rel="alternate" type="application/atom+xml" title="&quot;Test&quot; Atom feed" href="fake-link"/>';
+       // @codingStandardsIgnoreEnd
+
        // Ensure that we don't affect the global ResourceLoader state.
        protected function setUp() {
                parent::setUp();
@@ -51,6 +59,64 @@ class OutputPageTest extends MediaWikiTestCase {
                ];
        }
 
+       private function setupFeedLinks( $feed, $types ) {
+               $outputPage = $this->newInstance( [
+                       'AdvertisedFeedTypes' => $types,
+                       'Feed' => $feed,
+                       'OverrideSiteFeed' => false,
+                       'Script' => '/w',
+                       'Sitename' => false,
+               ] );
+               $outputPage->setTitle( Title::makeTitle( NS_MAIN, 'Test' ) );
+               $this->setMwGlobals( [
+                       'wgScript' => '/w/index.php',
+               ] );
+               return $outputPage;
+       }
+
+       private function assertFeedLinks( $outputPage, $message, $present, $non_present ) {
+               $links = $outputPage->getHeadLinksArray();
+               foreach ( $present as $link ) {
+                       $this->assertContains( $link, $links, $message );
+               }
+               foreach ( $non_present as $link ) {
+                       $this->assertNotContains( $link, $links, $message );
+               }
+       }
+
+       private function assertFeedUILinks( $outputPage, $ui_links ) {
+               if ( $ui_links ) {
+                       $this->assertTrue( $outputPage->isSyndicated(), 'Syndication should be offered' );
+                       $this->assertGreaterThan( 0, count( $outputPage->getSyndicationLinks() ),
+                               'Some syndication links should be there' );
+               } else {
+                       $this->assertFalse( $outputPage->isSyndicated(), 'No syndication should be offered' );
+                       $this->assertEquals( 0, count( $outputPage->getSyndicationLinks() ),
+                               'No syndication links should be there' );
+               }
+       }
+
+       public static function provideFeedLinkData() {
+               return [
+                       [
+                               true, [ 'rss' ], 'Only RSS RC link should be offerred',
+                               [ self::RSS_RC_LINK ], [ self::ATOM_RC_LINK ]
+                       ],
+                       [
+                               true, [ 'atom' ], 'Only Atom RC link should be offerred',
+                               [ self::ATOM_RC_LINK ], [ self::RSS_RC_LINK ]
+                       ],
+                       [
+                               true, [], 'No RC feed formats should be offerred',
+                               [], [ self::ATOM_RC_LINK, self::RSS_RC_LINK ]
+                       ],
+                       [
+                               false, [ 'atom' ], 'No RC feeds should be offerred',
+                               [], [ self::ATOM_RC_LINK, self::RSS_RC_LINK ]
+                       ],
+               ];
+       }
+
        /**
         * @covers OutputPage::setCopyrightUrl
         * @covers OutputPage::getHeadLinksArray
@@ -65,6 +131,67 @@ class OutputPageTest extends MediaWikiTestCase {
                );
        }
 
+       /**
+        * @dataProvider provideFeedLinkData
+        * @covers OutputPage::getHeadLinksArray
+        */
+       public function testRecentChangesFeed( $feed, $advertised_feed_types,
+                               $message, $present, $non_present ) {
+               $outputPage = $this->setupFeedLinks( $feed, $advertised_feed_types );
+               $this->assertFeedLinks( $outputPage, $message, $present, $non_present );
+       }
+
+       public static function provideAdditionalFeedData() {
+               return [
+                       [
+                               true, [ 'atom' ], 'Additional Atom feed should be offered',
+                               'atom',
+                               [ self::ATOM_TEST_LINK, self::ATOM_RC_LINK ],
+                               [ self::RSS_TEST_LINK, self::RSS_RC_LINK ],
+                               true,
+                       ],
+                       [
+                               true, [ 'rss' ], 'Additional RSS feed should be offered',
+                               'rss',
+                               [ self::RSS_TEST_LINK, self::RSS_RC_LINK ],
+                               [ self::ATOM_TEST_LINK, self::ATOM_RC_LINK ],
+                               true,
+                       ],
+                       [
+                               true, [ 'rss' ], 'Additional Atom feed should NOT be offered with RSS enabled',
+                               'atom',
+                               [ self::RSS_RC_LINK ],
+                               [ self::RSS_TEST_LINK, self::ATOM_TEST_LINK, self::ATOM_RC_LINK ],
+                               false,
+                       ],
+                       [
+                               false, [ 'atom' ], 'Additional Atom feed should NOT be offered, all feeds disabled',
+                               'atom',
+                               [],
+                               [
+                                       self::RSS_TEST_LINK, self::ATOM_TEST_LINK,
+                                       self::ATOM_RC_LINK, self::ATOM_RC_LINK,
+                               ],
+                               false,
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideAdditionalFeedData
+        * @covers OutputPage::getHeadLinksArray
+        * @covers OutputPage::addFeedLink
+        * @covers OutputPage::getSyndicationLinks
+        * @covers OutputPage::isSyndicated
+        */
+       public function testAdditionalFeeds( $feed, $advertised_feed_types, $message,
+                       $additional_feed_type, $present, $non_present, $any_ui_links ) {
+               $outputPage = $this->setupFeedLinks( $feed, $advertised_feed_types );
+               $outputPage->addFeedLink( $additional_feed_type, 'fake-link' );
+               $this->assertFeedLinks( $outputPage, $message, $present, $non_present );
+               $this->assertFeedUILinks( $outputPage, $any_ui_links );
+       }
+
        // @todo How to test setStatusCode?
 
        /**
@@ -797,7 +924,7 @@ class OutputPageTest extends MediaWikiTestCase {
         * @covers OutputPage::isSyndicated
         */
        public function testSetSyndicated() {
-               $op = $this->newInstance();
+               $op = $this->newInstance( [ 'Feed' => true ] );
                $this->assertFalse( $op->isSyndicated() );
 
                $op->setSyndicated();
@@ -805,6 +932,12 @@ class OutputPageTest extends MediaWikiTestCase {
 
                $op->setSyndicated( false );
                $this->assertFalse( $op->isSyndicated() );
+
+               $op = $this->newInstance(); // Feed => false by default
+               $this->assertFalse( $op->isSyndicated() );
+
+               $op->setSyndicated();
+               $this->assertFalse( $op->isSyndicated() );
        }
 
        /**
@@ -814,7 +947,7 @@ class OutputPageTest extends MediaWikiTestCase {
         * @covers OutputPage::getSyndicationLinks()
         */
        public function testFeedLinks() {
-               $op = $this->newInstance();
+               $op = $this->newInstance( [ 'Feed' => true ] );
                $this->assertSame( [], $op->getSyndicationLinks() );
 
                $op->addFeedLink( 'not a supported format', 'abc' );
@@ -839,6 +972,13 @@ class OutputPageTest extends MediaWikiTestCase {
                        $expected[$type] = $op->getTitle()->getLocalURL( "feed=$type&apples=oranges" );
                }
                $this->assertSame( $expected, $op->getSyndicationLinks() );
+
+               $op = $this->newInstance(); // Feed => false by default
+               $this->assertSame( [], $op->getSyndicationLinks() );
+
+               $op->addFeedLink( $feedTypes[0], 'def' );
+               $this->assertFalse( $op->isSyndicated() );
+               $this->assertSame( [], $op->getSyndicationLinks() );
        }
 
        /**
@@ -1486,7 +1626,7 @@ class OutputPageTest extends MediaWikiTestCase {
                                        "<p><b>Bold</b>\n</p>",
                                ], 'No section edit links' => [
                                        [ '== Title ==' ],
-                                       "<h2><span class=\"mw-headline\" id=\"Title\">Title</span></h2>\n",
+                                       "<h2><span class=\"mw-headline\" id=\"Title\">Title</span></h2>",
                                ],
                        ],
                        'addWikiTextWithTitle' => [
@@ -1515,7 +1655,7 @@ class OutputPageTest extends MediaWikiTestCase {
                                        '<p>* Not a list</p>',
                                ], 'No section edit links' => [
                                        [ '== Title ==' ],
-                                       "<h2><span class=\"mw-headline\" id=\"Title\">Title</span></h2>\n",
+                                       "<h2><span class=\"mw-headline\" id=\"Title\">Title</span></h2>",
                                ], 'With title at start' => [
                                        [ '* {{PAGENAME}}', true, Title::newFromText( 'Talk:Some page' ) ],
                                        "<ul><li>Some page</li></ul>\n",
@@ -1531,10 +1671,10 @@ class OutputPageTest extends MediaWikiTestCase {
                                // Preferred interface: output is tidied
                                'SpecialNewimages' => [
                                        [ "<p lang='en' dir='ltr'>\nMy message" ],
-                                       '<p lang="en" dir="ltr">' . "\nMy message\n</p>"
+                                       '<p lang="en" dir="ltr">' . "\nMy message</p>"
                                ], 'List at start' => [
                                        [ '* List' ],
-                                       "<ul><li>List</li></ul>\n",
+                                       "<ul><li>List</li></ul>",
                                ], 'List not at start' => [
                                        [ '* <b>Not a list', false ],
                                        '<p>* <b>Not a list</b></p>',
@@ -1546,7 +1686,7 @@ class OutputPageTest extends MediaWikiTestCase {
                                        "<p>* Some page</p>",
                                ], 'EditPage' => [
                                        [ "<div class='mw-editintro'>{{PAGENAME}}", true, Title::newFromText( 'Talk:Some page' ) ],
-                                       '<div class="mw-editintro">' . "Some page\n</div>"
+                                       '<div class="mw-editintro">' . "Some page</div>"
                                ],
                        ],
                        'wrapWikiTextAsInterface' => [
@@ -1555,7 +1695,7 @@ class OutputPageTest extends MediaWikiTestCase {
                                        "<div class=\"wrapperClass\"><p>text\n</p></div>"
                                ], 'Spurious </div>' => [
                                        [ 'wrapperClass', 'text</div><div>more' ],
-                                       "<div class=\"wrapperClass\"><p>text</p><div>more\n</div></div>"
+                                       "<div class=\"wrapperClass\"><p>text</p><div>more</div></div>"
                                ], 'Extra newlines would break <p> wrappers' => [
                                        [ 'two classes', "1\n\n2\n\n3" ],
                                        "<div class=\"two classes\"><p>1\n</p><p>2\n</p><p>3\n</p></div>"
@@ -1829,12 +1969,12 @@ class OutputPageTest extends MediaWikiTestCase {
                return [
                        'List at start of line (content)' => [
                                [ '* List', true, false ],
-                               "<div class=\"mw-parser-output\"><ul><li>List</li></ul>\n</div>",
-                               "<ul><li>List</li></ul>\n",
+                               "<div class=\"mw-parser-output\"><ul><li>List</li></ul></div>",
+                               "<ul><li>List</li></ul>",
                        ],
                        'List at start of line (interface)' => [
                                [ '* List', true, true ],
-                               "<ul><li>List</li></ul>\n",
+                               "<ul><li>List</li></ul>",
                        ],
                        'List not at start (content)' => [
                                [ "* ''Not'' list", false, false ],
@@ -1872,9 +2012,8 @@ class OutputPageTest extends MediaWikiTestCase {
                        'No section edit links' => [
                                [ '== Header ==' ],
                                '<div class="mw-parser-output"><h2><span class="mw-headline" id="Header">' .
-                                       "Header</span></h2>\n</div>",
-                               '<h2><span class="mw-headline" id="Header">Header</span></h2>' .
-                                       "\n",
+                                       "Header</span></h2></div>",
+                               '<h2><span class="mw-headline" id="Header">Header</span></h2>',
                        ]
                ];
        }
@@ -1925,7 +2064,7 @@ class OutputPageTest extends MediaWikiTestCase {
                return [
                        'List at start of line' => [
                                [ '* List', true ],
-                               "<ul><li>List</li></ul>\n",
+                               "<ul><li>List</li></ul>",
                        ],
                        'List not at start' => [
                                [ "* ''Not'' list", false ],
@@ -1944,8 +2083,7 @@ class OutputPageTest extends MediaWikiTestCase {
                        ],
                        'No section edit links' => [
                                [ '== Header ==' ],
-                               '<h2><span class="mw-headline" id="Header">Header</span></h2>' .
-                                       "\n",
+                               '<h2><span class="mw-headline" id="Header">Header</span></h2>',
                        ]
                ];
        }
@@ -2573,7 +2711,7 @@ class OutputPageTest extends MediaWikiTestCase {
                        // Single only=scripts load
                        [
                                [ 'test.foo', ResourceLoaderModule::TYPE_SCRIPTS ],
-                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
+                               "<script nonce=\"secret\">(RLQ=window.RLQ||[]).push(function(){"
                                        . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?lang=en\u0026modules=test.foo\u0026only=scripts\u0026skin=fallback");'
                                        . "});</script>"
                        ],
@@ -2586,14 +2724,14 @@ class OutputPageTest extends MediaWikiTestCase {
                        // Private embed (only=scripts)
                        [
                                [ 'test.quux', ResourceLoaderModule::TYPE_SCRIPTS ],
-                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
+                               "<script nonce=\"secret\">(RLQ=window.RLQ||[]).push(function(){"
                                        . "mw.test.baz({token:123});\nmw.loader.state({\"test.quux\":\"ready\"});"
                                        . "});</script>"
                        ],
                        // Load private module (combined)
                        [
                                [ 'test.quux', ResourceLoaderModule::TYPE_COMBINED ],
-                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
+                               "<script nonce=\"secret\">(RLQ=window.RLQ||[]).push(function(){"
                                        . "mw.loader.implement(\"test.quux@1ev0ijv\",function($,jQuery,require,module){"
                                        . "mw.test.baz({token:123});},{\"css\":[\".mw-icon{transition:none}"
                                        . "\"]});});</script>"
@@ -2611,7 +2749,7 @@ class OutputPageTest extends MediaWikiTestCase {
                        // Load two modules in separate groups
                        [
                                [ [ 'test.group.foo', 'test.group.bar' ], ResourceLoaderModule::TYPE_COMBINED ],
-                               "<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
+                               "<script nonce=\"secret\">(RLQ=window.RLQ||[]).push(function(){"
                                        . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?lang=en\u0026modules=test.group.bar\u0026skin=fallback");'
                                        . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?lang=en\u0026modules=test.group.foo\u0026skin=fallback");'
                                        . "});</script>"