assertTrue( $status->isGood() ); $this->assertTrue( $status->isOK() ); $this->assertEquals( $value, $status->getValue() ); } public static function provideValues() { return [ [], [ 'foo' ], [ [ 'foo' => 'bar' ] ], [ new Exception() ], [ 1234 ], ]; } public function testNewFatalWithMessage() { $message = $this->getMockMessage(); $status = Status::newFatal( $message ); $this->assertFalse( $status->isGood() ); $this->assertFalse( $status->isOK() ); $this->assertEquals( $message, $status->getMessage() ); } public function testNewFatalWithString() { $message = 'foo'; $status = Status::newFatal( $message ); $this->assertFalse( $status->isGood() ); $this->assertFalse( $status->isOK() ); $this->assertEquals( $message, $status->getMessage()->getKey() ); } public function testOkAndErrorsGetters() { $status = Status::newGood( 'foo' ); $this->assertTrue( $status->ok ); $status = Status::newFatal( 'foo', 1, 2 ); $this->assertFalse( $status->ok ); $this->assertArrayEquals( [ [ 'type' => 'error', 'message' => 'foo', 'params' => [ 1, 2 ] ] ], $status->errors ); } public function testOkSetter() { $status = new Status(); $status->ok = false; $this->assertFalse( $status->isOK() ); $status->ok = true; $this->assertTrue( $status->isOK() ); } /** * @dataProvider provideSetResult */ public function testSetResult( $ok, $value = null ) { $status = new Status(); $status->setResult( $ok, $value ); $this->assertEquals( $ok, $status->isOK() ); $this->assertEquals( $value, $status->getValue() ); } public static function provideSetResult() { return [ [ true ], [ false ], [ true, 'value' ], [ false, 'value' ], ]; } /** * @dataProvider provideIsOk */ public function testIsOk( $ok ) { $status = new Status(); $status->setOK( $ok ); $this->assertEquals( $ok, $status->isOK() ); } public static function provideIsOk() { return [ [ true ], [ false ], ]; } public function testGetValue() { $status = new Status(); $status->value = 'foobar'; $this->assertEquals( 'foobar', $status->getValue() ); } /** * @dataProvider provideIsGood */ public function testIsGood( $ok, $errors, $expected ) { $status = new Status(); $status->setOK( $ok ); foreach ( $errors as $error ) { $status->warning( $error ); } $this->assertEquals( $expected, $status->isGood() ); } public static function provideIsGood() { return [ [ true, [], true ], [ true, [ 'foo' ], false ], [ false, [], false ], [ false, [ 'foo' ], false ], ]; } /** * @dataProvider provideMockMessageDetails */ public function testWarningWithMessage( $mockDetails ) { $status = new Status(); $messages = $this->getMockMessages( $mockDetails ); foreach ( $messages as $message ) { $status->warning( $message ); } $warnings = $status->getWarningsArray(); $this->assertSameSize( $messages, $warnings ); foreach ( $messages as $key => $message ) { $expectedArray = [ $message->getKey(), ...$message->getParams() ]; $this->assertEquals( $expectedArray, $warnings[$key] ); } } /** * @dataProvider provideMockMessageDetails */ public function testErrorWithMessage( $mockDetails ) { $status = new Status(); $messages = $this->getMockMessages( $mockDetails ); foreach ( $messages as $message ) { $status->error( $message ); } $errors = $status->getErrorsArray(); $this->assertSameSize( $messages, $errors ); foreach ( $messages as $key => $message ) { $expectedArray = [ $message->getKey(), ...$message->getParams() ]; $this->assertEquals( $expectedArray, $errors[$key] ); } } /** * @dataProvider provideMockMessageDetails */ public function testFatalWithMessage( $mockDetails ) { $status = new Status(); $messages = $this->getMockMessages( $mockDetails ); foreach ( $messages as $message ) { $status->fatal( $message ); } $errors = $status->getErrorsArray(); $this->assertSameSize( $messages, $errors ); foreach ( $messages as $key => $message ) { $expectedArray = [ $message->getKey(), ...$message->getParams() ]; $this->assertEquals( $expectedArray, $errors[$key] ); } $this->assertStatusNotOK( $status ); } public function testRawMessage() { $status = new Status(); $msg = new RawMessage( 'Foo Bar' ); $status->fatal( $msg ); $this->assertEquals( 'rawmessage', $status->getErrorsArray()[0][0] ); $this->assertEquals( $msg, $status->getMessages()[0] ); } /** * @param array $messageDetails E.g. [ 'KEY' => [ /PARAMS/ ] ] * @return Message[] */ protected function getMockMessages( $messageDetails ) { $messages = []; foreach ( $messageDetails as $key => $paramsArray ) { $messages[] = $this->getMockMessage( $key, $paramsArray ); } return $messages; } public static function provideMockMessageDetails() { return [ [ [ 'key1' => [ 'bar' ] ] ], [ [ 'key1' => [ 'bar' ], 'key2' => [ 'bar2' ] ] ], ]; } public function testMerge() { $status1 = new Status(); $status2 = new Status(); $message1 = $this->getMockMessage( 'warn1' ); $message2 = $this->getMockMessage( 'error2' ); $status1->warning( $message1 ); $status2->error( $message2 ); $status1->merge( $status2 ); $this->assertCount( 2, $status1->getMessages() ); } public function testMergeWithOverwriteValue() { $status1 = new Status(); $status2 = new Status(); $message1 = $this->getMockMessage( 'warn1' ); $message2 = $this->getMockMessage( 'error2' ); $status1->warning( $message1 ); $status2->error( $message2 ); $status2->value = 'FooValue'; $status1->merge( $status2, true ); $this->assertCount( 2, $status1->getMessages() ); $this->assertEquals( 'FooValue', $status1->getValue() ); } public function testHasMessage() { $status = new Status(); $status->fatal( 'bad' ); $status->fatal( wfMessage( 'bad-msg' ) ); $status->fatal( new MessageValue( 'bad-msg-value' ) ); $this->assertTrue( $status->hasMessage( 'bad' ) ); $this->assertTrue( $status->hasMessage( 'bad-msg' ) ); $this->assertFalse( $status->hasMessage( 'good' ) ); } public function testHasMessagesExcept() { $status = new Status(); $status->fatal( 'bad' ); $status->fatal( wfMessage( 'bad-msg' ) ); $status->fatal( new MessageValue( 'bad-msg-value' ) ); $this->assertTrue( $status->hasMessagesExcept( 'good' ) ); $this->assertTrue( $status->hasMessagesExcept( 'bad' ) ); $this->assertFalse( $status->hasMessagesExcept( 'bad', 'bad-msg', 'bad-msg-value' ) ); $this->assertFalse( $status->hasMessagesExcept( 'good', 'bad', 'bad-msg', 'bad-msg-value' ) ); } /** * @dataProvider provideCleanParams */ public function testCleanParams( $cleanCallback, $params, $expected, $unexpected ) { $this->setUserLang( 'qqx' ); $status = new Status(); $status->cleanCallback = $cleanCallback; $status->warning( 'ok', ...$params ); $wikitext = $status->getWikiText(); $this->assertStringContainsString( $expected, $wikitext ); $this->assertStringNotContainsString( $unexpected, $wikitext ); $html = $status->getHTML(); $this->assertStringContainsString( $expected, $html ); $this->assertStringNotContainsString( $unexpected, $html ); } public static function provideCleanParams() { $cleanCallback = static function ( $value ) { return 'xxx'; }; return [ [ false, [ 'secret' ], 'secret', 'xxx' ], [ $cleanCallback, [ 'secret' ], 'xxx', 'secret' ], ]; } /** * @dataProvider provideGetWikiTextAndHtml */ public function testGetWikiText( Status $status, $wikitext, $wrappedWikitext, $html, $wrappedHtml ) { $this->assertEquals( $wikitext, $status->getWikiText() ); $this->assertEquals( $wrappedWikitext, $status->getWikiText( 'wrap-short', 'wrap-long', 'qqx' ) ); } /** * @dataProvider provideGetWikiTextAndHtml */ public function testGetHtml( Status $status, $wikitext, $wrappedWikitext, $html, $wrappedHtml ) { $this->assertEquals( $html, $status->getHTML() ); $this->assertEquals( $wrappedHtml, $status->getHTML( 'wrap-short', 'wrap-long', 'qqx' ) ); } /** * @return array Array of arrays with values; * 0 => status object * 1 => expected string (with no context) */ public static function provideGetWikiTextAndHtml() { $testCases = []; $testCases['GoodStatus'] = [ new Status(), "Internal error: MediaWiki\Status\StatusFormatter::getWikiText called for a good result, this is incorrect ", "(wrap-short: (internalerror_info: MediaWiki\Status\StatusFormatter::getWikiText called for a good result, " . "this is incorrect ))", "
Internal error: MediaWiki\Status\StatusFormatter::getWikiText called for a good result, this is incorrect \n
", "(wrap-short: (internalerror_info: MediaWiki\Status\StatusFormatter::getWikiText called for a good result, " . "this is incorrect ))\n
", ]; $status = new Status(); $status->setOK( false ); $testCases['GoodButNoError'] = [ $status, "Internal error: MediaWiki\Status\StatusFormatter::getWikiText: Invalid result object: no error text but not OK ", "(wrap-short: (internalerror_info: MediaWiki\Status\StatusFormatter::getWikiText: Invalid result object: " . "no error text but not OK ))", "Internal error: MediaWiki\Status\StatusFormatter::getWikiText: Invalid result object: no error text but not OK \n
", "(wrap-short: (internalerror_info: MediaWiki\Status\StatusFormatter::getWikiText: Invalid result object: " . "no error text but not OK ))\n
", ]; $status = new Status(); $status->warning( 'fooBar!' ); $testCases['1StringWarning'] = [ $status, "⧼fooBar!⧽", "(wrap-short: (fooBar!))", "⧼fooBar!⧽\n
", "(wrap-short: (fooBar!))\n
", ]; $status = new Status(); $status->warning( 'fooBar!' ); $status->warning( 'fooBar2!' ); $testCases['2StringWarnings'] = [ $status, "(wrap-long:
)\n
", ]; $status = new Status(); $status->warning( new Message( 'fooBar!', [ 'foo', 'bar' ] ) ); $testCases['1MessageWarning'] = [ $status, "⧼fooBar!⧽", "(wrap-short: (fooBar!: foo, bar))", "⧼fooBar!⧽\n
", "(wrap-short: (fooBar!: foo, bar))\n
", ]; $status = new Status(); $status->warning( new Message( 'fooBar!', [ 'foo', 'bar' ] ) ); $status->warning( new Message( 'fooBar2!' ) ); $testCases['2MessageWarnings'] = [ $status, "(wrap-long:
)\n
", ]; return $testCases; } private static function sanitizedMessageParams( Message $message ) { return array_map( static function ( $p ) { return $p instanceof Message ? [ 'key' => $p->getKey(), 'params' => self::sanitizedMessageParams( $p ), 'lang' => $p->getLanguage()->getCode(), ] : $p; }, $message instanceof RawMessage ? $message->getParamsOfRawMessage() : $message->getParams() ); } private static function sanitizedMessageKey( Message $message ) { return $message instanceof RawMessage ? $message->getTextOfRawMessage() : $message->getKey(); } /** * @dataProvider provideGetMessage */ public function testGetMessage( Status $status, $expectedParams, $expectedKey, $expectedWrapper ) { $message = $status->getMessage( null, null, 'qqx' ); $this->assertInstanceOf( Message::class, $message ); $this->assertEquals( $expectedParams, self::sanitizedMessageParams( $message ), 'Message::getParams' ); $this->assertEquals( $expectedKey, self::sanitizedMessageKey( $message ), 'Message::getKey' ); $message = $status->getMessage( 'wrapper-short', 'wrapper-long' ); $this->assertInstanceOf( Message::class, $message ); $this->assertEquals( $expectedWrapper, $message->getKey(), 'Message::getKey with wrappers' ); $this->assertCount( 1, $message->getParams(), 'Message::getParams with wrappers' ); $message = $status->getMessage( 'wrapper' ); $this->assertInstanceOf( Message::class, $message ); $this->assertEquals( 'wrapper', $message->getKey(), 'Message::getKey with wrappers' ); $this->assertCount( 1, $message->getParams(), 'Message::getParams with wrappers' ); $message = $status->getMessage( false, 'wrapper' ); $this->assertInstanceOf( Message::class, $message ); $this->assertEquals( 'wrapper', $message->getKey(), 'Message::getKey with wrappers' ); $this->assertCount( 1, $message->getParams(), 'Message::getParams with wrappers' ); } /** * @return array Array of arrays with values; * 0 => status object * 1 => expected Message parameters (with no context) * 2 => expected Message key */ public static function provideGetMessage() { $testCases = []; $testCases['GoodStatus'] = [ new Status(), [ "MediaWiki\Status\StatusFormatter::getMessage called for a good result, this is incorrect " ], 'internalerror_info', 'wrapper-short' ]; $status = new Status(); $status->setOK( false ); $testCases['GoodButNoError'] = [ $status, [ "MediaWiki\Status\StatusFormatter::getMessage: Invalid result object: no error text but not OK " ], 'internalerror_info', 'wrapper-short' ]; $status = new Status(); $status->warning( 'fooBar!' ); $testCases['1StringWarning'] = [ $status, [], 'fooBar!', 'wrapper-short' ]; $status = new Status(); $status->warning( 'fooBar!' ); $status->warning( 'fooBar2!' ); $testCases[ '2StringWarnings' ] = [ $status, [ [ 'key' => 'fooBar!', 'params' => [], 'lang' => 'qqx' ], [ 'key' => 'fooBar2!', 'params' => [], 'lang' => 'qqx' ] ], "* \$1\n* \$2", 'wrapper-long' ]; $status = new Status(); $status->warning( new Message( 'fooBar!', [ 'foo', 'bar' ] ) ); $testCases['1MessageWarning'] = [ $status, [ 'foo', 'bar' ], 'fooBar!', 'wrapper-short' ]; $status = new Status(); $status->warning( new MessageValue( 'fooBar!', [ 'foo', 'bar' ] ) ); $status->warning( new MessageValue( 'fooBar2!' ) ); $testCases['2MessageWarnings'] = [ $status, [ [ 'key' => 'fooBar!', 'params' => [ 'foo', 'bar' ], 'lang' => 'qqx' ], [ 'key' => 'fooBar2!', 'params' => [], 'lang' => 'qqx' ] ], "* \$1\n* \$2", 'wrapper-long' ]; return $testCases; } /** * @dataProvider provideGetPsr3MessageAndContext */ public function testGetPsr3MessageAndContext( array $errors, string $expectedMessage, array $expectedContext ) { // set up a rawmessage_2 message, which is just like rawmessage but doesn't trigger // the special-casing in Status::getPsr3MessageAndContext $this->setTemporaryHook( 'MessageCacheFetchOverrides', static function ( &$overrides ) { $overrides['rawmessage_2'] = 'rawmessage'; }, false ); $status = new Status(); foreach ( $errors as $error ) { $status->error( ...$error ); } [ $actualMessage, $actualContext ] = $status->getPsr3MessageAndContext(); $this->assertSame( $expectedMessage, $actualMessage ); $this->assertSame( $expectedContext, $actualContext ); } public static function provideGetPsr3MessageAndContext() { return [ // parameters to Status::error() calls as array of arrays; expected message; expected context 'no errors' => [ [], "Internal error: MediaWiki\Status\StatusFormatter::getWikiText called for a good result, this is incorrect ", [], ], // make sure that the rawmessage_2 hack works as the following tests rely on it 'rawmessage_2' => [ [ [ 'rawmessage_2', 'foo' ] ], '{parameter1}', [ 'parameter1' => 'foo' ], ], 'two errors' => [ [ [ 'rawmessage_2', 'foo' ], [ 'rawmessage_2', 'bar' ] ], "