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