3 use Wikimedia\TestingAccessWrapper
;
6 * @group ContentHandler
8 class RevisionUnitTest
extends MediaWikiTestCase
{
10 public function provideConstructFromArray() {
11 yield
'with text' => [
13 'text' => 'hello world.',
14 'content_model' => CONTENT_MODEL_JAVASCRIPT
17 yield
'with content' => [
19 'content' => new JavaScriptContent( 'hellow world.' )
25 * @dataProvider provideConstructFromArray
27 public function testConstructFromArray( $rowArray ) {
28 $rev = new Revision( $rowArray );
29 $this->assertNotNull( $rev->getContent(), 'no content object available' );
30 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT
, $rev->getContent()->getModel() );
31 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT
, $rev->getContentModel() );
34 public function provideConstructFromArrayThrowsExceptions() {
35 yield
'content and text_id both not empty' => [
37 'content' => new WikitextContent( 'GOAT' ),
38 'text_id' => 'someid',
40 new MWException( "Text already stored in external store (id someid), " .
41 "can't serialize content object" )
43 yield
'with bad content object (class)' => [
44 [ 'content' => new stdClass() ],
45 new MWException( '`content` field must contain a Content object.' )
47 yield
'with bad content object (string)' => [
48 [ 'content' => 'ImAGoat' ],
49 new MWException( '`content` field must contain a Content object.' )
51 yield
'bad row format' => [
52 'imastring, not a row',
53 new MWException( 'Revision constructor passed invalid row format.' )
58 * @dataProvider provideConstructFromArrayThrowsExceptions
60 public function testConstructFromArrayThrowsExceptions( $rowArray, Exception
$expectedException ) {
61 $this->setExpectedException(
62 get_class( $expectedException ),
63 $expectedException->getMessage(),
64 $expectedException->getCode()
66 new Revision( $rowArray );
69 public function provideGetRevisionText() {
70 yield
'Generic test' => [
71 'This is a goat of revision text.',
74 'old_text' => 'This is a goat of revision text.',
79 public function provideGetId() {
91 * @dataProvider provideGetId
92 * @covers Revision::getId
94 public function testGetId( $rowArray, $expectedId ) {
95 $rev = new Revision( $rowArray );
96 $this->assertEquals( $expectedId, $rev->getId() );
99 public function provideSetId() {
100 yield
[ '123', 123 ];
105 * @dataProvider provideSetId
106 * @covers Revision::setId
108 public function testSetId( $input, $expected ) {
109 $rev = new Revision( [] );
110 $rev->setId( $input );
111 $this->assertSame( $expected, $rev->getId() );
114 public function provideSetUserIdAndName() {
115 yield
[ '123', 123, 'GOaT' ];
116 yield
[ 456, 456, 'GOaT' ];
120 * @dataProvider provideSetUserIdAndName
121 * @covers Revision::setUserIdAndName
123 public function testSetUserIdAndName( $inputId, $expectedId, $name ) {
124 $rev = new Revision( [] );
125 $rev->setUserIdAndName( $inputId, $name );
126 $this->assertSame( $expectedId, $rev->getUser( Revision
::RAW
) );
127 $this->assertEquals( $name, $rev->getUserText( Revision
::RAW
) );
130 public function provideGetTextId() {
132 yield
[ [ 'text_id' => '123' ], 123 ];
133 yield
[ [ 'text_id' => 456 ], 456 ];
137 * @dataProvider provideGetTextId
138 * @covers Revision::getTextId()
140 public function testGetTextId( $rowArray, $expected ) {
141 $rev = new Revision( $rowArray );
142 $this->assertSame( $expected, $rev->getTextId() );
145 public function provideGetParentId() {
147 yield
[ [ 'parent_id' => '123' ], 123 ];
148 yield
[ [ 'parent_id' => 456 ], 456 ];
152 * @dataProvider provideGetParentId
153 * @covers Revision::getParentId()
155 public function testGetParentId( $rowArray, $expected ) {
156 $rev = new Revision( $rowArray );
157 $this->assertSame( $expected, $rev->getParentId() );
161 * @covers Revision::getRevisionText
162 * @dataProvider provideGetRevisionText
164 public function testGetRevisionText( $expected, $rowData, $prefix = 'old_', $wiki = false ) {
167 Revision
::getRevisionText( (object)$rowData, $prefix, $wiki ) );
170 public function provideGetRevisionTextWithZlibExtension() {
171 yield
'Generic gzip test' => [
172 'This is a small goat of revision text.',
174 'old_flags' => 'gzip',
175 'old_text' => gzdeflate( 'This is a small goat of revision text.' ),
181 * @covers Revision::getRevisionText
182 * @dataProvider provideGetRevisionTextWithZlibExtension
184 public function testGetRevisionWithZlibExtension( $expected, $rowData ) {
185 $this->checkPHPExtension( 'zlib' );
186 $this->testGetRevisionText( $expected, $rowData );
189 public function provideGetRevisionTextWithLegacyEncoding() {
190 yield
'Utf8Native' => [
191 "Wiki est l'\xc3\xa9cole superieur !",
194 'old_flags' => 'utf-8',
195 'old_text' => "Wiki est l'\xc3\xa9cole superieur !",
198 yield
'Utf8Legacy' => [
199 "Wiki est l'\xc3\xa9cole superieur !",
203 'old_text' => "Wiki est l'\xe9cole superieur !",
209 * @covers Revision::getRevisionText
210 * @dataProvider provideGetRevisionTextWithLegacyEncoding
212 public function testGetRevisionWithLegacyEncoding( $expected, $encoding, $rowData ) {
213 $this->setMwGlobals( 'wgLegacyEncoding', $encoding );
214 $this->testGetRevisionText( $expected, $rowData );
217 public function provideGetRevisionTextWithGzipAndLegacyEncoding() {
220 * Do not set the external flag!
221 * Otherwise, getRevisionText will hit the live database (if ExternalStore is enabled)!
223 yield
'Utf8NativeGzip' => [
224 "Wiki est l'\xc3\xa9cole superieur !",
227 'old_flags' => 'gzip,utf-8',
228 'old_text' => gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" ),
231 yield
'Utf8LegacyGzip' => [
232 "Wiki est l'\xc3\xa9cole superieur !",
235 'old_flags' => 'gzip',
236 'old_text' => gzdeflate( "Wiki est l'\xe9cole superieur !" ),
242 * @covers Revision::getRevisionText
243 * @dataProvider provideGetRevisionTextWithGzipAndLegacyEncoding
245 public function testGetRevisionWithGzipAndLegacyEncoding( $expected, $encoding, $rowData ) {
246 $this->checkPHPExtension( 'zlib' );
247 $this->setMwGlobals( 'wgLegacyEncoding', $encoding );
248 $this->testGetRevisionText( $expected, $rowData );
252 * @covers Revision::compressRevisionText
254 public function testCompressRevisionTextUtf8() {
256 $row->old_text
= "Wiki est l'\xc3\xa9cole superieur !";
257 $row->old_flags
= Revision
::compressRevisionText( $row->old_text
);
258 $this->assertTrue( false !== strpos( $row->old_flags
, 'utf-8' ),
259 "Flags should contain 'utf-8'" );
260 $this->assertFalse( false !== strpos( $row->old_flags
, 'gzip' ),
261 "Flags should not contain 'gzip'" );
262 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
263 $row->old_text
, "Direct check" );
264 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
265 Revision
::getRevisionText( $row ), "getRevisionText" );
269 * @covers Revision::compressRevisionText
271 public function testCompressRevisionTextUtf8Gzip() {
272 $this->checkPHPExtension( 'zlib' );
273 $this->setMwGlobals( 'wgCompressRevisions', true );
276 $row->old_text
= "Wiki est l'\xc3\xa9cole superieur !";
277 $row->old_flags
= Revision
::compressRevisionText( $row->old_text
);
278 $this->assertTrue( false !== strpos( $row->old_flags
, 'utf-8' ),
279 "Flags should contain 'utf-8'" );
280 $this->assertTrue( false !== strpos( $row->old_flags
, 'gzip' ),
281 "Flags should contain 'gzip'" );
282 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
283 gzinflate( $row->old_text
), "Direct check" );
284 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
285 Revision
::getRevisionText( $row ), "getRevisionText" );
289 * @covers Revision::userJoinCond
291 public function testUserJoinCond() {
293 [ 'LEFT JOIN', [ 'rev_user != 0', 'user_id = rev_user' ] ],
294 Revision
::userJoinCond()
299 * @covers Revision::pageJoinCond
301 public function testPageJoinCond() {
303 [ 'INNER JOIN', [ 'page_id = rev_page' ] ],
304 Revision
::pageJoinCond()
308 public function provideSelectFields() {
323 'rev_comment_text' => 'rev_comment',
324 'rev_comment_data' => 'NULL',
325 'rev_comment_cid' => 'NULL',
326 'rev_content_format',
344 'rev_comment_text' => 'rev_comment',
345 'rev_comment_data' => 'NULL',
346 'rev_comment_cid' => 'NULL',
352 * @dataProvider provideSelectFields
353 * @covers Revision::selectFields
354 * @todo a true unit test would mock CommentStore
356 public function testSelectFields( $contentHandlerUseDB, $expected ) {
357 $this->setMwGlobals( 'wgContentHandlerUseDB', $contentHandlerUseDB );
358 $this->assertEquals( $expected, Revision
::selectFields() );
361 public function provideSelectArchiveFields() {
378 'ar_comment_text' => 'ar_comment',
379 'ar_comment_data' => 'NULL',
380 'ar_comment_cid' => 'NULL',
401 'ar_comment_text' => 'ar_comment',
402 'ar_comment_data' => 'NULL',
403 'ar_comment_cid' => 'NULL',
409 * @dataProvider provideSelectArchiveFields
410 * @covers Revision::selectArchiveFields
411 * @todo a true unit test would mock CommentStore
413 public function testSelectArchiveFields( $contentHandlerUseDB, $expected ) {
414 $this->setMwGlobals( 'wgContentHandlerUseDB', $contentHandlerUseDB );
415 $this->assertEquals( $expected, Revision
::selectArchiveFields() );
419 * @covers Revision::selectTextFields
421 public function testSelectTextFields() {
427 Revision
::selectTextFields()
432 * @covers Revision::selectPageFields
434 public function testSelectPageFields() {
444 Revision
::selectPageFields()
449 * @covers Revision::selectUserFields
451 public function testSelectUserFields() {
456 Revision
::selectUserFields()
460 public function provideFetchFromConds() {
462 yield
[ Revision
::READ_LOCKING
, [ 'FOR UPDATE' ] ];
466 * @dataProvider provideFetchFromConds
467 * @covers Revision::fetchFromConds
469 public function testFetchFromConds( $flags, array $options ) {
470 $conditions = [ 'conditionsArray' ];
472 $db = $this->getMock( IDatabase
::class );
473 $db->expects( $this->once() )
474 ->method( 'selectRow' )
476 $this->equalTo( [ 'revision', 'page', 'user' ] ),
477 // We don't really care about the fields are they come from the selectField methods
478 $this->isType( 'array' ),
479 $this->equalTo( $conditions ),
481 $this->equalTo( 'Revision::fetchFromConds' ),
482 $this->equalTo( $options ),
483 // We don't really care about the join conds are they come from the joinCond methods
484 $this->isType( 'array' )
486 ->willReturn( 'RETURNVALUE' );
488 $wrapper = TestingAccessWrapper
::newFromClass( Revision
::class );
489 $result = $wrapper->fetchFromConds( $db, $conditions, $flags );
491 $this->assertEquals( 'RETURNVALUE', $result );