1<?php 2 3use MediaWiki\Revision\RevisionRecord; 4 5/** 6 * @group API 7 * @group Database 8 * @group medium 9 * @covers ApiComparePages 10 */ 11class ApiComparePagesTest extends ApiTestCase { 12 13 protected static $repl = []; 14 15 protected function addPage( $page, $text, $model = CONTENT_MODEL_WIKITEXT ) { 16 $title = Title::newFromText( 'ApiComparePagesTest ' . $page ); 17 $content = ContentHandler::makeContent( $text, $title, $model ); 18 19 $page = WikiPage::factory( $title ); 20 $user = static::getTestSysop()->getUser(); 21 $status = $page->doEditContent( 22 $content, 'Test for ApiComparePagesTest: ' . $text, 0, false, $user 23 ); 24 if ( !$status->isOK() ) { 25 $this->fail( "Failed to create $title: " . $status->getWikiText( false, false, 'en' ) ); 26 } 27 return $status->value['revision-record']->getId(); 28 } 29 30 public function addDBDataOnce() { 31 $user = static::getTestSysop()->getUser(); 32 self::$repl['creator'] = $user->getName(); 33 self::$repl['creatorid'] = $user->getId(); 34 35 self::$repl['revA1'] = $this->addPage( 'A', 'A 1' ); 36 self::$repl['revA2'] = $this->addPage( 'A', 'A 2' ); 37 self::$repl['revA3'] = $this->addPage( 'A', 'A 3' ); 38 self::$repl['revA4'] = $this->addPage( 'A', 'A 4' ); 39 self::$repl['pageA'] = Title::newFromText( 'ApiComparePagesTest A' )->getArticleID(); 40 41 self::$repl['revB1'] = $this->addPage( 'B', 'B 1' ); 42 self::$repl['revB2'] = $this->addPage( 'B', 'B 2' ); 43 self::$repl['revB3'] = $this->addPage( 'B', 'B 3' ); 44 self::$repl['revB4'] = $this->addPage( 'B', 'B 4' ); 45 self::$repl['pageB'] = Title::newFromText( 'ApiComparePagesTest B' )->getArticleID(); 46 foreach ( [ 47 self::$repl['revB1'] => '20010101011101', 48 self::$repl['revB2'] => '20020202022202', 49 self::$repl['revB3'] => '20030303033303', 50 self::$repl['revB4'] => '20040404044404', 51 ] as $id => $ts ) { 52 $this->db->update( 53 'revision', 54 [ 'rev_timestamp' => $this->db->timestamp( $ts ) ], 55 [ 'rev_id' => $id ], 56 __METHOD__ 57 ); 58 } 59 60 self::$repl['revC1'] = $this->addPage( 'C', 'C 1' ); 61 self::$repl['revC2'] = $this->addPage( 'C', 'C 2' ); 62 self::$repl['revC3'] = $this->addPage( 'C', 'C 3' ); 63 self::$repl['pageC'] = Title::newFromText( 'ApiComparePagesTest C' )->getArticleID(); 64 65 $id = $this->addPage( 'D', 'D 1' ); 66 self::$repl['pageD'] = Title::newFromText( 'ApiComparePagesTest D' )->getArticleID(); 67 wfGetDB( DB_MASTER )->delete( 'revision', [ 'rev_id' => $id ] ); 68 69 self::$repl['revE1'] = $this->addPage( 'E', 'E 1' ); 70 self::$repl['revE2'] = $this->addPage( 'E', 'E 2' ); 71 self::$repl['revE3'] = $this->addPage( 'E', 'E 3' ); 72 self::$repl['revE4'] = $this->addPage( 'E', 'E 4' ); 73 self::$repl['pageE'] = Title::newFromText( 'ApiComparePagesTest E' )->getArticleID(); 74 wfGetDB( DB_MASTER )->update( 75 'page', [ 'page_latest' => 0 ], [ 'page_id' => self::$repl['pageE'] ] 76 ); 77 78 self::$repl['revF1'] = $this->addPage( 'F', "== Section 1 ==\nF 1.1\n\n== Section 2 ==\nF 1.2" ); 79 self::$repl['pageF'] = Title::newFromText( 'ApiComparePagesTest F' )->getArticleID(); 80 81 self::$repl['revG1'] = $this->addPage( 'G', "== Section 1 ==\nG 1.1", CONTENT_MODEL_TEXT ); 82 self::$repl['pageG'] = Title::newFromText( 'ApiComparePagesTest G' )->getArticleID(); 83 84 WikiPage::factory( Title::newFromText( 'ApiComparePagesTest C' ) ) 85 ->doDeleteArticleReal( 'Test for ApiComparePagesTest', $user ); 86 87 RevisionDeleter::createList( 88 'revision', 89 RequestContext::getMain(), 90 Title::newFromText( 'ApiComparePagesTest B' ), 91 [ self::$repl['revB2'] ] 92 )->setVisibility( [ 93 'value' => [ 94 RevisionRecord::DELETED_TEXT => 1, 95 RevisionRecord::DELETED_USER => 1, 96 RevisionRecord::DELETED_COMMENT => 1, 97 ], 98 'comment' => 'Test for ApiComparePages', 99 ] ); 100 101 RevisionDeleter::createList( 102 'revision', 103 RequestContext::getMain(), 104 Title::newFromText( 'ApiComparePagesTest B' ), 105 [ self::$repl['revB3'] ] 106 )->setVisibility( [ 107 'value' => [ 108 RevisionRecord::DELETED_USER => 1, 109 RevisionRecord::DELETED_COMMENT => 1, 110 RevisionRecord::DELETED_RESTRICTED => 1, 111 ], 112 'comment' => 'Test for ApiComparePages', 113 ] ); 114 115 Title::clearCaches(); // Otherwise it has the wrong latest revision for some reason 116 } 117 118 protected function doReplacements( &$value ) { 119 if ( is_string( $value ) ) { 120 if ( preg_match( '/^{{REPL:(.+?)}}$/', $value, $m ) ) { 121 $value = self::$repl[$m[1]]; 122 } else { 123 $value = preg_replace_callback( '/{{REPL:(.+?)}}/', function ( $m ) { 124 return self::$repl[$m[1]] ?? $m[0]; 125 }, $value ); 126 } 127 } elseif ( is_array( $value ) || is_object( $value ) ) { 128 foreach ( $value as &$v ) { 129 $this->doReplacements( $v ); 130 } 131 unset( $v ); 132 } 133 } 134 135 /** 136 * @dataProvider provideDiff 137 */ 138 public function testDiff( $params, $expect, $exceptionCode = false, $sysop = false ) { 139 $this->setMwGlobals( [ 'wgDiffEngine' => 'php' ] ); 140 141 $this->doReplacements( $params ); 142 143 $params += [ 144 'action' => 'compare', 145 'errorformat' => 'none', 146 ]; 147 148 $user = $sysop 149 ? static::getTestSysop()->getUser() 150 : static::getTestUser()->getUser(); 151 if ( $exceptionCode ) { 152 try { 153 $this->doApiRequest( $params, null, false, $user ); 154 $this->fail( 'Expected exception not thrown' ); 155 } catch ( ApiUsageException $ex ) { 156 $this->assertTrue( $this->apiExceptionHasCode( $ex, $exceptionCode ), 157 "Exception with code $exceptionCode" ); 158 } 159 } else { 160 $apiResult = $this->doApiRequest( $params, null, false, $user ); 161 $apiResult = $apiResult[0]; 162 $this->doReplacements( $expect ); 163 $this->assertEquals( $expect, $apiResult ); 164 } 165 } 166 167 private static function makeDeprecationWarnings( ...$params ) { 168 $warn = []; 169 foreach ( $params as $p ) { 170 $warn[] = [ 171 'code' => 'deprecation', 172 'data' => [ 'feature' => "action=compare&{$p}" ], 173 'module' => 'compare', 174 ]; 175 if ( count( $warn ) === 1 ) { 176 $warn[] = [ 177 'code' => 'deprecation-help', 178 'module' => 'main', 179 ]; 180 } 181 } 182 183 return $warn; 184 } 185 186 public static function provideDiff() { 187 // phpcs:disable Generic.Files.LineLength.TooLong 188 return [ 189 'Basic diff, titles' => [ 190 [ 191 'fromtitle' => 'ApiComparePagesTest A', 192 'totitle' => 'ApiComparePagesTest B', 193 ], 194 [ 195 'compare' => [ 196 'fromid' => '{{REPL:pageA}}', 197 'fromrevid' => '{{REPL:revA4}}', 198 'fromns' => 0, 199 'fromtitle' => 'ApiComparePagesTest A', 200 'toid' => '{{REPL:pageB}}', 201 'torevid' => '{{REPL:revB4}}', 202 'tons' => 0, 203 'totitle' => 'ApiComparePagesTest B', 204 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 205 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 206 . '<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", 207 ] 208 ], 209 ], 210 'Basic diff, page IDs' => [ 211 [ 212 'fromid' => '{{REPL:pageA}}', 213 'toid' => '{{REPL:pageB}}', 214 ], 215 [ 216 'compare' => [ 217 'fromid' => '{{REPL:pageA}}', 218 'fromrevid' => '{{REPL:revA4}}', 219 'fromns' => 0, 220 'fromtitle' => 'ApiComparePagesTest A', 221 'toid' => '{{REPL:pageB}}', 222 'torevid' => '{{REPL:revB4}}', 223 'tons' => 0, 224 'totitle' => 'ApiComparePagesTest B', 225 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 226 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 227 . '<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", 228 ] 229 ], 230 ], 231 'Basic diff, revision IDs' => [ 232 [ 233 'fromrev' => '{{REPL:revA2}}', 234 'torev' => '{{REPL:revA3}}', 235 ], 236 [ 237 'compare' => [ 238 'fromid' => '{{REPL:pageA}}', 239 'fromrevid' => '{{REPL:revA2}}', 240 'fromns' => 0, 241 'fromtitle' => 'ApiComparePagesTest A', 242 'toid' => '{{REPL:pageA}}', 243 'torevid' => '{{REPL:revA3}}', 244 'tons' => 0, 245 'totitle' => 'ApiComparePagesTest A', 246 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 247 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 248 . '<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", 249 ] 250 ], 251 ], 252 'Basic diff, deleted revision ID as sysop' => [ 253 [ 254 'fromrev' => '{{REPL:revA2}}', 255 'torev' => '{{REPL:revC2}}', 256 ], 257 [ 258 'compare' => [ 259 'fromid' => '{{REPL:pageA}}', 260 'fromrevid' => '{{REPL:revA2}}', 261 'fromns' => 0, 262 'fromtitle' => 'ApiComparePagesTest A', 263 'toid' => 0, 264 'torevid' => '{{REPL:revC2}}', 265 'tons' => 0, 266 'totitle' => 'ApiComparePagesTest C', 267 'toarchive' => true, 268 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 269 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 270 . '<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", 271 ] 272 ], 273 false, true 274 ], 275 'Basic diff, revdel as sysop' => [ 276 [ 277 'fromrev' => '{{REPL:revA2}}', 278 'torev' => '{{REPL:revB2}}', 279 ], 280 [ 281 'compare' => [ 282 'fromid' => '{{REPL:pageA}}', 283 'fromrevid' => '{{REPL:revA2}}', 284 'fromns' => 0, 285 'fromtitle' => 'ApiComparePagesTest A', 286 'toid' => '{{REPL:pageB}}', 287 'torevid' => '{{REPL:revB2}}', 288 'tons' => 0, 289 'totitle' => 'ApiComparePagesTest B', 290 'totexthidden' => true, 291 'touserhidden' => true, 292 'tocommenthidden' => true, 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">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", 296 ] 297 ], 298 false, true 299 ], 300 'Basic diff, text' => [ 301 [ 302 'fromslots' => 'main', 303 'fromtext-main' => 'From text', 304 'fromcontentmodel-main' => 'wikitext', 305 'toslots' => 'main', 306 'totext-main' => 'To text {{subst:PAGENAME}}', 307 'tocontentmodel-main' => '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 <ins class="diffchange diffchange-inline">{{subst:PAGENAME}}</ins></div></td></tr>' . "\n", 314 ] 315 ], 316 ], 317 'Basic diff, text 2' => [ 318 [ 319 'fromslots' => 'main', 320 'fromtext-main' => 'From text', 321 'toslots' => 'main', 322 'totext-main' => 'To text {{subst:PAGENAME}}', 323 'tocontentmodel-main' => 'wikitext', 324 ], 325 [ 326 'compare' => [ 327 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 328 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 329 . '<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", 330 ] 331 ], 332 ], 333 'Basic diff, guessed model' => [ 334 [ 335 'fromslots' => 'main', 336 'fromtext-main' => 'From text', 337 'toslots' => 'main', 338 'totext-main' => 'To text', 339 ], 340 [ 341 'warnings' => [ [ 'code' => 'compare-nocontentmodel', 'module' => 'compare' ] ], 342 'compare' => [ 343 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 344 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 345 . '<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", 346 ] 347 ], 348 ], 349 'Basic diff, text with title and PST' => [ 350 [ 351 'fromslots' => 'main', 352 'fromtext-main' => 'From text', 353 'totitle' => 'Test', 354 'toslots' => 'main', 355 'totext-main' => 'To text {{subst:PAGENAME}}', 356 'topst' => true, 357 ], 358 [ 359 'compare' => [ 360 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 361 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 362 . '<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", 363 ] 364 ], 365 ], 366 'Basic diff, text with page ID and PST' => [ 367 [ 368 'fromslots' => 'main', 369 'fromtext-main' => 'From text', 370 'toid' => '{{REPL:pageB}}', 371 'toslots' => 'main', 372 'totext-main' => 'To text {{subst:PAGENAME}}', 373 'topst' => true, 374 ], 375 [ 376 'compare' => [ 377 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 378 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 379 . '<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", 380 ] 381 ], 382 ], 383 'Basic diff, text with revision and PST' => [ 384 [ 385 'fromslots' => 'main', 386 'fromtext-main' => 'From text', 387 'torev' => '{{REPL:revB2}}', 388 'toslots' => 'main', 389 'totext-main' => 'To text {{subst:PAGENAME}}', 390 'topst' => true, 391 ], 392 [ 393 'compare' => [ 394 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 395 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 396 . '<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", 397 ] 398 ], 399 ], 400 'Basic diff, text with deleted revision and PST' => [ 401 [ 402 'fromslots' => 'main', 403 'fromtext-main' => 'From text', 404 'torev' => '{{REPL:revC2}}', 405 'toslots' => 'main', 406 'totext-main' => 'To text {{subst:PAGENAME}}', 407 'topst' => true, 408 ], 409 [ 410 'compare' => [ 411 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 412 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 413 . '<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", 414 ] 415 ], 416 false, true 417 ], 418 'Basic diff, test with sections' => [ 419 [ 420 'fromtitle' => 'ApiComparePagesTest F', 421 'fromslots' => 'main', 422 'fromtext-main' => "== Section 2 ==\nFrom text?", 423 'fromsection-main' => 2, 424 'totitle' => 'ApiComparePagesTest F', 425 'toslots' => 'main', 426 'totext-main' => "== Section 1 ==\nTo text?", 427 'tosection-main' => 1, 428 ], 429 [ 430 'compare' => [ 431 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 432 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 433 . '<tr><td class=\'diff-marker\'> </td><td class=\'diff-context\'><div>== Section 1 ==</div></td><td class=\'diff-marker\'> </td><td class=\'diff-context\'><div>== Section 1 ==</div></td></tr>' . "\n" 434 . '<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" 435 . '<tr><td class=\'diff-marker\'> </td><td class=\'diff-context\'></td><td class=\'diff-marker\'> </td><td class=\'diff-context\'></td></tr>' . "\n" 436 . '<tr><td class=\'diff-marker\'> </td><td class=\'diff-context\'><div>== Section 2 ==</div></td><td class=\'diff-marker\'> </td><td class=\'diff-context\'><div>== Section 2 ==</div></td></tr>' . "\n" 437 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">From text?</del></div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">F 1.2</ins></div></td></tr>' . "\n", 438 ] 439 ], 440 ], 441 'Diff with all props' => [ 442 [ 443 'fromrev' => '{{REPL:revB1}}', 444 'torev' => '{{REPL:revB3}}', 445 'totitle' => 'ApiComparePagesTest B', 446 'prop' => 'diff|diffsize|rel|ids|title|user|comment|parsedcomment|size|timestamp' 447 ], 448 [ 449 'compare' => [ 450 'fromid' => '{{REPL:pageB}}', 451 'fromrevid' => '{{REPL:revB1}}', 452 'fromns' => 0, 453 'fromtitle' => 'ApiComparePagesTest B', 454 'fromsize' => 3, 455 'fromuser' => '{{REPL:creator}}', 456 'fromuserid' => '{{REPL:creatorid}}', 457 'fromcomment' => 'Test for ApiComparePagesTest: B 1', 458 'fromparsedcomment' => 'Test for ApiComparePagesTest: B 1', 459 'fromtimestamp' => '2001-01-01T01:11:01Z', 460 'toid' => '{{REPL:pageB}}', 461 'torevid' => '{{REPL:revB3}}', 462 'tons' => 0, 463 'totitle' => 'ApiComparePagesTest B', 464 'tosize' => 3, 465 'touserhidden' => true, 466 'tocommenthidden' => true, 467 'tosuppressed' => true, 468 'totimestamp' => '2003-03-03T03:33:03Z', 469 'next' => '{{REPL:revB4}}', 470 'diffsize' => 391, 471 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 472 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 473 . '<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", 474 ] 475 ], 476 ], 477 'Diff with all props as sysop' => [ 478 [ 479 'fromrev' => '{{REPL:revB2}}', 480 'torev' => '{{REPL:revB3}}', 481 'totitle' => 'ApiComparePagesTest B', 482 'prop' => 'diff|diffsize|rel|ids|title|user|comment|parsedcomment|size|timestamp' 483 ], 484 [ 485 'compare' => [ 486 'fromid' => '{{REPL:pageB}}', 487 'fromrevid' => '{{REPL:revB2}}', 488 'fromns' => 0, 489 'fromtitle' => 'ApiComparePagesTest B', 490 'fromsize' => 3, 491 'fromtexthidden' => true, 492 'fromuserhidden' => true, 493 'fromuser' => '{{REPL:creator}}', 494 'fromuserid' => '{{REPL:creatorid}}', 495 'fromcommenthidden' => true, 496 'fromcomment' => 'Test for ApiComparePagesTest: B 2', 497 'fromparsedcomment' => 'Test for ApiComparePagesTest: B 2', 498 'fromtimestamp' => '2002-02-02T02:22:02Z', 499 'toid' => '{{REPL:pageB}}', 500 'torevid' => '{{REPL:revB3}}', 501 'tons' => 0, 502 'totitle' => 'ApiComparePagesTest B', 503 'tosize' => 3, 504 'touserhidden' => true, 505 'tocommenthidden' => true, 506 'tosuppressed' => true, 507 'totimestamp' => '2003-03-03T03:33:03Z', 508 'prev' => '{{REPL:revB1}}', 509 'next' => '{{REPL:revB4}}', 510 'diffsize' => 391, 511 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 512 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 513 . '<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", 514 ] 515 ], 516 false, true 517 ], 518 'Text diff with all props' => [ 519 [ 520 'fromrev' => '{{REPL:revB1}}', 521 'toslots' => 'main', 522 'totext-main' => 'To text {{subst:PAGENAME}}', 523 'tocontentmodel-main' => 'wikitext', 524 'prop' => 'diff|diffsize|rel|ids|title|user|comment|parsedcomment|size|timestamp' 525 ], 526 [ 527 'compare' => [ 528 'fromid' => '{{REPL:pageB}}', 529 'fromrevid' => '{{REPL:revB1}}', 530 'fromns' => 0, 531 'fromtitle' => 'ApiComparePagesTest B', 532 'fromsize' => 3, 533 'fromuser' => '{{REPL:creator}}', 534 'fromuserid' => '{{REPL:creatorid}}', 535 'fromcomment' => 'Test for ApiComparePagesTest: B 1', 536 'fromparsedcomment' => 'Test for ApiComparePagesTest: B 1', 537 'fromtimestamp' => '2001-01-01T01:11:01Z', 538 'diffsize' => 414, 539 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 540 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 541 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div><del class="diffchange diffchange-inline">B 1</del></div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">To text {{subst:PAGENAME}}</ins></div></td></tr>' . "\n", 542 ] 543 ], 544 ], 545 'Relative diff, cur' => [ 546 [ 547 'fromrev' => '{{REPL:revA2}}', 548 'torelative' => 'cur', 549 'prop' => 'ids', 550 ], 551 [ 552 'compare' => [ 553 'fromid' => '{{REPL:pageA}}', 554 'fromrevid' => '{{REPL:revA2}}', 555 'toid' => '{{REPL:pageA}}', 556 'torevid' => '{{REPL:revA4}}', 557 ] 558 ], 559 ], 560 'Relative diff, next' => [ 561 [ 562 'fromrev' => '{{REPL:revE2}}', 563 'torelative' => 'next', 564 'prop' => 'ids|rel', 565 ], 566 [ 567 'compare' => [ 568 'fromid' => '{{REPL:pageE}}', 569 'fromrevid' => '{{REPL:revE2}}', 570 'toid' => '{{REPL:pageE}}', 571 'torevid' => '{{REPL:revE3}}', 572 'prev' => '{{REPL:revE1}}', 573 'next' => '{{REPL:revE4}}', 574 ] 575 ], 576 ], 577 'Relative diff, prev' => [ 578 [ 579 'fromrev' => '{{REPL:revE3}}', 580 'torelative' => 'prev', 581 'prop' => 'ids|rel', 582 ], 583 [ 584 'compare' => [ 585 'fromid' => '{{REPL:pageE}}', 586 'fromrevid' => '{{REPL:revE2}}', 587 'toid' => '{{REPL:pageE}}', 588 'torevid' => '{{REPL:revE3}}', 589 'prev' => '{{REPL:revE1}}', 590 'next' => '{{REPL:revE4}}', 591 ] 592 ], 593 ], 594 'Relative diff, no prev' => [ 595 [ 596 'fromrev' => '{{REPL:revA1}}', 597 'torelative' => 'prev', 598 'prop' => 'ids|rel|diff|title|user|comment', 599 ], 600 [ 601 'warnings' => [ 602 [ 603 'code' => 'compare-no-prev', 604 'module' => 'compare', 605 ], 606 ], 607 'compare' => [ 608 'toid' => '{{REPL:pageA}}', 609 'torevid' => '{{REPL:revA1}}', 610 'tons' => 0, 611 'totitle' => 'ApiComparePagesTest A', 612 'touser' => '{{REPL:creator}}', 613 'touserid' => '{{REPL:creatorid}}', 614 'tocomment' => 'Test for ApiComparePagesTest: A 1', 615 'toparsedcomment' => 'Test for ApiComparePagesTest: A 1', 616 'next' => '{{REPL:revA2}}', 617 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 618 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 619 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div> </div></td><td class=\'diff-marker\'>+</td><td class=\'diff-addedline\'><div><ins class="diffchange diffchange-inline">A 1</ins></div></td></tr>' . "\n", 620 ], 621 ], 622 ], 623 'Relative diff, no next' => [ 624 [ 625 'fromrev' => '{{REPL:revA4}}', 626 'torelative' => 'next', 627 'prop' => 'ids|rel|diff|title|user|comment', 628 ], 629 [ 630 'warnings' => [ 631 [ 632 'code' => 'compare-no-next', 633 'module' => 'compare', 634 ], 635 ], 636 'compare' => [ 637 'fromid' => '{{REPL:pageA}}', 638 'fromrevid' => '{{REPL:revA4}}', 639 'fromns' => 0, 640 'fromtitle' => 'ApiComparePagesTest A', 641 'fromuser' => '{{REPL:creator}}', 642 'fromuserid' => '{{REPL:creatorid}}', 643 'fromcomment' => 'Test for ApiComparePagesTest: A 4', 644 'fromparsedcomment' => 'Test for ApiComparePagesTest: A 4', 645 'prev' => '{{REPL:revA3}}', 646 'body' => '', 647 ], 648 ], 649 ], 650 'Diff for specific slots' => [ 651 // @todo Use a page with multiple slots here 652 [ 653 'fromrev' => '{{REPL:revA1}}', 654 'torev' => '{{REPL:revA3}}', 655 'prop' => 'diff', 656 'slots' => 'main', 657 ], 658 [ 659 'compare' => [ 660 'bodies' => [ 661 'main' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 662 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 663 . '<tr><td class=\'diff-marker\'>−</td><td class=\'diff-deletedline\'><div>A <del class="diffchange diffchange-inline">1</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", 664 ], 665 ], 666 ], 667 ], 668 // @todo Add a test for diffing with a deleted slot. Deleting 'main' doesn't work. 669 670 'Basic diff, deprecated text' => [ 671 [ 672 'fromtext' => 'From text', 673 'fromcontentmodel' => 'wikitext', 674 'totext' => 'To text {{subst:PAGENAME}}', 675 'tocontentmodel' => 'wikitext', 676 ], 677 [ 678 'warnings' => self::makeDeprecationWarnings( 'fromtext', 'fromcontentmodel', 'totext', 'tocontentmodel' ), 679 'compare' => [ 680 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 681 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 682 . '<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", 683 ] 684 ], 685 ], 686 'Basic diff, deprecated text 2' => [ 687 [ 688 'fromtext' => 'From text', 689 'totext' => 'To text {{subst:PAGENAME}}', 690 'tocontentmodel' => 'wikitext', 691 ], 692 [ 693 'warnings' => self::makeDeprecationWarnings( 'fromtext', 'totext', 'tocontentmodel' ), 694 'compare' => [ 695 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 696 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 697 . '<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", 698 ] 699 ], 700 ], 701 'Basic diff, deprecated text, guessed model' => [ 702 [ 703 'fromtext' => 'From text', 704 'totext' => 'To text', 705 ], 706 [ 707 'warnings' => array_merge( self::makeDeprecationWarnings( 'fromtext', 'totext' ), [ 708 [ 'code' => 'compare-nocontentmodel', 'module' => 'compare' ], 709 ] ), 710 'compare' => [ 711 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 712 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 713 . '<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", 714 ] 715 ], 716 ], 717 'Basic diff, deprecated text with title and PST' => [ 718 [ 719 'fromtext' => 'From text', 720 'totitle' => 'Test', 721 'totext' => 'To text {{subst:PAGENAME}}', 722 'topst' => true, 723 ], 724 [ 725 'warnings' => self::makeDeprecationWarnings( 'fromtext', 'totext' ), 726 'compare' => [ 727 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 728 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 729 . '<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", 730 ] 731 ], 732 ], 733 'Basic diff, deprecated text with page ID and PST' => [ 734 [ 735 'fromtext' => 'From text', 736 'toid' => '{{REPL:pageB}}', 737 'totext' => 'To text {{subst:PAGENAME}}', 738 'topst' => true, 739 ], 740 [ 741 'warnings' => self::makeDeprecationWarnings( 'fromtext', 'totext' ), 742 'compare' => [ 743 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 744 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 745 . '<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", 746 ] 747 ], 748 ], 749 'Basic diff, deprecated text with revision and PST' => [ 750 [ 751 'fromtext' => 'From text', 752 'torev' => '{{REPL:revB2}}', 753 'totext' => 'To text {{subst:PAGENAME}}', 754 'topst' => true, 755 ], 756 [ 757 'warnings' => self::makeDeprecationWarnings( 'fromtext', 'totext' ), 758 'compare' => [ 759 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 760 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 761 . '<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", 762 ] 763 ], 764 ], 765 'Basic diff, deprecated text with deleted revision and PST' => [ 766 [ 767 'fromtext' => 'From text', 768 'torev' => '{{REPL:revC2}}', 769 'totext' => 'To text {{subst:PAGENAME}}', 770 'topst' => true, 771 ], 772 [ 773 'warnings' => self::makeDeprecationWarnings( 'fromtext', 'totext' ), 774 'compare' => [ 775 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 776 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 777 . '<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", 778 ] 779 ], 780 false, true 781 ], 782 'Basic diff, test with deprecated sections' => [ 783 [ 784 'fromtitle' => 'ApiComparePagesTest F', 785 'fromsection' => 1, 786 'totext' => "== Section 1 ==\nTo text\n\n== Section 2 ==\nTo text?", 787 'tosection' => 2, 788 ], 789 [ 790 'warnings' => self::makeDeprecationWarnings( 'fromsection', 'totext', 'tosection' ), 791 'compare' => [ 792 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 793 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 794 . '<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" 795 . '<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", 796 'fromid' => '{{REPL:pageF}}', 797 'fromrevid' => '{{REPL:revF1}}', 798 'fromns' => '0', 799 'fromtitle' => 'ApiComparePagesTest F', 800 ] 801 ], 802 ], 803 'Basic diff, test with deprecated sections and revdel, non-sysop' => [ 804 [ 805 'fromrev' => '{{REPL:revB2}}', 806 'fromsection' => 0, 807 'torev' => '{{REPL:revB4}}', 808 'tosection' => 0, 809 ], 810 [], 811 'missingcontent' 812 ], 813 'Basic diff, test with deprecated sections and revdel, sysop' => [ 814 [ 815 'fromrev' => '{{REPL:revB2}}', 816 'fromsection' => 0, 817 'torev' => '{{REPL:revB4}}', 818 'tosection' => 0, 819 ], 820 [ 821 'warnings' => self::makeDeprecationWarnings( 'fromsection', 'tosection' ), 822 'compare' => [ 823 'body' => '<tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>' . "\n" 824 . '<td colspan="2" class="diff-lineno">Line 1:</td></tr>' . "\n" 825 . '<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">4</ins></div></td></tr>' . "\n", 826 'fromid' => '{{REPL:pageB}}', 827 'fromrevid' => '{{REPL:revB2}}', 828 'fromns' => 0, 829 'fromtitle' => 'ApiComparePagesTest B', 830 'fromtexthidden' => true, 831 'fromuserhidden' => true, 832 'fromcommenthidden' => true, 833 'toid' => '{{REPL:pageB}}', 834 'torevid' => '{{REPL:revB4}}', 835 'tons' => 0, 836 'totitle' => 'ApiComparePagesTest B', 837 ] 838 ], 839 false, true, 840 ], 841 842 'Error, missing title' => [ 843 [ 844 'fromtitle' => 'ApiComparePagesTest X', 845 'totitle' => 'ApiComparePagesTest B', 846 ], 847 [], 848 'missingtitle', 849 ], 850 'Error, invalid title' => [ 851 [ 852 'fromtitle' => '<bad>', 853 'totitle' => 'ApiComparePagesTest B', 854 ], 855 [], 856 'invalidtitle', 857 ], 858 'Error, missing page ID' => [ 859 [ 860 'fromid' => 8817900, 861 'totitle' => 'ApiComparePagesTest B', 862 ], 863 [], 864 'nosuchpageid', 865 ], 866 'Error, page with missing revision' => [ 867 [ 868 'fromtitle' => 'ApiComparePagesTest D', 869 'totitle' => 'ApiComparePagesTest B', 870 ], 871 [], 872 'nosuchrevid', 873 ], 874 'Error, page with no revision' => [ 875 [ 876 'fromtitle' => 'ApiComparePagesTest E', 877 'totitle' => 'ApiComparePagesTest B', 878 ], 879 [], 880 'nosuchrevid', 881 ], 882 'Error, bad rev ID' => [ 883 [ 884 'fromrev' => 8817900, 885 'totitle' => 'ApiComparePagesTest B', 886 ], 887 [], 888 'nosuchrevid', 889 ], 890 'Error, deleted revision ID, non-sysop' => [ 891 [ 892 'fromrev' => '{{REPL:revA2}}', 893 'torev' => '{{REPL:revC2}}', 894 ], 895 [], 896 'nosuchrevid', 897 ], 898 'Error, deleted revision ID and torelative=prev' => [ 899 [ 900 'fromrev' => '{{REPL:revC2}}', 901 'torelative' => 'prev', 902 ], 903 [], 904 'compare-relative-to-deleted', true 905 ], 906 'Error, deleted revision ID and torelative=next' => [ 907 [ 908 'fromrev' => '{{REPL:revC2}}', 909 'torelative' => 'next', 910 ], 911 [], 912 'compare-relative-to-deleted', true 913 ], 914 'Deleted revision ID and torelative=cur' => [ 915 [ 916 'fromrev' => '{{REPL:revC2}}', 917 'torelative' => 'cur', 918 ], 919 [], 920 'nosuchrevid', true 921 ], 922 'Error, revision-deleted content' => [ 923 [ 924 'fromrev' => '{{REPL:revA2}}', 925 'torev' => '{{REPL:revB2}}', 926 ], 927 [], 928 'missingcontent', 929 ], 930 'Error, text with no title and PST' => [ 931 [ 932 'fromtext' => 'From text', 933 'totext' => 'To text {{subst:PAGENAME}}', 934 'topst' => true, 935 ], 936 [], 937 'compare-no-title', 938 ], 939 'Error, test with invalid from section ID' => [ 940 [ 941 'fromtitle' => 'ApiComparePagesTest F', 942 'fromsection' => 5, 943 'totext' => "== Section 1 ==\nTo text\n\n== Section 2 ==\nTo text?", 944 'tosection' => 2, 945 ], 946 [], 947 'nosuchfromsection', 948 ], 949 'Error, test with invalid to section ID' => [ 950 [ 951 'fromtitle' => 'ApiComparePagesTest F', 952 'fromsection' => 1, 953 'totext' => "== Section 1 ==\nTo text\n\n== Section 2 ==\nTo text?", 954 'tosection' => 5, 955 ], 956 [], 957 'nosuchtosection', 958 ], 959 'Error, Relative diff, no from revision' => [ 960 [ 961 'fromtext' => 'Foo', 962 'torelative' => 'cur', 963 'prop' => 'ids', 964 ], 965 [], 966 'compare-relative-to-nothing' 967 ], 968 'Error, Relative diff, cur with no current revision' => [ 969 [ 970 'fromrev' => '{{REPL:revE2}}', 971 'torelative' => 'cur', 972 'prop' => 'ids', 973 ], 974 [], 975 'nosuchrevid' 976 ], 977 'Error, Relative diff, next revdeleted' => [ 978 [ 979 'fromrev' => '{{REPL:revB1}}', 980 'torelative' => 'next', 981 'prop' => 'ids', 982 ], 983 [], 984 'missingcontent' 985 ], 986 'Error, Relative diff, prev revdeleted' => [ 987 [ 988 'fromrev' => '{{REPL:revB3}}', 989 'torelative' => 'prev', 990 'prop' => 'ids', 991 ], 992 [], 993 'missingcontent' 994 ], 995 'Error, section diff with no revision' => [ 996 [ 997 'fromtitle' => 'ApiComparePagesTest F', 998 'toslots' => 'main', 999 'totext-main' => "== Section 1 ==\nTo text?", 1000 'tosection-main' => 1, 1001 ], 1002 [], 1003 'compare-notorevision', 1004 ], 1005 'Error, section diff with revdeleted revision' => [ 1006 [ 1007 'fromtitle' => 'ApiComparePagesTest F', 1008 'torev' => '{{REPL:revB2}}', 1009 'toslots' => 'main', 1010 'totext-main' => "== Section 1 ==\nTo text?", 1011 'tosection-main' => 1, 1012 ], 1013 [], 1014 'missingcontent', 1015 ], 1016 'Error, section diff with a content model not supporting sections' => [ 1017 [ 1018 'fromtitle' => 'ApiComparePagesTest G', 1019 'torev' => '{{REPL:revG1}}', 1020 'toslots' => 'main', 1021 'totext-main' => "== Section 1 ==\nTo text?", 1022 'tosection-main' => 1, 1023 ], 1024 [], 1025 'sectionsnotsupported', 1026 ], 1027 'Error, section diff with bad content model' => [ 1028 [ 1029 'fromtitle' => 'ApiComparePagesTest F', 1030 'torev' => '{{REPL:revF1}}', 1031 'toslots' => 'main', 1032 'totext-main' => "== Section 1 ==\nTo text?", 1033 'tosection-main' => 1, 1034 'tocontentmodel-main' => CONTENT_MODEL_TEXT, 1035 ], 1036 [], 1037 'sectionreplacefailed', 1038 ], 1039 'Error, deleting the main slot' => [ 1040 [ 1041 'fromtitle' => 'ApiComparePagesTest A', 1042 'totitle' => 'ApiComparePagesTest A', 1043 'toslots' => 'main', 1044 ], 1045 [], 1046 'compare-maintextrequired', 1047 ], 1048 // @todo Add a test for using 'tosection-foo' without 'totext-foo' (can't do it with main) 1049 ]; 1050 // phpcs:enable 1051 } 1052} 1053