Merge "Set relevant title on Special:RecentChangesLinked"
[lhc/web/wiklou.git] / tests / phpunit / includes / StatusTest.php
1 <?php
2
3 /**
4 * @author Adam Shorland
5 */
6 class StatusTest extends MediaWikiLangTestCase {
7
8 public function testCanConstruct() {
9 new Status();
10 $this->assertTrue( true );
11 }
12
13 /**
14 * @dataProvider provideValues
15 * @covers Status::newGood
16 */
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() );
22 }
23
24 public static function provideValues() {
25 return array(
26 array(),
27 array( 'foo' ),
28 array( array( 'foo' => 'bar' ) ),
29 array( new Exception() ),
30 array( 1234 ),
31 );
32 }
33
34 /**
35 * @covers Status::newFatal
36 */
37 public function testNewFatalWithMessage() {
38 $message = $this->getMockBuilder( 'Message' )
39 ->disableOriginalConstructor()
40 ->getMock();
41
42 $status = Status::newFatal( $message );
43 $this->assertFalse( $status->isGood() );
44 $this->assertFalse( $status->isOK() );
45 $this->assertEquals( $message, $status->getMessage() );
46 }
47
48 /**
49 * @covers Status::newFatal
50 */
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() );
57 }
58
59 /**
60 * @dataProvider provideSetResult
61 * @covers Status::setResult
62 */
63 public function testSetResult( $ok, $value = null ) {
64 $status = new Status();
65 $status->setResult( $ok, $value );
66 $this->assertEquals( $ok, $status->isOK() );
67 $this->assertEquals( $value, $status->getValue() );
68 }
69
70 public static function provideSetResult() {
71 return array(
72 array( true ),
73 array( false ),
74 array( true, 'value' ),
75 array( false, 'value' ),
76 );
77 }
78
79 /**
80 * @dataProvider provideIsOk
81 * @covers Status::isOk
82 */
83 public function testIsOk( $ok ) {
84 $status = new Status();
85 $status->ok = $ok;
86 $this->assertEquals( $ok, $status->isOK() );
87 }
88
89 public static function provideIsOk() {
90 return array(
91 array( true ),
92 array( false ),
93 );
94 }
95
96 /**
97 * @covers Status::getValue
98 */
99 public function testGetValue() {
100 $status = new Status();
101 $status->value = 'foobar';
102 $this->assertEquals( 'foobar', $status->getValue() );
103 }
104
105 /**
106 * @dataProvider provideIsGood
107 * @covers Status::isGood
108 */
109 public function testIsGood( $ok, $errors, $expected ) {
110 $status = new Status();
111 $status->ok = $ok;
112 $status->errors = $errors;
113 $this->assertEquals( $expected, $status->isGood() );
114 }
115
116 public static function provideIsGood() {
117 return array(
118 array( true, array(), true ),
119 array( true, array( 'foo' ), false ),
120 array( false, array(), false ),
121 array( false, array( 'foo' ), false ),
122 );
123 }
124
125 /**
126 * @dataProvider provideMockMessageDetails
127 * @covers Status::warning
128 * @covers Status::getWarningsArray
129 * @covers Status::getStatusArray
130 */
131 public function testWarningWithMessage( $mockDetails ) {
132 $status = new Status();
133 $messages = $this->getMockMessages( $mockDetails );
134
135 foreach ( $messages as $message ) {
136 $status->warning( $message );
137 }
138 $warnings = $status->getWarningsArray();
139
140 $this->assertEquals( count( $messages ), count( $warnings ) );
141 foreach ( $messages as $key => $message ) {
142 $expectedArray = array_merge( array( $message->getKey() ), $message->getParams() );
143 $this->assertEquals( $warnings[$key], $expectedArray );
144 }
145 }
146
147 /**
148 * @dataProvider provideMockMessageDetails
149 * @covers Status::error
150 * @covers Status::getErrorsArray
151 * @covers Status::getStatusArray
152 */
153 public function testErrorWithMessage( $mockDetails ) {
154 $status = new Status();
155 $messages = $this->getMockMessages( $mockDetails );
156
157 foreach ( $messages as $message ) {
158 $status->error( $message );
159 }
160 $errors = $status->getErrorsArray();
161
162 $this->assertEquals( count( $messages ), count( $errors ) );
163 foreach ( $messages as $key => $message ) {
164 $expectedArray = array_merge( array( $message->getKey() ), $message->getParams() );
165 $this->assertEquals( $errors[$key], $expectedArray );
166 }
167 }
168
169 /**
170 * @dataProvider provideMockMessageDetails
171 * @covers Status::fatal
172 * @covers Status::getErrorsArray
173 * @covers Status::getStatusArray
174 */
175 public function testFatalWithMessage( $mockDetails ) {
176 $status = new Status();
177 $messages = $this->getMockMessages( $mockDetails );
178
179 foreach ( $messages as $message ) {
180 $status->fatal( $message );
181 }
182 $errors = $status->getErrorsArray();
183
184 $this->assertEquals( count( $messages ), count( $errors ) );
185 foreach ( $messages as $key => $message ) {
186 $expectedArray = array_merge( array( $message->getKey() ), $message->getParams() );
187 $this->assertEquals( $errors[$key], $expectedArray );
188 }
189 $this->assertFalse( $status->isOK() );
190 }
191
192 protected function getMockMessage( $key = 'key', $params = array() ) {
193 $message = $this->getMockBuilder( 'Message' )
194 ->disableOriginalConstructor()
195 ->getMock();
196 $message->expects( $this->atLeastOnce() )
197 ->method( 'getKey' )
198 ->will( $this->returnValue( $key ) );
199 $message->expects( $this->atLeastOnce() )
200 ->method( 'getParams' )
201 ->will( $this->returnValue( $params ) );
202 return $message;
203 }
204
205 /**
206 * @param array $messageDetails E.g. array( 'KEY' => array(/PARAMS/) )
207 * @return Message[]
208 */
209 protected function getMockMessages( $messageDetails ) {
210 $messages = array();
211 foreach ( $messageDetails as $key => $paramsArray ) {
212 $messages[] = $this->getMockMessage( $key, $paramsArray );
213 }
214 return $messages;
215 }
216
217 public static function provideMockMessageDetails() {
218 return array(
219 array( array( 'key1' => array( 'foo' => 'bar' ) ) ),
220 array( array( 'key1' => array( 'foo' => 'bar' ), 'key2' => array( 'foo2' => 'bar2' ) ) ),
221 );
222 }
223
224 /**
225 * @covers Status::merge
226 */
227 public function testMerge() {
228 $status1 = new Status();
229 $status2 = new Status();
230 $message1 = $this->getMockMessage( 'warn1' );
231 $message2 = $this->getMockMessage( 'error2' );
232 $status1->warning( $message1 );
233 $status2->error( $message2 );
234
235 $status1->merge( $status2 );
236 $this->assertEquals(
237 2,
238 count( $status1->getWarningsArray() ) + count( $status1->getErrorsArray() )
239 );
240 }
241
242 /**
243 * @covers Status::merge
244 */
245 public function testMergeWithOverwriteValue() {
246 $status1 = new Status();
247 $status2 = new Status();
248 $message1 = $this->getMockMessage( 'warn1' );
249 $message2 = $this->getMockMessage( 'error2' );
250 $status1->warning( $message1 );
251 $status2->error( $message2 );
252 $status2->value = 'FooValue';
253
254 $status1->merge( $status2, true );
255 $this->assertEquals(
256 2,
257 count( $status1->getWarningsArray() ) + count( $status1->getErrorsArray() )
258 );
259 $this->assertEquals( 'FooValue', $status1->getValue() );
260 }
261
262 /**
263 * @covers Status::hasMessage
264 */
265 public function testHasMessage() {
266 $status = new Status();
267 $status->fatal( 'bad' );
268 $status->fatal( wfMessage( 'bad-msg' ) );
269 $this->assertTrue( $status->hasMessage( 'bad' ) );
270 $this->assertTrue( $status->hasMessage( 'bad-msg' ) );
271 $this->assertTrue( $status->hasMessage( wfMessage( 'bad-msg' ) ) );
272 $this->assertFalse( $status->hasMessage( 'good' ) );
273 }
274
275 /**
276 * @dataProvider provideCleanParams
277 * @covers Status::cleanParams
278 */
279 public function testCleanParams( $cleanCallback, $params, $expected ) {
280 $method = new ReflectionMethod( 'Status', 'cleanParams' );
281 $method->setAccessible( true );
282 $status = new Status();
283 $status->cleanCallback = $cleanCallback;
284
285 $this->assertEquals( $expected, $method->invoke( $status, $params ) );
286 }
287
288 public static function provideCleanParams() {
289 $cleanCallback = function ( $value ) {
290 return '-' . $value . '-';
291 };
292
293 return array(
294 array( false, array( 'foo' => 'bar' ), array( 'foo' => 'bar' ) ),
295 array( $cleanCallback, array( 'foo' => 'bar' ), array( 'foo' => '-bar-' ) ),
296 );
297 }
298
299 /**
300 * @dataProvider provideGetWikiTextAndHtml
301 * @covers Status::getWikiText
302 * @todo test long and short context messages generated through this method
303 * this can not really be done now due to use of wfMessage()->plain()
304 * It is possible to mock such methods but only if namespaces are used
305 */
306 public function testGetWikiText( Status $status, $wikitext, $html ) {
307 $this->assertEquals( $wikitext, $status->getWikiText() );
308 }
309
310 /**
311 * @dataProvider provideGetWikiTextAndHtml
312 * @covers Status::getHtml
313 * @todo test long and short context messages generated through this method
314 * this can not really be done now due to use of $this->getWikiText using
315 * wfMessage()->plain(). It is possible to mock such methods but only if
316 * namespaces are used.
317 */
318 public function testGetHtml( Status $status, $wikitext, $html ) {
319 $this->assertEquals( $html, $status->getHTML() );
320 }
321
322 /**
323 * @return array of arrays with values;
324 * 0 => status object
325 * 1 => expected string (with no context)
326 */
327 public static function provideGetWikiTextAndHtml() {
328 $testCases = array();
329
330 $testCases['GoodStatus'] = array(
331 new Status(),
332 "Internal error: Status::getWikiText called for a good result, this is incorrect\n",
333 "<p>Internal error: Status::getWikiText called for a good result, this is incorrect\n</p>",
334 );
335
336 $status = new Status();
337 $status->ok = false;
338 $testCases['GoodButNoError'] = array(
339 $status,
340 "Internal error: Status::getWikiText: Invalid result object: no error text but not OK\n",
341 "<p>Internal error: Status::getWikiText: Invalid result object: no error text but not OK\n</p>",
342 );
343
344 $status = new Status();
345 $status->warning( 'fooBar!' );
346 $testCases['1StringWarning'] = array(
347 $status,
348 "<fooBar!>",
349 "<p>&lt;fooBar!&gt;\n</p>",
350 );
351
352 $status = new Status();
353 $status->warning( 'fooBar!' );
354 $status->warning( 'fooBar2!' );
355 $testCases['2StringWarnings'] = array(
356 $status,
357 "* <fooBar!>\n* <fooBar2!>\n",
358 "<ul><li> &lt;fooBar!&gt;</li>\n<li> &lt;fooBar2!&gt;</li></ul>\n",
359 );
360
361 $status = new Status();
362 $status->warning( new Message( 'fooBar!', array( 'foo', 'bar' ) ) );
363 $testCases['1MessageWarning'] = array(
364 $status,
365 "<fooBar!>",
366 "<p>&lt;fooBar!&gt;\n</p>",
367 );
368
369 $status = new Status();
370 $status->warning( new Message( 'fooBar!', array( 'foo', 'bar' ) ) );
371 $status->warning( new Message( 'fooBar2!' ) );
372 $testCases['2MessageWarnings'] = array(
373 $status,
374 "* <fooBar!>\n* <fooBar2!>\n",
375 "<ul><li> &lt;fooBar!&gt;</li>\n<li> &lt;fooBar2!&gt;</li></ul>\n",
376 );
377
378 return $testCases;
379 }
380
381 /**
382 * @dataProvider provideGetMessage
383 * @covers Status::getMessage
384 * @todo test long and short context messages generated through this method
385 */
386 public function testGetMessage( Status $status, $expectedParams = array(), $expectedKey ) {
387 $message = $status->getMessage();
388 $this->assertInstanceOf( 'Message', $message );
389 $this->assertEquals( $expectedParams, $message->getParams(), 'Message::getParams' );
390 $this->assertEquals( $expectedKey, $message->getKey(), 'Message::getKey' );
391 }
392
393 /**
394 * @return array of arrays with values;
395 * 0 => status object
396 * 1 => expected Message parameters (with no context)
397 * 2 => expected Message key
398 */
399 public static function provideGetMessage() {
400 $testCases = array();
401
402 $testCases['GoodStatus'] = array(
403 new Status(),
404 array( "Status::getMessage called for a good result, this is incorrect\n" ),
405 'internalerror_info'
406 );
407
408 $status = new Status();
409 $status->ok = false;
410 $testCases['GoodButNoError'] = array(
411 $status,
412 array( "Status::getMessage: Invalid result object: no error text but not OK\n" ),
413 'internalerror_info'
414 );
415
416 $status = new Status();
417 $status->warning( 'fooBar!' );
418 $testCases['1StringWarning'] = array(
419 $status,
420 array(),
421 'fooBar!'
422 );
423
424 // FIXME: Assertion tries to compare a StubUserLang with a Language object, because
425 // "data providers are executed before both the call to the setUpBeforeClass static method
426 // and the first call to the setUp method. Because of that you can't access any variables
427 // you create there from within a data provider."
428 // http://phpunit.de/manual/3.7/en/writing-tests-for-phpunit.html
429 // $status = new Status();
430 // $status->warning( 'fooBar!' );
431 // $status->warning( 'fooBar2!' );
432 // $testCases[ '2StringWarnings' ] = array(
433 // $status,
434 // array( new Message( 'fooBar!' ), new Message( 'fooBar2!' ) ),
435 // "* \$1\n* \$2"
436 // );
437
438 $status = new Status();
439 $status->warning( new Message( 'fooBar!', array( 'foo', 'bar' ) ) );
440 $testCases['1MessageWarning'] = array(
441 $status,
442 array( 'foo', 'bar' ),
443 'fooBar!'
444 );
445
446 $status = new Status();
447 $status->warning( new Message( 'fooBar!', array( 'foo', 'bar' ) ) );
448 $status->warning( new Message( 'fooBar2!' ) );
449 $testCases['2MessageWarnings'] = array(
450 $status,
451 array( new Message( 'fooBar!', array( 'foo', 'bar' ) ), new Message( 'fooBar2!' ) ),
452 "* \$1\n* \$2"
453 );
454
455 return $testCases;
456 }
457
458 /**
459 * @covers Status::replaceMessage
460 */
461 public function testReplaceMessage() {
462 $status = new Status();
463 $message = new Message( 'key1', array( 'foo1', 'bar1' ) );
464 $status->error( $message );
465 $newMessage = new Message( 'key2', array( 'foo2', 'bar2' ) );
466
467 $status->replaceMessage( $message, $newMessage );
468
469 $this->assertEquals( $newMessage, $status->errors[0]['message'] );
470 }
471
472 /**
473 * @covers Status::getErrorMessage
474 */
475 public function testGetErrorMessage() {
476 $method = new ReflectionMethod( 'Status', 'getErrorMessage' );
477 $method->setAccessible( true );
478 $status = new Status();
479 $key = 'foo';
480 $params = array( 'bar' );
481
482 /** @var Message $message */
483 $message = $method->invoke( $status, array_merge( array( $key ), $params ) );
484 $this->assertInstanceOf( 'Message', $message );
485 $this->assertEquals( $key, $message->getKey() );
486 $this->assertEquals( $params, $message->getParams() );
487 }
488
489 /**
490 * @covers Status::getErrorMessageArray
491 */
492 public function testGetErrorMessageArray() {
493 $method = new ReflectionMethod( 'Status', 'getErrorMessageArray' );
494 $method->setAccessible( true );
495 $status = new Status();
496 $key = 'foo';
497 $params = array( 'bar' );
498
499 /** @var Message[] $messageArray */
500 $messageArray = $method->invoke(
501 $status,
502 array(
503 array_merge( array( $key ), $params ),
504 array_merge( array( $key ), $params )
505 )
506 );
507
508 $this->assertInternalType( 'array', $messageArray );
509 $this->assertCount( 2, $messageArray );
510 foreach ( $messageArray as $message ) {
511 $this->assertInstanceOf( 'Message', $message );
512 $this->assertEquals( $key, $message->getKey() );
513 $this->assertEquals( $params, $message->getParams() );
514 }
515 }
516
517 /**
518 * @covers Status::getErrorsByType
519 */
520 public function testGetErrorsByType() {
521 $status = new Status();
522 $warning = new Message( 'warning111' );
523 $error = new Message( 'error111' );
524 $status->warning( $warning );
525 $status->error( $error );
526
527 $warnings = $status->getErrorsByType( 'warning' );
528 $errors = $status->getErrorsByType( 'error' );
529
530 $this->assertCount( 1, $warnings );
531 $this->assertCount( 1, $errors );
532 $this->assertEquals( $warning, $warnings[0]['message'] );
533 $this->assertEquals( $error, $errors[0]['message'] );
534 }
535
536 /**
537 * @covers Status::__wakeup
538 */
539 public function testWakeUpSanitizesCallback() {
540 $status = new Status();
541 $status->cleanCallback = function ( $value ) {
542 return '-' . $value . '-';
543 };
544 $status->__wakeup();
545 $this->assertEquals( false, $status->cleanCallback );
546 }
547
548 /**
549 * @dataProvider provideNonObjectMessages
550 * @covers Status::getStatusArray
551 */
552 public function testGetStatusArrayWithNonObjectMessages( $nonObjMsg ) {
553 $status = new Status();
554 if ( !array_key_exists( 1, $nonObjMsg ) ) {
555 $status->warning( $nonObjMsg[0] );
556 } else {
557 $status->warning( $nonObjMsg[0], $nonObjMsg[1] );
558 }
559
560 $array = $status->getWarningsArray(); // We use getWarningsArray to access getStatusArray
561
562 $this->assertEquals( 1, count( $array ) );
563 $this->assertEquals( $nonObjMsg, $array[0] );
564 }
565
566 public static function provideNonObjectMessages() {
567 return array(
568 array( array( 'ImaString', array( 'param1' => 'value1' ) ) ),
569 array( array( 'ImaString' ) ),
570 );
571 }
572
573 }