d
', $op->getHTML() ); $op->clearHTML(); $this->assertSame( '', $op->getHTML() ); } /** * @dataProvider provideRevisionId * @covers OutputPage::setRevisionId * @covers OutputPage::getRevisionId */ public function testRevisionId( $newVal, $expected ) { $op = $this->newInstance(); $this->assertNull( $op->setRevisionId( $newVal ) ); $this->assertSame( $expected, $op->getRevisionId() ); $this->assertSame( $expected, $op->setRevisionId( null ) ); $this->assertNull( $op->getRevisionId() ); } public function provideRevisionId() { return [ [ null, null ], [ 7, 7 ], [ -1, -1 ], [ 3.2, 3 ], [ '0', 0 ], [ '32% finished', 32 ], [ false, 0 ], ]; } /** * @covers OutputPage::setRevisionTimestamp * @covers OutputPage::getRevisionTimestamp */ public function testRevisionTimestamp() { $op = $this->newInstance(); $this->assertNull( $op->getRevisionTimestamp() ); $this->assertNull( $op->setRevisionTimestamp( 'abc' ) ); $this->assertSame( 'abc', $op->getRevisionTimestamp() ); $this->assertSame( 'abc', $op->setRevisionTimestamp( null ) ); $this->assertNull( $op->getRevisionTimestamp() ); } /** * @covers OutputPage::setFileVersion * @covers OutputPage::getFileVersion */ public function testFileVersion() { $op = $this->newInstance(); $this->assertNull( $op->getFileVersion() ); $stubFile = $this->createMock( File::class ); $stubFile->method( 'exists' )->willReturn( true ); $stubFile->method( 'getTimestamp' )->willReturn( '12211221123321' ); $stubFile->method( 'getSha1' )->willReturn( 'bf3ffa7047dc080f5855377a4f83cd18887e3b05' ); $op->setFileVersion( $stubFile ); $this->assertEquals( [ 'time' => '12211221123321', 'sha1' => 'bf3ffa7047dc080f5855377a4f83cd18887e3b05' ], $op->getFileVersion() ); $stubMissingFile = $this->createMock( File::class ); $stubMissingFile->method( 'exists' )->willReturn( false ); $op->setFileVersion( $stubMissingFile ); $this->assertNull( $op->getFileVersion() ); $op->setFileVersion( $stubFile ); $this->assertNotNull( $op->getFileVersion() ); $op->setFileVersion( null ); $this->assertNull( $op->getFileVersion() ); } private function createParserOutputStub( $method = '', $retVal = [] ) { $pOut = $this->getMock( ParserOutput::class ); if ( $method !== '' ) { $pOut->method( $method )->willReturn( $retVal ); } $arrayReturningMethods = [ 'getCategories', 'getFileSearchOptions', 'getHeadItems', 'getIndicators', 'getLanguageLinks', 'getOutputHooks', 'getTemplateIds', ]; foreach ( $arrayReturningMethods as $method ) { $pOut->method( $method )->willReturn( [] ); } return $pOut; } /** * @covers OutputPage::getTemplateIds * @covers OutputPage::addParserOutputMetadata */ public function testTemplateIds() { $op = $this->newInstance(); $this->assertSame( [], $op->getTemplateIds() ); // Test with no template id's $stubPOEmpty = $this->createParserOutputStub(); $op->addParserOutputMetadata( $stubPOEmpty ); $this->assertSame( [], $op->getTemplateIds() ); // Test with some arbitrary template id's $ids = [ NS_MAIN => [ 'A' => 3, 'B' => 17 ], NS_TALK => [ 'C' => 31 ], NS_MEDIA => [ 'D' => -1 ], ]; $stubPO1 = $this->createParserOutputStub( 'getTemplateIds', $ids ); $op->addParserOutputMetadata( $stubPO1 ); $this->assertSame( $ids, $op->getTemplateIds() ); // Test merging with a second set of id's $stubPO2 = $this->createParserOutputStub( 'getTemplateIds', [ NS_MAIN => [ 'E' => 1234 ], NS_PROJECT => [ 'F' => 5678 ], ] ); $finalIds = [ NS_MAIN => [ 'E' => 1234, 'A' => 3, 'B' => 17 ], NS_TALK => [ 'C' => 31 ], NS_MEDIA => [ 'D' => -1 ], NS_PROJECT => [ 'F' => 5678 ], ]; $op->addParserOutputMetadata( $stubPO2 ); $this->assertSame( $finalIds, $op->getTemplateIds() ); // Test merging with an empty set of id's $op->addParserOutputMetadata( $stubPOEmpty ); $this->assertSame( $finalIds, $op->getTemplateIds() ); } /** * @covers OutputPage::getFileSearchOptions * @covers OutputPage::addParserOutputMetadata */ public function testFileSearchOptions() { $op = $this->newInstance(); $this->assertSame( [], $op->getFileSearchOptions() ); // Test with no files $stubPOEmpty = $this->createParserOutputStub(); $op->addParserOutputMetadata( $stubPOEmpty ); $this->assertSame( [], $op->getFileSearchOptions() ); // Test with some arbitrary files $files1 = [ 'A' => [ 'time' => null, 'sha1' => '' ], 'B' => [ 'time' => '12211221123321', 'sha1' => 'bf3ffa7047dc080f5855377a4f83cd18887e3b05', ], ]; $stubPO1 = $this->createParserOutputStub( 'getFileSearchOptions', $files1 ); $op->addParserOutputMetadata( $stubPO1 ); $this->assertSame( $files1, $op->getFileSearchOptions() ); // Test merging with a second set of files $files2 = [ 'C' => [ 'time' => null, 'sha1' => '' ], 'B' => [ 'time' => null, 'sha1' => '' ], ]; $stubPO2 = $this->createParserOutputStub( 'getFileSearchOptions', $files2 ); $op->addParserOutputMetadata( $stubPO2 ); $this->assertSame( array_merge( $files1, $files2 ), $op->getFileSearchOptions() ); // Test merging with an empty set of files $op->addParserOutputMetadata( $stubPOEmpty ); $this->assertSame( array_merge( $files1, $files2 ), $op->getFileSearchOptions() ); } /** * @dataProvider provideAddWikiText * @covers OutputPage::addWikiText * @covers OutputPage::addWikiTextWithTitle * @covers OutputPage::addWikiTextTitle * @covers OutputPage::addWikiTextTidy * @covers OutputPage::addWikiTextTitleTidy * @covers OutputPage::getHTML */ public function testAddWikiText( $method, array $args, $expected ) { $op = $this->newInstance(); $this->assertSame( '', $op->getHTML() ); if ( in_array( $method, [ 'addWikiTextWithTitle', 'addWikiTextTitleTidy', 'addWikiTextTitle' ] ) && count( $args ) >= 2 && $args[1] === null ) { // Special placeholder because we can't get the actual title in the provider $args[1] = $op->getTitle(); } $op->$method( ...$args ); $this->assertSame( $expected, $op->getHTML() ); } public function provideAddWikiText() { $tests = [ 'addWikiText' => [ 'Simple wikitext' => [ [ "'''Bold'''" ], "Bold\n
", ], 'List at start' => [ [ '* List' ], "Bold\n
", ], 'No section edit links' => [ [ '== Title ==' ], "\nMy message" ], '
' . "\nMy message\n
" ], 'List at start' => [ [ '* List' ], "* Not a list
', ], ], 'addWikiTextTitleTidy' => [ 'With title at start' => [ [ '* {{PAGENAME}}', Title::newFromText( 'Talk:Some page' ) ], "* Some page
", ], 'EditPage' => [ [ "(a)\n
", $op->getHTML() ); } /** * @covers OutputPage::wrapWikiMsg */ public function testWrapWikiMsg() { $msg = wfMessage( 'parentheses' ); $this->assertSame( '(a)', $msg->rawParams( 'a' )->plain() ); $op = $this->newInstance(); $this->assertSame( '', $op->getHTML() ); $op->wrapWikiMsg( '[$1]', [ 'parentheses', "a" ] ); // This is known to be bad unbalanced HTML; this will be fixed // by I743f4185a03403f8d9b9db010ff1ee4e9342e062 (T198214) $this->assertSame( "[(a)]\n
", $op->getHTML() ); } /** * @covers OutputPage::addParserOutputMetadata */ public function testNoGallery() { $op = $this->newInstance(); $this->assertFalse( $op->mNoGallery ); $stubPO1 = $this->createParserOutputStub( 'getNoGallery', true ); $op->addParserOutputMetadata( $stubPO1 ); $this->assertTrue( $op->mNoGallery ); $stubPO2 = $this->createParserOutputStub( 'getNoGallery', false ); $op->addParserOutputMetadata( $stubPO2 ); $this->assertFalse( $op->mNoGallery ); } // @todo Make sure to test the following in addParserOutputMetadata() as well when we add tests // for them: // * enableClientCache() // * addModules() // * addModuleScripts() // * addModuleStyles() // * addJsConfigVars() // * preventClickJacking() // Otherwise those lines of addParserOutputMetadata() will be reported as covered, but we won't // be testing they actually work. /** * @covers OutputPage::haveCacheVaryCookies */ public function testHaveCacheVaryCookies() { $request = new FauxRequest(); $context = new RequestContext(); $context->setRequest( $request ); $op = new OutputPage( $context ); // No cookies are set. $this->assertFalse( $op->haveCacheVaryCookies() ); // 'Token' is present but empty, so it shouldn't count. $request->setCookie( 'Token', '' ); $this->assertFalse( $op->haveCacheVaryCookies() ); // 'Token' present and nonempty. $request->setCookie( 'Token', '123' ); $this->assertTrue( $op->haveCacheVaryCookies() ); } /** * @dataProvider provideVaryHeaders * * @covers OutputPage::addVaryHeader * @covers OutputPage::getVaryHeader * @covers OutputPage::getKeyHeader */ public function testVaryHeaders( $calls, $vary, $key ) { // get rid of default Vary fields $op = $this->getMockBuilder( OutputPage::class ) ->setConstructorArgs( [ new RequestContext() ] ) ->setMethods( [ 'getCacheVaryCookies' ] ) ->getMock(); $op->expects( $this->any() ) ->method( 'getCacheVaryCookies' ) ->will( $this->returnValue( [] ) ); TestingAccessWrapper::newFromObject( $op )->mVaryHeader = []; foreach ( $calls as $call ) { call_user_func_array( [ $op, 'addVaryHeader' ], $call ); } $this->assertEquals( $vary, $op->getVaryHeader(), 'Vary:' ); $this->assertEquals( $key, $op->getKeyHeader(), 'Key:' ); } public function provideVaryHeaders() { // note: getKeyHeader() automatically adds Vary: Cookie return [ [ // single header [ [ 'Cookie' ], ], 'Vary: Cookie', 'Key: Cookie', ], [ // non-unique headers [ [ 'Cookie' ], [ 'Accept-Language' ], [ 'Cookie' ], ], 'Vary: Cookie, Accept-Language', 'Key: Cookie,Accept-Language', ], [ // two headers with single options [ [ 'Cookie', [ 'param=phpsessid' ] ], [ 'Accept-Language', [ 'substr=en' ] ], ], 'Vary: Cookie, Accept-Language', 'Key: Cookie;param=phpsessid,Accept-Language;substr=en', ], [ // one header with multiple options [ [ 'Cookie', [ 'param=phpsessid', 'param=userId' ] ], ], 'Vary: Cookie', 'Key: Cookie;param=phpsessid;param=userId', ], [ // Duplicate option [ [ 'Cookie', [ 'param=phpsessid' ] ], [ 'Cookie', [ 'param=phpsessid' ] ], [ 'Accept-Language', [ 'substr=en', 'substr=en' ] ], ], 'Vary: Cookie, Accept-Language', 'Key: Cookie;param=phpsessid,Accept-Language;substr=en', ], [ // Same header, different options [ [ 'Cookie', [ 'param=phpsessid' ] ], [ 'Cookie', [ 'param=userId' ] ], ], 'Vary: Cookie', 'Key: Cookie;param=phpsessid;param=userId', ], ]; } /** * @dataProvider provideLinkHeaders * * @covers OutputPage::addLinkHeader * @covers OutputPage::getLinkHeader */ public function testLinkHeaders( $headers, $result ) { $op = $this->newInstance(); foreach ( $headers as $header ) { $op->addLinkHeader( $header ); } $this->assertEquals( $result, $op->getLinkHeader() ); } public function provideLinkHeaders() { return [ [ [], false ], [ [ '