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