Remove hard deprecation of PasswordPolicyChecks::checkPopularPasswordBlacklist
[lhc/web/wiklou.git] / tests / phpunit / includes / api / ApiErrorFormatterTest.php
1 <?php
2
3 use Wikimedia\TestingAccessWrapper;
4
5 /**
6 * @group API
7 */
8 class ApiErrorFormatterTest extends MediaWikiLangTestCase {
9
10 /**
11 * @covers ApiErrorFormatter
12 */
13 public function testErrorFormatterBasics() {
14 $result = new ApiResult( 8388608 );
15 $formatter = new ApiErrorFormatter( $result, Language::factory( 'de' ), 'wikitext', false );
16 $this->assertSame( 'de', $formatter->getLanguage()->getCode() );
17 $this->assertSame( 'wikitext', $formatter->getFormat() );
18
19 $formatter->addMessagesFromStatus( null, Status::newGood() );
20 $this->assertSame(
21 [ ApiResult::META_TYPE => 'assoc' ],
22 $result->getResultData()
23 );
24
25 $this->assertSame( [], $formatter->arrayFromStatus( Status::newGood() ) );
26
27 $wrappedFormatter = TestingAccessWrapper::newFromObject( $formatter );
28 $this->assertSame(
29 'Blah "kbd" <X> 😊',
30 $wrappedFormatter->stripMarkup( 'Blah <kbd>kbd</kbd> <b>&lt;X&gt;</b> &#x1f60a;' ),
31 'stripMarkup'
32 );
33 }
34
35 /**
36 * @covers ApiErrorFormatter
37 * @covers ApiErrorFormatter_BackCompat
38 */
39 public function testNewWithFormat() {
40 $result = new ApiResult( 8388608 );
41 $formatter = new ApiErrorFormatter( $result, Language::factory( 'de' ), 'wikitext', false );
42 $formatter2 = $formatter->newWithFormat( 'html' );
43
44 $this->assertSame( $formatter->getLanguage(), $formatter2->getLanguage() );
45 $this->assertSame( 'html', $formatter2->getFormat() );
46
47 $formatter3 = new ApiErrorFormatter_BackCompat( $result );
48 $formatter4 = $formatter3->newWithFormat( 'html' );
49 $this->assertNotInstanceOf( ApiErrorFormatter_BackCompat::class, $formatter4 );
50 $this->assertSame( $formatter3->getLanguage(), $formatter4->getLanguage() );
51 $this->assertSame( 'html', $formatter4->getFormat() );
52 }
53
54 /**
55 * @covers ApiErrorFormatter
56 * @dataProvider provideErrorFormatter
57 */
58 public function testErrorFormatter( $format, $lang, $useDB,
59 $expect1, $expect2, $expect3
60 ) {
61 $result = new ApiResult( 8388608 );
62 $formatter = new ApiErrorFormatter( $result, Language::factory( $lang ), $format, $useDB );
63
64 // Add default type
65 $expect1[ApiResult::META_TYPE] = 'assoc';
66 $expect2[ApiResult::META_TYPE] = 'assoc';
67 $expect3[ApiResult::META_TYPE] = 'assoc';
68
69 $formatter->addWarning( 'string', 'mainpage' );
70 $formatter->addError( 'err', 'mainpage' );
71 $this->assertEquals( $expect1, $result->getResultData(), 'Simple test' );
72
73 $result->reset();
74 $formatter->addWarning( 'foo', 'mainpage' );
75 $formatter->addWarning( 'foo', 'mainpage' );
76 $formatter->addWarning( 'foo', [ 'parentheses', 'foobar' ] );
77 $msg1 = wfMessage( 'mainpage' );
78 $formatter->addWarning( 'message', $msg1 );
79 $msg2 = new ApiMessage( 'mainpage', 'overriddenCode', [ 'overriddenData' => true ] );
80 $formatter->addWarning( 'messageWithData', $msg2 );
81 $formatter->addError( 'errWithData', $msg2 );
82 $this->assertSame( $expect2, $result->getResultData(), 'Complex test' );
83
84 $this->assertEquals(
85 $this->removeModuleTag( $expect2['warnings'][2] ),
86 $formatter->formatMessage( $msg1 ),
87 'formatMessage test 1'
88 );
89 $this->assertEquals(
90 $this->removeModuleTag( $expect2['warnings'][3] ),
91 $formatter->formatMessage( $msg2 ),
92 'formatMessage test 2'
93 );
94
95 $result->reset();
96 $status = Status::newGood();
97 $status->warning( 'mainpage' );
98 $status->warning( 'parentheses', 'foobar' );
99 $status->warning( $msg1 );
100 $status->warning( $msg2 );
101 $status->error( 'mainpage' );
102 $status->error( 'parentheses', 'foobar' );
103 $formatter->addMessagesFromStatus( 'status', $status );
104 $this->assertSame( $expect3, $result->getResultData(), 'Status test' );
105
106 $this->assertSame(
107 array_map( [ $this, 'removeModuleTag' ], $expect3['errors'] ),
108 $formatter->arrayFromStatus( $status, 'error' ),
109 'arrayFromStatus test for error'
110 );
111 $this->assertSame(
112 array_map( [ $this, 'removeModuleTag' ], $expect3['warnings'] ),
113 $formatter->arrayFromStatus( $status, 'warning' ),
114 'arrayFromStatus test for warning'
115 );
116 }
117
118 private function removeModuleTag( $s ) {
119 if ( is_array( $s ) ) {
120 unset( $s['module'] );
121 }
122 return $s;
123 }
124
125 public static function provideErrorFormatter() {
126 $mainpageText = wfMessage( 'mainpage' )->inLanguage( 'de' )->useDatabase( false )->text();
127 $parensText = wfMessage( 'parentheses', 'foobar' )->inLanguage( 'de' )
128 ->useDatabase( false )->text();
129 $mainpageHTML = wfMessage( 'mainpage' )->inLanguage( 'en' )->parse();
130 $parensHTML = wfMessage( 'parentheses', 'foobar' )->inLanguage( 'en' )->parse();
131 $C = ApiResult::META_CONTENT;
132 $I = ApiResult::META_INDEXED_TAG_NAME;
133 $overriddenData = [ 'overriddenData' => true, ApiResult::META_TYPE => 'assoc' ];
134
135 return [
136 $tmp = [ 'wikitext', 'de', false,
137 [
138 'errors' => [
139 [ 'code' => 'mainpage', 'text' => $mainpageText, 'module' => 'err', $C => 'text' ],
140 $I => 'error',
141 ],
142 'warnings' => [
143 [ 'code' => 'mainpage', 'text' => $mainpageText, 'module' => 'string', $C => 'text' ],
144 $I => 'warning',
145 ],
146 ],
147 [
148 'errors' => [
149 [ 'code' => 'overriddenCode', 'text' => $mainpageText,
150 'data' => $overriddenData, 'module' => 'errWithData', $C => 'text' ],
151 $I => 'error',
152 ],
153 'warnings' => [
154 [ 'code' => 'mainpage', 'text' => $mainpageText, 'module' => 'foo', $C => 'text' ],
155 [ 'code' => 'parentheses', 'text' => $parensText, 'module' => 'foo', $C => 'text' ],
156 [ 'code' => 'mainpage', 'text' => $mainpageText, 'module' => 'message', $C => 'text' ],
157 [ 'code' => 'overriddenCode', 'text' => $mainpageText,
158 'data' => $overriddenData, 'module' => 'messageWithData', $C => 'text' ],
159 $I => 'warning',
160 ],
161 ],
162 [
163 'errors' => [
164 [ 'code' => 'mainpage', 'text' => $mainpageText, 'module' => 'status', $C => 'text' ],
165 [ 'code' => 'parentheses', 'text' => $parensText, 'module' => 'status', $C => 'text' ],
166 $I => 'error',
167 ],
168 'warnings' => [
169 [ 'code' => 'mainpage', 'text' => $mainpageText, 'module' => 'status', $C => 'text' ],
170 [ 'code' => 'parentheses', 'text' => $parensText, 'module' => 'status', $C => 'text' ],
171 [ 'code' => 'overriddenCode', 'text' => $mainpageText,
172 'data' => $overriddenData, 'module' => 'status', $C => 'text' ],
173 $I => 'warning',
174 ],
175 ],
176 ],
177 [ 'plaintext' ] + $tmp, // For these messages, plaintext and wikitext are the same
178 [ 'html', 'en', true,
179 [
180 'errors' => [
181 [ 'code' => 'mainpage', 'html' => $mainpageHTML, 'module' => 'err', $C => 'html' ],
182 $I => 'error',
183 ],
184 'warnings' => [
185 [ 'code' => 'mainpage', 'html' => $mainpageHTML, 'module' => 'string', $C => 'html' ],
186 $I => 'warning',
187 ],
188 ],
189 [
190 'errors' => [
191 [ 'code' => 'overriddenCode', 'html' => $mainpageHTML,
192 'data' => $overriddenData, 'module' => 'errWithData', $C => 'html' ],
193 $I => 'error',
194 ],
195 'warnings' => [
196 [ 'code' => 'mainpage', 'html' => $mainpageHTML, 'module' => 'foo', $C => 'html' ],
197 [ 'code' => 'parentheses', 'html' => $parensHTML, 'module' => 'foo', $C => 'html' ],
198 [ 'code' => 'mainpage', 'html' => $mainpageHTML, 'module' => 'message', $C => 'html' ],
199 [ 'code' => 'overriddenCode', 'html' => $mainpageHTML,
200 'data' => $overriddenData, 'module' => 'messageWithData', $C => 'html' ],
201 $I => 'warning',
202 ],
203 ],
204 [
205 'errors' => [
206 [ 'code' => 'mainpage', 'html' => $mainpageHTML, 'module' => 'status', $C => 'html' ],
207 [ 'code' => 'parentheses', 'html' => $parensHTML, 'module' => 'status', $C => 'html' ],
208 $I => 'error',
209 ],
210 'warnings' => [
211 [ 'code' => 'mainpage', 'html' => $mainpageHTML, 'module' => 'status', $C => 'html' ],
212 [ 'code' => 'parentheses', 'html' => $parensHTML, 'module' => 'status', $C => 'html' ],
213 [ 'code' => 'overriddenCode', 'html' => $mainpageHTML,
214 'data' => $overriddenData, 'module' => 'status', $C => 'html' ],
215 $I => 'warning',
216 ],
217 ],
218 ],
219 [ 'raw', 'fr', true,
220 [
221 'errors' => [
222 [
223 'code' => 'mainpage',
224 'key' => 'mainpage',
225 'params' => [ $I => 'param' ],
226 'module' => 'err',
227 ],
228 $I => 'error',
229 ],
230 'warnings' => [
231 [
232 'code' => 'mainpage',
233 'key' => 'mainpage',
234 'params' => [ $I => 'param' ],
235 'module' => 'string',
236 ],
237 $I => 'warning',
238 ],
239 ],
240 [
241 'errors' => [
242 [
243 'code' => 'overriddenCode',
244 'key' => 'mainpage',
245 'params' => [ $I => 'param' ],
246 'data' => $overriddenData,
247 'module' => 'errWithData',
248 ],
249 $I => 'error',
250 ],
251 'warnings' => [
252 [
253 'code' => 'mainpage',
254 'key' => 'mainpage',
255 'params' => [ $I => 'param' ],
256 'module' => 'foo',
257 ],
258 [
259 'code' => 'parentheses',
260 'key' => 'parentheses',
261 'params' => [ 'foobar', $I => 'param' ],
262 'module' => 'foo',
263 ],
264 [
265 'code' => 'mainpage',
266 'key' => 'mainpage',
267 'params' => [ $I => 'param' ],
268 'module' => 'message',
269 ],
270 [
271 'code' => 'overriddenCode',
272 'key' => 'mainpage',
273 'params' => [ $I => 'param' ],
274 'data' => $overriddenData,
275 'module' => 'messageWithData',
276 ],
277 $I => 'warning',
278 ],
279 ],
280 [
281 'errors' => [
282 [
283 'code' => 'mainpage',
284 'key' => 'mainpage',
285 'params' => [ $I => 'param' ],
286 'module' => 'status',
287 ],
288 [
289 'code' => 'parentheses',
290 'key' => 'parentheses',
291 'params' => [ 'foobar', $I => 'param' ],
292 'module' => 'status',
293 ],
294 $I => 'error',
295 ],
296 'warnings' => [
297 [
298 'code' => 'mainpage',
299 'key' => 'mainpage',
300 'params' => [ $I => 'param' ],
301 'module' => 'status',
302 ],
303 [
304 'code' => 'parentheses',
305 'key' => 'parentheses',
306 'params' => [ 'foobar', $I => 'param' ],
307 'module' => 'status',
308 ],
309 [
310 'code' => 'overriddenCode',
311 'key' => 'mainpage',
312 'params' => [ $I => 'param' ],
313 'data' => $overriddenData,
314 'module' => 'status',
315 ],
316 $I => 'warning',
317 ],
318 ],
319 ],
320 [ 'none', 'fr', true,
321 [
322 'errors' => [
323 [ 'code' => 'mainpage', 'module' => 'err' ],
324 $I => 'error',
325 ],
326 'warnings' => [
327 [ 'code' => 'mainpage', 'module' => 'string' ],
328 $I => 'warning',
329 ],
330 ],
331 [
332 'errors' => [
333 [ 'code' => 'overriddenCode', 'data' => $overriddenData,
334 'module' => 'errWithData' ],
335 $I => 'error',
336 ],
337 'warnings' => [
338 [ 'code' => 'mainpage', 'module' => 'foo' ],
339 [ 'code' => 'parentheses', 'module' => 'foo' ],
340 [ 'code' => 'mainpage', 'module' => 'message' ],
341 [ 'code' => 'overriddenCode', 'data' => $overriddenData,
342 'module' => 'messageWithData' ],
343 $I => 'warning',
344 ],
345 ],
346 [
347 'errors' => [
348 [ 'code' => 'mainpage', 'module' => 'status' ],
349 [ 'code' => 'parentheses', 'module' => 'status' ],
350 $I => 'error',
351 ],
352 'warnings' => [
353 [ 'code' => 'mainpage', 'module' => 'status' ],
354 [ 'code' => 'parentheses', 'module' => 'status' ],
355 [ 'code' => 'overriddenCode', 'data' => $overriddenData, 'module' => 'status' ],
356 $I => 'warning',
357 ],
358 ],
359 ],
360 ];
361 }
362
363 /**
364 * @covers ApiErrorFormatter_BackCompat
365 */
366 public function testErrorFormatterBC() {
367 $mainpagePlain = wfMessage( 'mainpage' )->useDatabase( false )->plain();
368 $parensPlain = wfMessage( 'parentheses', 'foobar' )->useDatabase( false )->plain();
369
370 $result = new ApiResult( 8388608 );
371 $formatter = new ApiErrorFormatter_BackCompat( $result );
372
373 $this->assertSame( 'en', $formatter->getLanguage()->getCode() );
374 $this->assertSame( 'bc', $formatter->getFormat() );
375
376 $this->assertSame( [], $formatter->arrayFromStatus( Status::newGood() ) );
377
378 $formatter->addWarning( 'string', 'mainpage' );
379 $formatter->addWarning( 'raw',
380 new RawMessage( 'Blah <kbd>kbd</kbd> <b>&lt;X&gt;</b> &#x1f61e;' )
381 );
382 $formatter->addError( 'err', 'mainpage' );
383 $this->assertSame( [
384 'error' => [
385 'code' => 'mainpage',
386 'info' => $mainpagePlain,
387 ],
388 'warnings' => [
389 'raw' => [
390 'warnings' => 'Blah "kbd" <X> 😞',
391 ApiResult::META_CONTENT => 'warnings',
392 ],
393 'string' => [
394 'warnings' => $mainpagePlain,
395 ApiResult::META_CONTENT => 'warnings',
396 ],
397 ],
398 ApiResult::META_TYPE => 'assoc',
399 ], $result->getResultData(), 'Simple test' );
400
401 $result->reset();
402 $formatter->addWarning( 'foo', 'mainpage' );
403 $formatter->addWarning( 'foo', 'mainpage' );
404 $formatter->addWarning( 'xxx+foo', [ 'parentheses', 'foobar' ] );
405 $msg1 = wfMessage( 'mainpage' );
406 $formatter->addWarning( 'message', $msg1 );
407 $msg2 = new ApiMessage( 'mainpage', 'overriddenCode', [ 'overriddenData' => true ] );
408 $formatter->addWarning( 'messageWithData', $msg2 );
409 $formatter->addError( 'errWithData', $msg2 );
410 $formatter->addWarning( null, 'mainpage' );
411 $this->assertSame( [
412 'error' => [
413 'code' => 'overriddenCode',
414 'info' => $mainpagePlain,
415 'overriddenData' => true,
416 ],
417 'warnings' => [
418 'unknown' => [
419 'warnings' => $mainpagePlain,
420 ApiResult::META_CONTENT => 'warnings',
421 ],
422 'messageWithData' => [
423 'warnings' => $mainpagePlain,
424 ApiResult::META_CONTENT => 'warnings',
425 ],
426 'message' => [
427 'warnings' => $mainpagePlain,
428 ApiResult::META_CONTENT => 'warnings',
429 ],
430 'foo' => [
431 'warnings' => "$mainpagePlain\n$parensPlain",
432 ApiResult::META_CONTENT => 'warnings',
433 ],
434 ],
435 ApiResult::META_TYPE => 'assoc',
436 ], $result->getResultData(), 'Complex test' );
437
438 $this->assertSame(
439 [
440 'code' => 'mainpage',
441 'info' => 'Main Page',
442 ],
443 $formatter->formatMessage( $msg1 )
444 );
445 $this->assertSame(
446 [
447 'code' => 'overriddenCode',
448 'info' => 'Main Page',
449 'overriddenData' => true,
450 ],
451 $formatter->formatMessage( $msg2 )
452 );
453
454 $result->reset();
455 $status = Status::newGood();
456 $status->warning( 'mainpage' );
457 $status->warning( 'parentheses', 'foobar' );
458 $status->warning( $msg1 );
459 $status->warning( $msg2 );
460 $status->error( 'mainpage' );
461 $status->error( 'parentheses', 'foobar' );
462 $formatter->addMessagesFromStatus( 'status', $status );
463 $this->assertSame( [
464 'error' => [
465 'code' => 'mainpage',
466 'info' => $mainpagePlain,
467 ],
468 'warnings' => [
469 'status' => [
470 'warnings' => "$mainpagePlain\n$parensPlain",
471 ApiResult::META_CONTENT => 'warnings',
472 ],
473 ],
474 ApiResult::META_TYPE => 'assoc',
475 ], $result->getResultData(), 'Status test' );
476
477 $I = ApiResult::META_INDEXED_TAG_NAME;
478 $this->assertSame(
479 [
480 [
481 'message' => 'mainpage',
482 'params' => [ $I => 'param' ],
483 'code' => 'mainpage',
484 'type' => 'error',
485 ],
486 [
487 'message' => 'parentheses',
488 'params' => [ 'foobar', $I => 'param' ],
489 'code' => 'parentheses',
490 'type' => 'error',
491 ],
492 $I => 'error',
493 ],
494 $formatter->arrayFromStatus( $status, 'error' ),
495 'arrayFromStatus test for error'
496 );
497 $this->assertSame(
498 [
499 [
500 'message' => 'mainpage',
501 'params' => [ $I => 'param' ],
502 'code' => 'mainpage',
503 'type' => 'warning',
504 ],
505 [
506 'message' => 'parentheses',
507 'params' => [ 'foobar', $I => 'param' ],
508 'code' => 'parentheses',
509 'type' => 'warning',
510 ],
511 [
512 'message' => 'mainpage',
513 'params' => [ $I => 'param' ],
514 'code' => 'mainpage',
515 'type' => 'warning',
516 ],
517 [
518 'message' => 'mainpage',
519 'params' => [ $I => 'param' ],
520 'code' => 'overriddenCode',
521 'type' => 'warning',
522 ],
523 $I => 'warning',
524 ],
525 $formatter->arrayFromStatus( $status, 'warning' ),
526 'arrayFromStatus test for warning'
527 );
528
529 $result->reset();
530 $result->addValue( null, 'error', [ 'bogus' ] );
531 $formatter->addError( 'err', 'mainpage' );
532 $this->assertSame( [
533 'error' => [
534 'code' => 'mainpage',
535 'info' => $mainpagePlain,
536 ],
537 ApiResult::META_TYPE => 'assoc',
538 ], $result->getResultData(), 'Overwrites bogus "error" value with real error' );
539 }
540
541 /**
542 * @dataProvider provideGetMessageFromException
543 * @covers ApiErrorFormatter::getMessageFromException
544 * @covers ApiErrorFormatter::formatException
545 * @param Exception $exception
546 * @param array $options
547 * @param array $expect
548 */
549 public function testGetMessageFromException( $exception, $options, $expect ) {
550 $result = new ApiResult( 8388608 );
551 $formatter = new ApiErrorFormatter( $result, Language::factory( 'en' ), 'html', false );
552
553 $msg = $formatter->getMessageFromException( $exception, $options );
554 $this->assertInstanceOf( Message::class, $msg );
555 $this->assertInstanceOf( IApiMessage::class, $msg );
556 $this->assertSame( $expect, [
557 'text' => $msg->parse(),
558 'code' => $msg->getApiCode(),
559 'data' => $msg->getApiData(),
560 ] );
561
562 $expectFormatted = $formatter->formatMessage( $msg );
563 $formatted = $formatter->formatException( $exception, $options );
564 $this->assertSame( $expectFormatted, $formatted );
565 }
566
567 /**
568 * @dataProvider provideGetMessageFromException
569 * @covers ApiErrorFormatter_BackCompat::formatException
570 * @param Exception $exception
571 * @param array $options
572 * @param array $expect
573 */
574 public function testGetMessageFromException_BC( $exception, $options, $expect ) {
575 $result = new ApiResult( 8388608 );
576 $formatter = new ApiErrorFormatter_BackCompat( $result );
577
578 $msg = $formatter->getMessageFromException( $exception, $options );
579 $this->assertInstanceOf( Message::class, $msg );
580 $this->assertInstanceOf( IApiMessage::class, $msg );
581 $this->assertSame( $expect, [
582 'text' => $msg->parse(),
583 'code' => $msg->getApiCode(),
584 'data' => $msg->getApiData(),
585 ] );
586
587 $expectFormatted = $formatter->formatMessage( $msg );
588 $formatted = $formatter->formatException( $exception, $options );
589 $this->assertSame( $expectFormatted, $formatted );
590 $formatted = $formatter->formatException( $exception, $options + [ 'bc' => true ] );
591 $this->assertSame( $expectFormatted['info'], $formatted );
592 }
593
594 public static function provideGetMessageFromException() {
595 return [
596 'Normal exception' => [
597 new RuntimeException( '<b>Something broke!</b>' ),
598 [],
599 [
600 'text' => '&#60;b&#62;Something broke!&#60;/b&#62;',
601 'code' => 'internal_api_error_RuntimeException',
602 'data' => [
603 'errorclass' => 'RuntimeException',
604 ],
605 ]
606 ],
607 'Normal exception, wrapped' => [
608 new RuntimeException( '<b>Something broke!</b>' ),
609 [ 'wrap' => 'parentheses', 'code' => 'some-code', 'data' => [ 'foo' => 'bar', 'baz' => 42 ] ],
610 [
611 'text' => '(&#60;b&#62;Something broke!&#60;/b&#62;)',
612 'code' => 'some-code',
613 'data' => [ 'foo' => 'bar', 'baz' => 42 ],
614 ]
615 ],
616 'LocalizedException' => [
617 new LocalizedException( [ 'returnto', '<b>FooBar</b>' ] ),
618 [],
619 [
620 'text' => 'Return to <b>FooBar</b>.',
621 'code' => 'returnto',
622 'data' => [],
623 ]
624 ],
625 'LocalizedException, wrapped' => [
626 new LocalizedException( [ 'returnto', '<b>FooBar</b>' ] ),
627 [ 'wrap' => 'parentheses', 'code' => 'some-code', 'data' => [ 'foo' => 'bar', 'baz' => 42 ] ],
628 [
629 'text' => 'Return to <b>FooBar</b>.',
630 'code' => 'some-code',
631 'data' => [ 'foo' => 'bar', 'baz' => 42 ],
632 ]
633 ],
634 ];
635 }
636
637 /**
638 * @covers ApiErrorFormatter::addMessagesFromStatus
639 * @covers ApiErrorFormatter::addWarningOrError
640 * @covers ApiErrorFormatter::formatMessageInternal
641 */
642 public function testAddMessagesFromStatus_filter() {
643 $result = new ApiResult( 8388608 );
644 $formatter = new ApiErrorFormatter( $result, Language::factory( 'qqx' ), 'plaintext', false );
645
646 $status = Status::newGood();
647 $status->warning( 'mainpage' );
648 $status->warning( 'parentheses', 'foobar' );
649 $status->warning( wfMessage( 'mainpage' ) );
650 $status->error( 'mainpage' );
651 $status->error( 'parentheses', 'foobaz' );
652 $formatter->addMessagesFromStatus( 'status', $status, [ 'warning', 'error' ], [ 'mainpage' ] );
653 $this->assertSame( [
654 'errors' => [
655 [
656 'code' => 'parentheses',
657 'text' => '(parentheses: foobaz)',
658 'module' => 'status',
659 ApiResult::META_CONTENT => 'text',
660 ],
661 ApiResult::META_INDEXED_TAG_NAME => 'error',
662 ],
663 'warnings' => [
664 [
665 'code' => 'parentheses',
666 'text' => '(parentheses: foobar)',
667 'module' => 'status',
668 ApiResult::META_CONTENT => 'text',
669 ],
670 ApiResult::META_INDEXED_TAG_NAME => 'warning',
671 ],
672 ApiResult::META_TYPE => 'assoc',
673 ], $result->getResultData() );
674 }
675
676 /**
677 * @dataProvider provideIsValidApiCode
678 * @covers ApiErrorFormatter::isValidApiCode
679 * @param string $code
680 * @param bool $expect
681 */
682 public function testIsValidApiCode( $code, $expect ) {
683 $this->assertSame( $expect, ApiErrorFormatter::isValidApiCode( $code ) );
684 }
685
686 public static function provideIsValidApiCode() {
687 return [
688 [ 'foo-bar_Baz123', true ],
689 [ 'foo bar', false ],
690 [ 'foo\\bar', false ],
691 [ 'internal_api_error_foo\\bar baz', true ],
692 ];
693 }
694
695 }