Merge "Added release notes for 'ContentHandler::runLegacyHooks' removal"
[mediawiki.git] / tests / phpunit / includes / StatusTest.php
blob7e56ebf20b66a02b1619e042d515405a9871c0d5
1 <?php
3 /**
4 * @author Addshore
5 */
6 class StatusTest extends MediaWikiLangTestCase {
8 public function testCanConstruct() {
9 new Status();
10 $this->assertTrue( true );
13 /**
14 * @dataProvider provideValues
15 * @covers Status::newGood
17 public function testNewGood( $value = null ) {
18 $status = Status::newGood( $value );
19 $this->assertTrue( $status->isGood() );
20 $this->assertTrue( $status->isOK() );
21 $this->assertEquals( $value, $status->getValue() );
24 public static function provideValues() {
25 return [
26 [],
27 [ 'foo' ],
28 [ [ 'foo' => 'bar' ] ],
29 [ new Exception() ],
30 [ 1234 ],
34 /**
35 * @covers Status::newFatal
37 public function testNewFatalWithMessage() {
38 $message = $this->getMockBuilder( 'Message' )
39 ->disableOriginalConstructor()
40 ->getMock();
42 $status = Status::newFatal( $message );
43 $this->assertFalse( $status->isGood() );
44 $this->assertFalse( $status->isOK() );
45 $this->assertEquals( $message, $status->getMessage() );
48 /**
49 * @covers Status::newFatal
51 public function testNewFatalWithString() {
52 $message = 'foo';
53 $status = Status::newFatal( $message );
54 $this->assertFalse( $status->isGood() );
55 $this->assertFalse( $status->isOK() );
56 $this->assertEquals( $message, $status->getMessage()->getKey() );
59 /**
60 * Test 'ok' and 'errors' getters.
62 * @covers Status::__get
64 public function testOkAndErrorsGetters() {
65 $status = Status::newGood( 'foo' );
66 $this->assertTrue( $status->ok );
67 $status = Status::newFatal( 'foo', 1, 2 );
68 $this->assertFalse( $status->ok );
69 $this->assertArrayEquals(
72 'type' => 'error',
73 'message' => 'foo',
74 'params' => [ 1, 2 ]
77 $status->errors
81 /**
82 * Test 'ok' setter.
84 * @covers Status::__set
86 public function testOkSetter() {
87 $status = new Status();
88 $status->ok = false;
89 $this->assertFalse( $status->isOK() );
90 $status->ok = true;
91 $this->assertTrue( $status->isOK() );
94 /**
95 * @dataProvider provideSetResult
96 * @covers Status::setResult
98 public function testSetResult( $ok, $value = null ) {
99 $status = new Status();
100 $status->setResult( $ok, $value );
101 $this->assertEquals( $ok, $status->isOK() );
102 $this->assertEquals( $value, $status->getValue() );
105 public static function provideSetResult() {
106 return [
107 [ true ],
108 [ false ],
109 [ true, 'value' ],
110 [ false, 'value' ],
115 * @dataProvider provideIsOk
116 * @covers Status::setOK
117 * @covers Status::isOK
119 public function testIsOk( $ok ) {
120 $status = new Status();
121 $status->setOK( $ok );
122 $this->assertEquals( $ok, $status->isOK() );
125 public static function provideIsOk() {
126 return [
127 [ true ],
128 [ false ],
133 * @covers Status::getValue
135 public function testGetValue() {
136 $status = new Status();
137 $status->value = 'foobar';
138 $this->assertEquals( 'foobar', $status->getValue() );
142 * @dataProvider provideIsGood
143 * @covers Status::isGood
145 public function testIsGood( $ok, $errors, $expected ) {
146 $status = new Status();
147 $status->setOK( $ok );
148 foreach ( $errors as $error ) {
149 $status->warning( $error );
151 $this->assertEquals( $expected, $status->isGood() );
154 public static function provideIsGood() {
155 return [
156 [ true, [], true ],
157 [ true, [ 'foo' ], false ],
158 [ false, [], false ],
159 [ false, [ 'foo' ], false ],
164 * @dataProvider provideMockMessageDetails
165 * @covers Status::warning
166 * @covers Status::getWarningsArray
167 * @covers Status::getStatusArray
169 public function testWarningWithMessage( $mockDetails ) {
170 $status = new Status();
171 $messages = $this->getMockMessages( $mockDetails );
173 foreach ( $messages as $message ) {
174 $status->warning( $message );
176 $warnings = $status->getWarningsArray();
178 $this->assertEquals( count( $messages ), count( $warnings ) );
179 foreach ( $messages as $key => $message ) {
180 $expectedArray = array_merge( [ $message->getKey() ], $message->getParams() );
181 $this->assertEquals( $warnings[$key], $expectedArray );
186 * @dataProvider provideMockMessageDetails
187 * @covers Status::error
188 * @covers Status::getErrorsArray
189 * @covers Status::getStatusArray
190 * @covers Status::getErrors
192 public function testErrorWithMessage( $mockDetails ) {
193 $status = new Status();
194 $messages = $this->getMockMessages( $mockDetails );
196 foreach ( $messages as $message ) {
197 $status->error( $message );
199 $errors = $status->getErrorsArray();
201 $this->assertEquals( count( $messages ), count( $errors ) );
202 foreach ( $messages as $key => $message ) {
203 $expectedArray = array_merge( [ $message->getKey() ], $message->getParams() );
204 $this->assertEquals( $errors[$key], $expectedArray );
209 * @dataProvider provideMockMessageDetails
210 * @covers Status::fatal
211 * @covers Status::getErrorsArray
212 * @covers Status::getStatusArray
214 public function testFatalWithMessage( $mockDetails ) {
215 $status = new Status();
216 $messages = $this->getMockMessages( $mockDetails );
218 foreach ( $messages as $message ) {
219 $status->fatal( $message );
221 $errors = $status->getErrorsArray();
223 $this->assertEquals( count( $messages ), count( $errors ) );
224 foreach ( $messages as $key => $message ) {
225 $expectedArray = array_merge( [ $message->getKey() ], $message->getParams() );
226 $this->assertEquals( $errors[$key], $expectedArray );
228 $this->assertFalse( $status->isOK() );
231 protected function getMockMessage( $key = 'key', $params = [] ) {
232 $message = $this->getMockBuilder( 'Message' )
233 ->disableOriginalConstructor()
234 ->getMock();
235 $message->expects( $this->atLeastOnce() )
236 ->method( 'getKey' )
237 ->will( $this->returnValue( $key ) );
238 $message->expects( $this->atLeastOnce() )
239 ->method( 'getParams' )
240 ->will( $this->returnValue( $params ) );
241 return $message;
245 * @param array $messageDetails E.g. array( 'KEY' => array(/PARAMS/) )
246 * @return Message[]
248 protected function getMockMessages( $messageDetails ) {
249 $messages = [];
250 foreach ( $messageDetails as $key => $paramsArray ) {
251 $messages[] = $this->getMockMessage( $key, $paramsArray );
253 return $messages;
256 public static function provideMockMessageDetails() {
257 return [
258 [ [ 'key1' => [ 'foo' => 'bar' ] ] ],
259 [ [ 'key1' => [ 'foo' => 'bar' ], 'key2' => [ 'foo2' => 'bar2' ] ] ],
264 * @covers Status::merge
266 public function testMerge() {
267 $status1 = new Status();
268 $status2 = new Status();
269 $message1 = $this->getMockMessage( 'warn1' );
270 $message2 = $this->getMockMessage( 'error2' );
271 $status1->warning( $message1 );
272 $status2->error( $message2 );
274 $status1->merge( $status2 );
275 $this->assertEquals(
277 count( $status1->getWarningsArray() ) + count( $status1->getErrorsArray() )
282 * @covers Status::merge
284 public function testMergeWithOverwriteValue() {
285 $status1 = new Status();
286 $status2 = new Status();
287 $message1 = $this->getMockMessage( 'warn1' );
288 $message2 = $this->getMockMessage( 'error2' );
289 $status1->warning( $message1 );
290 $status2->error( $message2 );
291 $status2->value = 'FooValue';
293 $status1->merge( $status2, true );
294 $this->assertEquals(
296 count( $status1->getWarningsArray() ) + count( $status1->getErrorsArray() )
298 $this->assertEquals( 'FooValue', $status1->getValue() );
302 * @covers Status::hasMessage
304 public function testHasMessage() {
305 $status = new Status();
306 $status->fatal( 'bad' );
307 $status->fatal( wfMessage( 'bad-msg' ) );
308 $this->assertTrue( $status->hasMessage( 'bad' ) );
309 $this->assertTrue( $status->hasMessage( 'bad-msg' ) );
310 $this->assertTrue( $status->hasMessage( wfMessage( 'bad-msg' ) ) );
311 $this->assertFalse( $status->hasMessage( 'good' ) );
315 * @dataProvider provideCleanParams
316 * @covers Status::cleanParams
318 public function testCleanParams( $cleanCallback, $params, $expected ) {
319 $method = new ReflectionMethod( 'Status', 'cleanParams' );
320 $method->setAccessible( true );
321 $status = new Status();
322 $status->cleanCallback = $cleanCallback;
324 $this->assertEquals( $expected, $method->invoke( $status, $params ) );
327 public static function provideCleanParams() {
328 $cleanCallback = function ( $value ) {
329 return '-' . $value . '-';
332 return [
333 [ false, [ 'foo' => 'bar' ], [ 'foo' => 'bar' ] ],
334 [ $cleanCallback, [ 'foo' => 'bar' ], [ 'foo' => '-bar-' ] ],
339 * @dataProvider provideGetWikiTextAndHtml
340 * @covers Status::getWikiText
342 public function testGetWikiText(
343 Status $status, $wikitext, $wrappedWikitext, $html, $wrappedHtml
345 $this->assertEquals( $wikitext, $status->getWikiText() );
347 $this->assertEquals( $wrappedWikitext, $status->getWikiText( 'wrap-short', 'wrap-long', 'qqx' ) );
351 * @dataProvider provideGetWikiTextAndHtml
352 * @covers Status::getHtml
354 public function testGetHtml(
355 Status $status, $wikitext, $wrappedWikitext, $html, $wrappedHtml
357 $this->assertEquals( $html, $status->getHTML() );
359 $this->assertEquals( $wrappedHtml, $status->getHTML( 'wrap-short', 'wrap-long', 'qqx' ) );
363 * @return array Array of arrays with values;
364 * 0 => status object
365 * 1 => expected string (with no context)
367 public static function provideGetWikiTextAndHtml() {
368 $testCases = [];
370 $testCases['GoodStatus'] = [
371 new Status(),
372 "Internal error: Status::getWikiText called for a good result, this is incorrect\n",
373 "(wrap-short: (internalerror_info: Status::getWikiText called for a good result, " .
374 "this is incorrect\n))",
375 "<p>Internal error: Status::getWikiText called for a good result, this is incorrect\n</p>",
376 "<p>(wrap-short: (internalerror_info: Status::getWikiText called for a good result, " .
377 "this is incorrect\n))\n</p>",
380 $status = new Status();
381 $status->setOK( false );
382 $testCases['GoodButNoError'] = [
383 $status,
384 "Internal error: Status::getWikiText: Invalid result object: no error text but not OK\n",
385 "(wrap-short: (internalerror_info: Status::getWikiText: Invalid result object: " .
386 "no error text but not OK\n))",
387 "<p>Internal error: Status::getWikiText: Invalid result object: no error text but not OK\n</p>",
388 "<p>(wrap-short: (internalerror_info: Status::getWikiText: Invalid result object: " .
389 "no error text but not OK\n))\n</p>",
392 $status = new Status();
393 $status->warning( 'fooBar!' );
394 $testCases['1StringWarning'] = [
395 $status,
396 "⧼fooBar!⧽",
397 "(wrap-short: (fooBar!))",
398 "<p>⧼fooBar!⧽\n</p>",
399 "<p>(wrap-short: (fooBar!))\n</p>",
402 $status = new Status();
403 $status->warning( 'fooBar!' );
404 $status->warning( 'fooBar2!' );
405 $testCases['2StringWarnings'] = [
406 $status,
407 "* ⧼fooBar!⧽\n* ⧼fooBar2!⧽\n",
408 "(wrap-long: * (fooBar!)\n* (fooBar2!)\n)",
409 "<ul><li> ⧼fooBar!⧽</li>\n<li> ⧼fooBar2!⧽</li></ul>\n",
410 "<p>(wrap-long: * (fooBar!)\n</p>\n<ul><li> (fooBar2!)</li></ul>\n<p>)\n</p>",
413 $status = new Status();
414 $status->warning( new Message( 'fooBar!', [ 'foo', 'bar' ] ) );
415 $testCases['1MessageWarning'] = [
416 $status,
417 "⧼fooBar!⧽",
418 "(wrap-short: (fooBar!: foo, bar))",
419 "<p>⧼fooBar!⧽\n</p>",
420 "<p>(wrap-short: (fooBar!: foo, bar))\n</p>",
423 $status = new Status();
424 $status->warning( new Message( 'fooBar!', [ 'foo', 'bar' ] ) );
425 $status->warning( new Message( 'fooBar2!' ) );
426 $testCases['2MessageWarnings'] = [
427 $status,
428 "* ⧼fooBar!⧽\n* ⧼fooBar2!⧽\n",
429 "(wrap-long: * (fooBar!: foo, bar)\n* (fooBar2!)\n)",
430 "<ul><li> ⧼fooBar!⧽</li>\n<li> ⧼fooBar2!⧽</li></ul>\n",
431 "<p>(wrap-long: * (fooBar!: foo, bar)\n</p>\n<ul><li> (fooBar2!)</li></ul>\n<p>)\n</p>",
434 return $testCases;
437 private static function sanitizedMessageParams( Message $message ) {
438 return array_map( function ( $p ) {
439 return $p instanceof Message
441 'key' => $p->getKey(),
442 'params' => self::sanitizedMessageParams( $p ),
443 'lang' => $p->getLanguage()->getCode(),
445 : $p;
446 }, $message->getParams() );
450 * @dataProvider provideGetMessage
451 * @covers Status::getMessage
453 public function testGetMessage(
454 Status $status, $expectedParams = [], $expectedKey, $expectedWrapper
456 $message = $status->getMessage( null, null, 'qqx' );
457 $this->assertInstanceOf( 'Message', $message );
458 $this->assertEquals( $expectedParams, self::sanitizedMessageParams( $message ),
459 'Message::getParams' );
460 $this->assertEquals( $expectedKey, $message->getKey(), 'Message::getKey' );
462 $message = $status->getMessage( 'wrapper-short', 'wrapper-long' );
463 $this->assertInstanceOf( 'Message', $message );
464 $this->assertEquals( $expectedWrapper, $message->getKey(), 'Message::getKey with wrappers' );
465 $this->assertCount( 1, $message->getParams(), 'Message::getParams with wrappers' );
467 $message = $status->getMessage( 'wrapper' );
468 $this->assertInstanceOf( 'Message', $message );
469 $this->assertEquals( 'wrapper', $message->getKey(), 'Message::getKey with wrappers' );
470 $this->assertCount( 1, $message->getParams(), 'Message::getParams with wrappers' );
472 $message = $status->getMessage( false, 'wrapper' );
473 $this->assertInstanceOf( 'Message', $message );
474 $this->assertEquals( 'wrapper', $message->getKey(), 'Message::getKey with wrappers' );
475 $this->assertCount( 1, $message->getParams(), 'Message::getParams with wrappers' );
479 * @return array Array of arrays with values;
480 * 0 => status object
481 * 1 => expected Message parameters (with no context)
482 * 2 => expected Message key
484 public static function provideGetMessage() {
485 $testCases = [];
487 $testCases['GoodStatus'] = [
488 new Status(),
489 [ "Status::getMessage called for a good result, this is incorrect\n" ],
490 'internalerror_info',
491 'wrapper-short'
494 $status = new Status();
495 $status->setOK( false );
496 $testCases['GoodButNoError'] = [
497 $status,
498 [ "Status::getMessage: Invalid result object: no error text but not OK\n" ],
499 'internalerror_info',
500 'wrapper-short'
503 $status = new Status();
504 $status->warning( 'fooBar!' );
505 $testCases['1StringWarning'] = [
506 $status,
508 'fooBar!',
509 'wrapper-short'
512 $status = new Status();
513 $status->warning( 'fooBar!' );
514 $status->warning( 'fooBar2!' );
515 $testCases[ '2StringWarnings' ] = [
516 $status,
518 [ 'key' => 'fooBar!', 'params' => [], 'lang' => 'qqx' ],
519 [ 'key' => 'fooBar2!', 'params' => [], 'lang' => 'qqx' ]
521 "* \$1\n* \$2",
522 'wrapper-long'
525 $status = new Status();
526 $status->warning( new Message( 'fooBar!', [ 'foo', 'bar' ] ) );
527 $testCases['1MessageWarning'] = [
528 $status,
529 [ 'foo', 'bar' ],
530 'fooBar!',
531 'wrapper-short'
534 $status = new Status();
535 $status->warning( new Message( 'fooBar!', [ 'foo', 'bar' ] ) );
536 $status->warning( new Message( 'fooBar2!' ) );
537 $testCases['2MessageWarnings'] = [
538 $status,
540 [ 'key' => 'fooBar!', 'params' => [ 'foo', 'bar' ], 'lang' => 'qqx' ],
541 [ 'key' => 'fooBar2!', 'params' => [], 'lang' => 'qqx' ]
543 "* \$1\n* \$2",
544 'wrapper-long'
547 return $testCases;
551 * @covers Status::replaceMessage
553 public function testReplaceMessage() {
554 $status = new Status();
555 $message = new Message( 'key1', [ 'foo1', 'bar1' ] );
556 $status->error( $message );
557 $newMessage = new Message( 'key2', [ 'foo2', 'bar2' ] );
559 $status->replaceMessage( $message, $newMessage );
561 $this->assertEquals( $newMessage, $status->errors[0]['message'] );
565 * @covers Status::getErrorMessage
567 public function testGetErrorMessage() {
568 $method = new ReflectionMethod( 'Status', 'getErrorMessage' );
569 $method->setAccessible( true );
570 $status = new Status();
571 $key = 'foo';
572 $params = [ 'bar' ];
574 /** @var Message $message */
575 $message = $method->invoke( $status, array_merge( [ $key ], $params ) );
576 $this->assertInstanceOf( 'Message', $message );
577 $this->assertEquals( $key, $message->getKey() );
578 $this->assertEquals( $params, $message->getParams() );
582 * @covers Status::getErrorMessageArray
584 public function testGetErrorMessageArray() {
585 $method = new ReflectionMethod( 'Status', 'getErrorMessageArray' );
586 $method->setAccessible( true );
587 $status = new Status();
588 $key = 'foo';
589 $params = [ 'bar' ];
591 /** @var Message[] $messageArray */
592 $messageArray = $method->invoke(
593 $status,
595 array_merge( [ $key ], $params ),
596 array_merge( [ $key ], $params )
600 $this->assertInternalType( 'array', $messageArray );
601 $this->assertCount( 2, $messageArray );
602 foreach ( $messageArray as $message ) {
603 $this->assertInstanceOf( 'Message', $message );
604 $this->assertEquals( $key, $message->getKey() );
605 $this->assertEquals( $params, $message->getParams() );
610 * @covers Status::getErrorsByType
612 public function testGetErrorsByType() {
613 $status = new Status();
614 $warning = new Message( 'warning111' );
615 $error = new Message( 'error111' );
616 $status->warning( $warning );
617 $status->error( $error );
619 $warnings = $status->getErrorsByType( 'warning' );
620 $errors = $status->getErrorsByType( 'error' );
622 $this->assertCount( 1, $warnings );
623 $this->assertCount( 1, $errors );
624 $this->assertEquals( $warning, $warnings[0]['message'] );
625 $this->assertEquals( $error, $errors[0]['message'] );
629 * @covers Status::__wakeup
631 public function testWakeUpSanitizesCallback() {
632 $status = new Status();
633 $status->cleanCallback = function ( $value ) {
634 return '-' . $value . '-';
636 $status->__wakeup();
637 $this->assertEquals( false, $status->cleanCallback );
641 * @dataProvider provideNonObjectMessages
642 * @covers Status::getStatusArray
644 public function testGetStatusArrayWithNonObjectMessages( $nonObjMsg ) {
645 $status = new Status();
646 if ( !array_key_exists( 1, $nonObjMsg ) ) {
647 $status->warning( $nonObjMsg[0] );
648 } else {
649 $status->warning( $nonObjMsg[0], $nonObjMsg[1] );
652 $array = $status->getWarningsArray(); // We use getWarningsArray to access getStatusArray
654 $this->assertEquals( 1, count( $array ) );
655 $this->assertEquals( $nonObjMsg, $array[0] );
658 public static function provideNonObjectMessages() {
659 return [
660 [ [ 'ImaString', [ 'param1' => 'value1' ] ] ],
661 [ [ 'ImaString' ] ],
666 * @dataProvider provideErrorsWarningsOnly
667 * @covers Status::splitByErrorType
668 * @covers StatusValue::splitByErrorType
670 public function testGetErrorsWarningsOnlyStatus( $errorText, $warningText, $type, $errorResult,
671 $warningResult
673 $status = Status::newGood();
674 if ( $errorText ) {
675 $status->fatal( $errorText );
677 if ( $warningText ) {
678 $status->warning( $warningText );
680 $testStatus = $status->splitByErrorType()[$type];
681 $this->assertEquals( $errorResult, $testStatus->getErrorsByType( 'error' ) );
682 $this->assertEquals( $warningResult, $testStatus->getErrorsByType( 'warning' ) );
685 public static function provideErrorsWarningsOnly() {
686 return [
688 'Just an error',
689 'Just a warning',
692 0 => [
693 'type' => 'error',
694 'message' => 'Just an error',
695 'params' => []
699 ], [
700 'Just an error',
701 'Just a warning',
705 0 => [
706 'type' => 'warning',
707 'message' => 'Just a warning',
708 'params' => []
711 ], [
712 null,
713 null,
717 ], [
718 null,
719 null,