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&feed=rss"/>';
+ const ATOM_RC_LINK = '<link rel="alternate" type="application/atom+xml" title=" Atom feed" href="/w/index.php?title=Special:RecentChanges&feed=atom"/>';
+
+ const RSS_TEST_LINK = '<link rel="alternate" type="application/rss+xml" title=""Test" RSS feed" href="fake-link"/>';
+ const ATOM_TEST_LINK = '<link rel="alternate" type="application/atom+xml" title=""Test" Atom feed" href="fake-link"/>';
+ // @codingStandardsIgnoreEnd
+
// Ensure that we don't affect the global ResourceLoader state.
protected function setUp() {
parent::setUp();
];
}
+ 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
);
}
+ /**
+ * @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?
/**
* @covers OutputPage::isSyndicated
*/
public function testSetSyndicated() {
- $op = $this->newInstance();
+ $op = $this->newInstance( [ 'Feed' => true ] );
$this->assertFalse( $op->isSyndicated() );
$op->setSyndicated();
$op->setSyndicated( false );
$this->assertFalse( $op->isSyndicated() );
+
+ $op = $this->newInstance(); // Feed => false by default
+ $this->assertFalse( $op->isSyndicated() );
+
+ $op->setSyndicated();
+ $this->assertFalse( $op->isSyndicated() );
}
/**
* @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' );
$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() );
}
/**
"<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' => [
'<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",
// 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>',
"<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' => [
"<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>"
// @todo Make sure to test the following in addParserOutputMetadata() as well when we add tests
// for them:
// * addModules()
- // * addModuleScripts()
// * addModuleStyles()
// * addJsConfigVars()
// * enableOOUI()
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 ],
'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>',
]
];
}
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 ],
],
'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>',
]
];
}
[
[ 'test.foo', ResourceLoaderModule::TYPE_SCRIPTS ],
"<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
- . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.foo\u0026only=scripts\u0026skin=fallback");'
+ . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?lang=en\u0026modules=test.foo\u0026only=scripts\u0026skin=fallback");'
. "});</script>"
],
// Multiple only=styles load
[
[ [ 'test.baz', 'test.foo', 'test.bar' ], ResourceLoaderModule::TYPE_STYLES ],
- '<link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?debug=false&lang=en&modules=test.bar%2Cbaz%2Cfoo&only=styles&skin=fallback"/>'
+ '<link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?lang=en&modules=test.bar%2Cbaz%2Cfoo&only=styles&skin=fallback"/>'
],
// Private embed (only=scripts)
[
// noscript group
[
[ 'test.noscript', ResourceLoaderModule::TYPE_STYLES ],
- '<noscript><link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?debug=false&lang=en&modules=test.noscript&only=styles&skin=fallback"/></noscript>'
+ '<noscript><link rel="stylesheet" href="http://127.0.0.1:8080/w/load.php?lang=en&modules=test.noscript&only=styles&skin=fallback"/></noscript>'
],
// Load two modules in separate groups
[
[ [ 'test.group.foo', 'test.group.bar' ], ResourceLoaderModule::TYPE_COMBINED ],
"<script nonce=\"secret\">(window.RLQ=window.RLQ||[]).push(function(){"
- . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.bar\u0026skin=fallback");'
- . 'mw.loader.load("http://127.0.0.1:8080/w/load.php?debug=false\u0026lang=en\u0026modules=test.group.foo\u0026skin=fallback");'
+ . '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>"
],
];
'default logged-out' => [
'exemptStyleModules' => [ 'site' => [ 'site.styles' ] ],
'<meta name="ResourceLoaderDynamicStyles" content=""/>' . "\n" .
- '<link rel="stylesheet" href="/w/load.php?debug=false&lang=en&modules=site.styles&only=styles&skin=fallback"/>',
+ '<link rel="stylesheet" href="/w/load.php?lang=en&modules=site.styles&only=styles&skin=fallback"/>',
],
'default logged-in' => [
'exemptStyleModules' => [ 'site' => [ 'site.styles' ], 'user' => [ 'user.styles' ] ],
'<meta name="ResourceLoaderDynamicStyles" content=""/>' . "\n" .
- '<link rel="stylesheet" href="/w/load.php?debug=false&lang=en&modules=site.styles&only=styles&skin=fallback"/>' . "\n" .
- '<link rel="stylesheet" href="/w/load.php?debug=false&lang=en&modules=user.styles&only=styles&skin=fallback&version=1ai9g6t"/>',
+ '<link rel="stylesheet" href="/w/load.php?lang=en&modules=site.styles&only=styles&skin=fallback"/>' . "\n" .
+ '<link rel="stylesheet" href="/w/load.php?lang=en&modules=user.styles&only=styles&skin=fallback&version=1ai9g6t"/>',
],
'custom modules' => [
'exemptStyleModules' => [
'user' => [ 'user.styles', 'example.user' ],
],
'<meta name="ResourceLoaderDynamicStyles" content=""/>' . "\n" .
- '<link rel="stylesheet" href="/w/load.php?debug=false&lang=en&modules=example.site.a%2Cb&only=styles&skin=fallback"/>' . "\n" .
- '<link rel="stylesheet" href="/w/load.php?debug=false&lang=en&modules=site.styles&only=styles&skin=fallback"/>' . "\n" .
- '<link rel="stylesheet" href="/w/load.php?debug=false&lang=en&modules=example.user&only=styles&skin=fallback&version=0a56zyi"/>' . "\n" .
- '<link rel="stylesheet" href="/w/load.php?debug=false&lang=en&modules=user.styles&only=styles&skin=fallback&version=1ai9g6t"/>',
+ '<link rel="stylesheet" href="/w/load.php?lang=en&modules=example.site.a%2Cb&only=styles&skin=fallback"/>' . "\n" .
+ '<link rel="stylesheet" href="/w/load.php?lang=en&modules=site.styles&only=styles&skin=fallback"/>' . "\n" .
+ '<link rel="stylesheet" href="/w/load.php?lang=en&modules=example.user&only=styles&skin=fallback&version=0a56zyi"/>' . "\n" .
+ '<link rel="stylesheet" href="/w/load.php?lang=en&modules=user.styles&only=styles&skin=fallback&version=1ai9g6t"/>',
],
];
// phpcs:enable