Merge "ApiComparePages: Add 'fromsection' and 'tosection' parameters"
[lhc/web/wiklou.git] / tests / phpunit / includes / api / ApiComparePagesTest.php
1 <?php
2
3 /**
4 * @group API
5 * @group Database
6 * @group medium
7 * @covers ApiComparePages
8 */
9 class ApiComparePagesTest extends ApiTestCase {
10
11 protected static $repl = [];
12
13 protected function setUp() {
14 parent::setUp();
15
16 // Set $wgExternalDiffEngine to something bogus to try to force use of
17 // the PHP engine rather than wikidiff2.
18 $this->setMwGlobals( [
19 'wgExternalDiffEngine' => '/dev/null',
20 ] );
21 }
22
23 protected function addPage( $page, $text, $model = CONTENT_MODEL_WIKITEXT ) {
24 $title = Title::newFromText( 'ApiComparePagesTest ' . $page );
25 $content = ContentHandler::makeContent( $text, $title, $model );
26
27 $page = WikiPage::factory( $title );
28 $user = static::getTestSysop()->getUser();
29 $status = $page->doEditContent(
30 $content, 'Test for ApiComparePagesTest: ' . $text, 0, false, $user
31 );
32 if ( !$status->isOK() ) {
33 $this->fail( "Failed to create $title: " . $status->getWikiText( false, false, 'en' ) );
34 }
35 return $status->value['revision']->getId();
36 }
37
38 public function addDBDataOnce() {
39 $user = static::getTestSysop()->getUser();
40 self::$repl['creator'] = $user->getName();
41 self::$repl['creatorid'] = $user->getId();
42
43 self::$repl['revA1'] = $this->addPage( 'A', 'A 1' );
44 self::$repl['revA2'] = $this->addPage( 'A', 'A 2' );
45 self::$repl['revA3'] = $this->addPage( 'A', 'A 3' );
46 self::$repl['revA4'] = $this->addPage( 'A', 'A 4' );
47 self::$repl['pageA'] = Title::newFromText( 'ApiComparePagesTest A' )->getArticleId();
48
49 self::$repl['revB1'] = $this->addPage( 'B', 'B 1' );
50 self::$repl['revB2'] = $this->addPage( 'B', 'B 2' );
51 self::$repl['revB3'] = $this->addPage( 'B', 'B 3' );
52 self::$repl['revB4'] = $this->addPage( 'B', 'B 4' );
53 self::$repl['pageB'] = Title::newFromText( 'ApiComparePagesTest B' )->getArticleId();
54
55 self::$repl['revC1'] = $this->addPage( 'C', 'C 1' );
56 self::$repl['revC2'] = $this->addPage( 'C', 'C 2' );
57 self::$repl['revC3'] = $this->addPage( 'C', 'C 3' );
58 self::$repl['pageC'] = Title::newFromText( 'ApiComparePagesTest C' )->getArticleId();
59
60 $id = $this->addPage( 'D', 'D 1' );
61 self::$repl['pageD'] = Title::newFromText( 'ApiComparePagesTest D' )->getArticleId();
62 wfGetDB( DB_MASTER )->delete( 'revision', [ 'rev_id' => $id ] );
63
64 self::$repl['revE1'] = $this->addPage( 'E', 'E 1' );
65 self::$repl['revE2'] = $this->addPage( 'E', 'E 2' );
66 self::$repl['revE3'] = $this->addPage( 'E', 'E 3' );
67 self::$repl['revE4'] = $this->addPage( 'E', 'E 4' );
68 self::$repl['pageE'] = Title::newFromText( 'ApiComparePagesTest E' )->getArticleId();
69 wfGetDB( DB_MASTER )->update(
70 'page', [ 'page_latest' => 0 ], [ 'page_id' => self::$repl['pageE'] ]
71 );
72
73 self::$repl['revF1'] = $this->addPage( 'F', "== Section 1 ==\nF 1.1\n\n== Section 2 ==\nF 1.2" );
74 self::$repl['pageF'] = Title::newFromText( 'ApiComparePagesTest F' )->getArticleId();
75
76 WikiPage::factory( Title::newFromText( 'ApiComparePagesTest C' ) )
77 ->doDeleteArticleReal( 'Test for ApiComparePagesTest' );
78
79 RevisionDeleter::createList(
80 'revision',
81 RequestContext::getMain(),
82 Title::newFromText( 'ApiComparePagesTest B' ),
83 [ self::$repl['revB2'] ]
84 )->setVisibility( [
85 'value' => [
86 Revision::DELETED_TEXT => 1,
87 Revision::DELETED_USER => 1,
88 Revision::DELETED_COMMENT => 1,
89 ],
90 'comment' => 'Test for ApiComparePages',
91 ] );
92
93 RevisionDeleter::createList(
94 'revision',
95 RequestContext::getMain(),
96 Title::newFromText( 'ApiComparePagesTest B' ),
97 [ self::$repl['revB3'] ]
98 )->setVisibility( [
99 'value' => [
100 Revision::DELETED_USER => 1,
101 Revision::DELETED_COMMENT => 1,
102 Revision::DELETED_RESTRICTED => 1,
103 ],
104 'comment' => 'Test for ApiComparePages',
105 ] );
106
107 Title::clearCaches(); // Otherwise it has the wrong latest revision for some reason
108 }
109
110 protected function doReplacements( &$value ) {
111 if ( is_string( $value ) ) {
112 if ( preg_match( '/^{{REPL:(.+?)}}$/', $value, $m ) ) {
113 $value = self::$repl[$m[1]];
114 } else {
115 $value = preg_replace_callback( '/{{REPL:(.+?)}}/', function ( $m ) {
116 return isset( self::$repl[$m[1]] ) ? self::$repl[$m[1]] : $m[0];
117 }, $value );
118 }
119 } elseif ( is_array( $value ) || is_object( $value ) ) {
120 foreach ( $value as &$v ) {
121 $this->doReplacements( $v );
122 }
123 unset( $v );
124 }
125 }
126
127 /**
128 * @dataProvider provideDiff
129 */
130 public function testDiff( $params, $expect, $exceptionCode = false, $sysop = false ) {
131 $this->doReplacements( $params );
132
133 $params += [
134 'action' => 'compare',
135 ];
136
137 $user = $sysop
138 ? static::getTestSysop()->getUser()
139 : static::getTestUser()->getUser();
140 if ( $exceptionCode ) {
141 try {
142 $this->doApiRequest( $params, null, false, $user );
143 $this->fail( 'Expected exception not thrown' );
144 } catch ( ApiUsageException $ex ) {
145 $this->assertTrue( $this->apiExceptionHasCode( $ex, $exceptionCode ),
146 "Exception with code $exceptionCode" );
147 }
148 } else {
149 $apiResult = $this->doApiRequest( $params, null, false, $user );
150 $apiResult = $apiResult[0];
151 $this->doReplacements( $expect );
152 $this->assertEquals( $expect, $apiResult );
153 }
154 }
155
156 public static function provideDiff() {
157 // phpcs:disable Generic.Files.LineLength.TooLong
158 return [
159 'Basic diff, titles' => [
160 [
161 'fromtitle' => 'ApiComparePagesTest A',
162 'totitle' => 'ApiComparePagesTest B',
163 ],
164 [
165 'compare' => [
166 'fromid' => '{{REPL:pageA}}',
167 'fromrevid' => '{{REPL:revA4}}',
168 'fromns' => 0,
169 'fromtitle' => 'ApiComparePagesTest A',
170 'toid' => '{{REPL:pageB}}',
171 'torevid' => '{{REPL:revB4}}',
172 'tons' => 0,
173 'totitle' => 'ApiComparePagesTest B',
174 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
175 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
176 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">A </del>4</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">B </ins>4</div></td></tr>' . "\n",
177 ]
178 ],
179 ],
180 'Basic diff, page IDs' => [
181 [
182 'fromid' => '{{REPL:pageA}}',
183 'toid' => '{{REPL:pageB}}',
184 ],
185 [
186 'compare' => [
187 'fromid' => '{{REPL:pageA}}',
188 'fromrevid' => '{{REPL:revA4}}',
189 'fromns' => 0,
190 'fromtitle' => 'ApiComparePagesTest A',
191 'toid' => '{{REPL:pageB}}',
192 'torevid' => '{{REPL:revB4}}',
193 'tons' => 0,
194 'totitle' => 'ApiComparePagesTest B',
195 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
196 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
197 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">A </del>4</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">B </ins>4</div></td></tr>' . "\n",
198 ]
199 ],
200 ],
201 'Basic diff, revision IDs' => [
202 [
203 'fromrev' => '{{REPL:revA2}}',
204 'torev' => '{{REPL:revA3}}',
205 ],
206 [
207 'compare' => [
208 'fromid' => '{{REPL:pageA}}',
209 'fromrevid' => '{{REPL:revA2}}',
210 'fromns' => 0,
211 'fromtitle' => 'ApiComparePagesTest A',
212 'toid' => '{{REPL:pageA}}',
213 'torevid' => '{{REPL:revA3}}',
214 'tons' => 0,
215 'totitle' => 'ApiComparePagesTest A',
216 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
217 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
218 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div>A <del class="diffchange diffchange-inline">2</del></div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div>A <ins class="diffchange diffchange-inline">3</ins></div></td></tr>' . "\n",
219 ]
220 ],
221 ],
222 'Basic diff, deleted revision ID as sysop' => [
223 [
224 'fromrev' => '{{REPL:revA2}}',
225 'torev' => '{{REPL:revC2}}',
226 ],
227 [
228 'compare' => [
229 'fromid' => '{{REPL:pageA}}',
230 'fromrevid' => '{{REPL:revA2}}',
231 'fromns' => 0,
232 'fromtitle' => 'ApiComparePagesTest A',
233 'toid' => 0,
234 'torevid' => '{{REPL:revC2}}',
235 'tons' => 0,
236 'totitle' => 'ApiComparePagesTest C',
237 'toarchive' => true,
238 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
239 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
240 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">A </del>2</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">C </ins>2</div></td></tr>' . "\n",
241 ]
242 ],
243 false, true
244 ],
245 'Basic diff, revdel as sysop' => [
246 [
247 'fromrev' => '{{REPL:revA2}}',
248 'torev' => '{{REPL:revB2}}',
249 ],
250 [
251 'compare' => [
252 'fromid' => '{{REPL:pageA}}',
253 'fromrevid' => '{{REPL:revA2}}',
254 'fromns' => 0,
255 'fromtitle' => 'ApiComparePagesTest A',
256 'toid' => '{{REPL:pageB}}',
257 'torevid' => '{{REPL:revB2}}',
258 'tons' => 0,
259 'totitle' => 'ApiComparePagesTest B',
260 'totexthidden' => true,
261 'touserhidden' => true,
262 'tocommenthidden' => true,
263 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
264 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
265 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">A </del>2</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">B </ins>2</div></td></tr>' . "\n",
266 ]
267 ],
268 false, true
269 ],
270 'Basic diff, text' => [
271 [
272 'fromtext' => 'From text',
273 'fromcontentmodel' => 'wikitext',
274 'totext' => 'To text {{subst:PAGENAME}}',
275 'tocontentmodel' => 'wikitext',
276 ],
277 [
278 'compare' => [
279 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
280 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
281 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">From </del>text</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">To </ins>text <ins class="diffchange diffchange-inline">{{subst:PAGENAME}}</ins></div></td></tr>' . "\n",
282 ]
283 ],
284 ],
285 'Basic diff, text 2' => [
286 [
287 'fromtext' => 'From text',
288 'totext' => 'To text {{subst:PAGENAME}}',
289 'tocontentmodel' => 'wikitext',
290 ],
291 [
292 'compare' => [
293 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
294 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
295 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">From </del>text</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">To </ins>text <ins class="diffchange diffchange-inline">{{subst:PAGENAME}}</ins></div></td></tr>' . "\n",
296 ]
297 ],
298 ],
299 'Basic diff, guessed model' => [
300 [
301 'fromtext' => 'From text',
302 'totext' => 'To text',
303 ],
304 [
305 'warnings' => [
306 'compare' => [
307 'warnings' => 'No content model could be determined, assuming wikitext.',
308 ],
309 ],
310 'compare' => [
311 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
312 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
313 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">From </del>text</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">To </ins>text</div></td></tr>' . "\n",
314 ]
315 ],
316 ],
317 'Basic diff, text with title and PST' => [
318 [
319 'fromtext' => 'From text',
320 'totitle' => 'Test',
321 'totext' => 'To text {{subst:PAGENAME}}',
322 'topst' => true,
323 ],
324 [
325 'compare' => [
326 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
327 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
328 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">From </del>text</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">To </ins>text <ins class="diffchange diffchange-inline">Test</ins></div></td></tr>' . "\n",
329 ]
330 ],
331 ],
332 'Basic diff, text with page ID and PST' => [
333 [
334 'fromtext' => 'From text',
335 'toid' => '{{REPL:pageB}}',
336 'totext' => 'To text {{subst:PAGENAME}}',
337 'topst' => true,
338 ],
339 [
340 'compare' => [
341 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
342 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
343 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">From </del>text</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">To </ins>text <ins class="diffchange diffchange-inline">ApiComparePagesTest B</ins></div></td></tr>' . "\n",
344 ]
345 ],
346 ],
347 'Basic diff, text with revision and PST' => [
348 [
349 'fromtext' => 'From text',
350 'torev' => '{{REPL:revB2}}',
351 'totext' => 'To text {{subst:PAGENAME}}',
352 'topst' => true,
353 ],
354 [
355 'compare' => [
356 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
357 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
358 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">From </del>text</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">To </ins>text <ins class="diffchange diffchange-inline">ApiComparePagesTest B</ins></div></td></tr>' . "\n",
359 ]
360 ],
361 ],
362 'Basic diff, text with deleted revision and PST' => [
363 [
364 'fromtext' => 'From text',
365 'torev' => '{{REPL:revC2}}',
366 'totext' => 'To text {{subst:PAGENAME}}',
367 'topst' => true,
368 ],
369 [
370 'compare' => [
371 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
372 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
373 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">From </del>text</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">To </ins>text <ins class="diffchange diffchange-inline">ApiComparePagesTest C</ins></div></td></tr>' . "\n",
374 ]
375 ],
376 false, true
377 ],
378 'Basic diff, test with sections' => [
379 [
380 'fromtitle' => 'ApiComparePagesTest F',
381 'fromsection' => 1,
382 'totext' => "== Section 1 ==\nTo text\n\n== Section 2 ==\nTo text?",
383 'tosection' => 2,
384 ],
385 [
386 'compare' => [
387 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
388 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
389 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div>== Section <del class="diffchange diffchange-inline">1 </del>==</div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div>== Section <ins class="diffchange diffchange-inline">2 </ins>==</div></td></tr>' . "\n"
390 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">F 1.1</del></div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">To text?</ins></div></td></tr>' . "\n",
391 'fromid' => '{{REPL:pageF}}',
392 'fromrevid' => '{{REPL:revF1}}',
393 'fromns' => '0',
394 'fromtitle' => 'ApiComparePagesTest F',
395 ]
396 ],
397 ],
398 'Diff with all props' => [
399 [
400 'fromrev' => '{{REPL:revB1}}',
401 'torev' => '{{REPL:revB3}}',
402 'totitle' => 'ApiComparePagesTest B',
403 'prop' => 'diff|diffsize|rel|ids|title|user|comment|parsedcomment|size'
404 ],
405 [
406 'compare' => [
407 'fromid' => '{{REPL:pageB}}',
408 'fromrevid' => '{{REPL:revB1}}',
409 'fromns' => 0,
410 'fromtitle' => 'ApiComparePagesTest B',
411 'fromsize' => 3,
412 'fromuser' => '{{REPL:creator}}',
413 'fromuserid' => '{{REPL:creatorid}}',
414 'fromcomment' => 'Test for ApiComparePagesTest: B 1',
415 'fromparsedcomment' => 'Test for ApiComparePagesTest: B 1',
416 'toid' => '{{REPL:pageB}}',
417 'torevid' => '{{REPL:revB3}}',
418 'tons' => 0,
419 'totitle' => 'ApiComparePagesTest B',
420 'tosize' => 3,
421 'touserhidden' => true,
422 'tocommenthidden' => true,
423 'tosuppressed' => true,
424 'next' => '{{REPL:revB4}}',
425 'diffsize' => 391,
426 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
427 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
428 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div>B <del class="diffchange diffchange-inline">1</del></div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div>B <ins class="diffchange diffchange-inline">3</ins></div></td></tr>' . "\n",
429 ]
430 ],
431 ],
432 'Diff with all props as sysop' => [
433 [
434 'fromrev' => '{{REPL:revB2}}',
435 'torev' => '{{REPL:revB3}}',
436 'totitle' => 'ApiComparePagesTest B',
437 'prop' => 'diff|diffsize|rel|ids|title|user|comment|parsedcomment|size'
438 ],
439 [
440 'compare' => [
441 'fromid' => '{{REPL:pageB}}',
442 'fromrevid' => '{{REPL:revB2}}',
443 'fromns' => 0,
444 'fromtitle' => 'ApiComparePagesTest B',
445 'fromsize' => 3,
446 'fromtexthidden' => true,
447 'fromuserhidden' => true,
448 'fromuser' => '{{REPL:creator}}',
449 'fromuserid' => '{{REPL:creatorid}}',
450 'fromcommenthidden' => true,
451 'fromcomment' => 'Test for ApiComparePagesTest: B 2',
452 'fromparsedcomment' => 'Test for ApiComparePagesTest: B 2',
453 'toid' => '{{REPL:pageB}}',
454 'torevid' => '{{REPL:revB3}}',
455 'tons' => 0,
456 'totitle' => 'ApiComparePagesTest B',
457 'tosize' => 3,
458 'touserhidden' => true,
459 'tocommenthidden' => true,
460 'tosuppressed' => true,
461 'prev' => '{{REPL:revB1}}',
462 'next' => '{{REPL:revB4}}',
463 'diffsize' => 391,
464 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n"
465 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n"
466 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div>B <del class="diffchange diffchange-inline">2</del></div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div>B <ins class="diffchange diffchange-inline">3</ins></div></td></tr>' . "\n",
467 ]
468 ],
469 false, true
470 ],
471 'Relative diff, cur' => [
472 [
473 'fromrev' => '{{REPL:revA2}}',
474 'torelative' => 'cur',
475 'prop' => 'ids',
476 ],
477 [
478 'compare' => [
479 'fromid' => '{{REPL:pageA}}',
480 'fromrevid' => '{{REPL:revA2}}',
481 'toid' => '{{REPL:pageA}}',
482 'torevid' => '{{REPL:revA4}}',
483 ]
484 ],
485 ],
486 'Relative diff, next' => [
487 [
488 'fromrev' => '{{REPL:revE2}}',
489 'torelative' => 'next',
490 'prop' => 'ids|rel',
491 ],
492 [
493 'compare' => [
494 'fromid' => '{{REPL:pageE}}',
495 'fromrevid' => '{{REPL:revE2}}',
496 'toid' => '{{REPL:pageE}}',
497 'torevid' => '{{REPL:revE3}}',
498 'prev' => '{{REPL:revE1}}',
499 'next' => '{{REPL:revE4}}',
500 ]
501 ],
502 ],
503 'Relative diff, prev' => [
504 [
505 'fromrev' => '{{REPL:revE3}}',
506 'torelative' => 'prev',
507 'prop' => 'ids|rel',
508 ],
509 [
510 'compare' => [
511 'fromid' => '{{REPL:pageE}}',
512 'fromrevid' => '{{REPL:revE2}}',
513 'toid' => '{{REPL:pageE}}',
514 'torevid' => '{{REPL:revE3}}',
515 'prev' => '{{REPL:revE1}}',
516 'next' => '{{REPL:revE4}}',
517 ]
518 ],
519 ],
520
521 'Error, missing title' => [
522 [
523 'fromtitle' => 'ApiComparePagesTest X',
524 'totitle' => 'ApiComparePagesTest B',
525 ],
526 [],
527 'missingtitle',
528 ],
529 'Error, invalid title' => [
530 [
531 'fromtitle' => '<bad>',
532 'totitle' => 'ApiComparePagesTest B',
533 ],
534 [],
535 'invalidtitle',
536 ],
537 'Error, missing page ID' => [
538 [
539 'fromid' => 8817900,
540 'totitle' => 'ApiComparePagesTest B',
541 ],
542 [],
543 'nosuchpageid',
544 ],
545 'Error, page with missing revision' => [
546 [
547 'fromtitle' => 'ApiComparePagesTest D',
548 'totitle' => 'ApiComparePagesTest B',
549 ],
550 [],
551 'nosuchrevid',
552 ],
553 'Error, page with no revision' => [
554 [
555 'fromtitle' => 'ApiComparePagesTest E',
556 'totitle' => 'ApiComparePagesTest B',
557 ],
558 [],
559 'nosuchrevid',
560 ],
561 'Error, bad rev ID' => [
562 [
563 'fromrev' => 8817900,
564 'totitle' => 'ApiComparePagesTest B',
565 ],
566 [],
567 'nosuchrevid',
568 ],
569 'Error, deleted revision ID, non-sysop' => [
570 [
571 'fromrev' => '{{REPL:revA2}}',
572 'torev' => '{{REPL:revC2}}',
573 ],
574 [],
575 'nosuchrevid',
576 ],
577 'Error, revision-deleted content' => [
578 [
579 'fromrev' => '{{REPL:revA2}}',
580 'torev' => '{{REPL:revB2}}',
581 ],
582 [],
583 'missingcontent',
584 ],
585 'Error, text with no title and PST' => [
586 [
587 'fromtext' => 'From text',
588 'totext' => 'To text {{subst:PAGENAME}}',
589 'topst' => true,
590 ],
591 [],
592 'compare-no-title',
593 ],
594 'Error, test with invalid from section ID' => [
595 [
596 'fromtitle' => 'ApiComparePagesTest F',
597 'fromsection' => 5,
598 'totext' => "== Section 1 ==\nTo text\n\n== Section 2 ==\nTo text?",
599 'tosection' => 2,
600 ],
601 [],
602 'nosuchfromsection',
603 ],
604 'Error, test with invalid to section ID' => [
605 [
606 'fromtitle' => 'ApiComparePagesTest F',
607 'fromsection' => 1,
608 'totext' => "== Section 1 ==\nTo text\n\n== Section 2 ==\nTo text?",
609 'tosection' => 5,
610 ],
611 [],
612 'nosuchtosection',
613 ],
614 'Error, Relative diff, no from revision' => [
615 [
616 'fromtext' => 'Foo',
617 'torelative' => 'cur',
618 'prop' => 'ids',
619 ],
620 [],
621 'compare-relative-to-nothing'
622 ],
623 'Error, Relative diff, cur with no current revision' => [
624 [
625 'fromrev' => '{{REPL:revE2}}',
626 'torelative' => 'cur',
627 'prop' => 'ids',
628 ],
629 [],
630 'nosuchrevid'
631 ],
632 'Error, Relative diff, next revdeleted' => [
633 [
634 'fromrev' => '{{REPL:revB1}}',
635 'torelative' => 'next',
636 'prop' => 'ids',
637 ],
638 [],
639 'missingcontent'
640 ],
641 'Error, Relative diff, prev revdeleted' => [
642 [
643 'fromrev' => '{{REPL:revB3}}',
644 'torelative' => 'prev',
645 'prop' => 'ids',
646 ],
647 [],
648 'missingcontent'
649 ],
650 ];
651 // phpcs:enable
652 }
653 }