}
}
+ /**
+ * Return effective list of advertised feed types
+ * @see addFeedLink()
+ *
+ * @return array Array of feed type names ( 'rss', 'atom' )
+ */
+ protected function getAdvertisedFeedTypes() {
+ if ( $this->getConfig()->get( 'Feed' ) ) {
+ return $this->getConfig()->get( 'AdvertisedFeedTypes' );
+ } else {
+ return [];
+ }
+ }
+
/**
* Add default feeds to the page header
* This is mainly kept for backward compatibility, see OutputPage::addFeedLink()
public function setFeedAppendQuery( $val ) {
$this->mFeedLinks = [];
- foreach ( $this->getConfig()->get( 'AdvertisedFeedTypes' ) as $type ) {
+ foreach ( $this->getAdvertisedFeedTypes() as $type ) {
$query = "feed=$type";
if ( is_string( $val ) ) {
$query .= '&' . $val;
* @param string $href URL
*/
public function addFeedLink( $format, $href ) {
- if ( in_array( $format, $this->getConfig()->get( 'AdvertisedFeedTypes' ) ) ) {
+ if ( in_array( $format, $this->getAdvertisedFeedTypes() ) ) {
$this->mFeedLinks[$format] = $href;
}
}
# or "Breaking news" one). For this, we see if $wgOverrideSiteFeed is defined.
# If so, use it instead.
$sitename = $config->get( 'Sitename' );
- if ( $config->get( 'OverrideSiteFeed' ) ) {
- foreach ( $config->get( 'OverrideSiteFeed' ) as $type => $feedUrl ) {
+ $overrideSiteFeed = $config->get( 'OverrideSiteFeed' );
+ if ( $overrideSiteFeed ) {
+ foreach ( $overrideSiteFeed as $type => $feedUrl ) {
// Note, this->feedLink escapes the url.
$feedLinks[] = $this->feedLink(
$type,
}
} elseif ( !$this->getTitle()->isSpecial( 'Recentchanges' ) ) {
$rctitle = SpecialPage::getTitleFor( 'Recentchanges' );
- foreach ( $config->get( 'AdvertisedFeedTypes' ) as $format ) {
+ foreach ( $this->getAdvertisedFeedTypes() as $format ) {
$feedLinks[] = $this->feedLink(
$format,
$rctitle->getLocalURL( [ 'feed' => $format ] ),
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() );
}
/**