]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - tests/phpunit/includes/RevisionTest.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / tests / phpunit / includes / RevisionTest.php
1 <?php
2
3 /**
4  * @group ContentHandler
5  */
6 class RevisionTest extends MediaWikiTestCase {
7         protected function setUp() {
8                 global $wgContLang;
9
10                 parent::setUp();
11
12                 $this->setMwGlobals( [
13                         'wgContLang' => Language::factory( 'en' ),
14                         'wgLanguageCode' => 'en',
15                         'wgLegacyEncoding' => false,
16                         'wgCompressRevisions' => false,
17
18                         'wgContentHandlerTextFallback' => 'ignore',
19                 ] );
20
21                 $this->mergeMwGlobalArrayValue(
22                         'wgExtraNamespaces',
23                         [
24                                 12312 => 'Dummy',
25                                 12313 => 'Dummy_talk',
26                         ]
27                 );
28
29                 $this->mergeMwGlobalArrayValue(
30                         'wgNamespaceContentModels',
31                         [
32                                 12312 => 'testing',
33                         ]
34                 );
35
36                 $this->mergeMwGlobalArrayValue(
37                         'wgContentHandlers',
38                         [
39                                 'testing' => 'DummyContentHandlerForTesting',
40                                 'RevisionTestModifyableContent' => 'RevisionTestModifyableContentHandler',
41                         ]
42                 );
43
44                 MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
45                 $wgContLang->resetNamespaces(); # reset namespace cache
46         }
47
48         function tearDown() {
49                 global $wgContLang;
50
51                 MWNamespace::getCanonicalNamespaces( true ); # reset namespace cache
52                 $wgContLang->resetNamespaces(); # reset namespace cache
53
54                 parent::tearDown();
55         }
56
57         /**
58          * @covers Revision::getRevisionText
59          */
60         public function testGetRevisionText() {
61                 $row = new stdClass;
62                 $row->old_flags = '';
63                 $row->old_text = 'This is a bunch of revision text.';
64                 $this->assertEquals(
65                         'This is a bunch of revision text.',
66                         Revision::getRevisionText( $row ) );
67         }
68
69         /**
70          * @covers Revision::getRevisionText
71          */
72         public function testGetRevisionTextGzip() {
73                 $this->checkPHPExtension( 'zlib' );
74
75                 $row = new stdClass;
76                 $row->old_flags = 'gzip';
77                 $row->old_text = gzdeflate( 'This is a bunch of revision text.' );
78                 $this->assertEquals(
79                         'This is a bunch of revision text.',
80                         Revision::getRevisionText( $row ) );
81         }
82
83         /**
84          * @covers Revision::getRevisionText
85          */
86         public function testGetRevisionTextUtf8Native() {
87                 $row = new stdClass;
88                 $row->old_flags = 'utf-8';
89                 $row->old_text = "Wiki est l'\xc3\xa9cole superieur !";
90                 $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
91                 $this->assertEquals(
92                         "Wiki est l'\xc3\xa9cole superieur !",
93                         Revision::getRevisionText( $row ) );
94         }
95
96         /**
97          * @covers Revision::getRevisionText
98          */
99         public function testGetRevisionTextUtf8Legacy() {
100                 $row = new stdClass;
101                 $row->old_flags = '';
102                 $row->old_text = "Wiki est l'\xe9cole superieur !";
103                 $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
104                 $this->assertEquals(
105                         "Wiki est l'\xc3\xa9cole superieur !",
106                         Revision::getRevisionText( $row ) );
107         }
108
109         /**
110          * @covers Revision::getRevisionText
111          */
112         public function testGetRevisionTextUtf8NativeGzip() {
113                 $this->checkPHPExtension( 'zlib' );
114
115                 $row = new stdClass;
116                 $row->old_flags = 'gzip,utf-8';
117                 $row->old_text = gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" );
118                 $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
119                 $this->assertEquals(
120                         "Wiki est l'\xc3\xa9cole superieur !",
121                         Revision::getRevisionText( $row ) );
122         }
123
124         /**
125          * @covers Revision::getRevisionText
126          */
127         public function testGetRevisionTextUtf8LegacyGzip() {
128                 $this->checkPHPExtension( 'zlib' );
129
130                 $row = new stdClass;
131                 $row->old_flags = 'gzip';
132                 $row->old_text = gzdeflate( "Wiki est l'\xe9cole superieur !" );
133                 $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
134                 $this->assertEquals(
135                         "Wiki est l'\xc3\xa9cole superieur !",
136                         Revision::getRevisionText( $row ) );
137         }
138
139         /**
140          * @covers Revision::compressRevisionText
141          */
142         public function testCompressRevisionTextUtf8() {
143                 $row = new stdClass;
144                 $row->old_text = "Wiki est l'\xc3\xa9cole superieur !";
145                 $row->old_flags = Revision::compressRevisionText( $row->old_text );
146                 $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ),
147                         "Flags should contain 'utf-8'" );
148                 $this->assertFalse( false !== strpos( $row->old_flags, 'gzip' ),
149                         "Flags should not contain 'gzip'" );
150                 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
151                         $row->old_text, "Direct check" );
152                 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
153                         Revision::getRevisionText( $row ), "getRevisionText" );
154         }
155
156         /**
157          * @covers Revision::compressRevisionText
158          */
159         public function testCompressRevisionTextUtf8Gzip() {
160                 $this->checkPHPExtension( 'zlib' );
161                 $this->setMwGlobals( 'wgCompressRevisions', true );
162
163                 $row = new stdClass;
164                 $row->old_text = "Wiki est l'\xc3\xa9cole superieur !";
165                 $row->old_flags = Revision::compressRevisionText( $row->old_text );
166                 $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ),
167                         "Flags should contain 'utf-8'" );
168                 $this->assertTrue( false !== strpos( $row->old_flags, 'gzip' ),
169                         "Flags should contain 'gzip'" );
170                 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
171                         gzinflate( $row->old_text ), "Direct check" );
172                 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
173                         Revision::getRevisionText( $row ), "getRevisionText" );
174         }
175
176         # =========================================================================
177
178         /**
179          * @param string $text
180          * @param string $title
181          * @param string $model
182          * @param string $format
183          *
184          * @return Revision
185          */
186         function newTestRevision( $text, $title = "Test",
187                 $model = CONTENT_MODEL_WIKITEXT, $format = null
188         ) {
189                 if ( is_string( $title ) ) {
190                         $title = Title::newFromText( $title );
191                 }
192
193                 $content = ContentHandler::makeContent( $text, $title, $model, $format );
194
195                 $rev = new Revision(
196                         [
197                                 'id' => 42,
198                                 'page' => 23,
199                                 'title' => $title,
200
201                                 'content' => $content,
202                                 'length' => $content->getSize(),
203                                 'comment' => "testing",
204                                 'minor_edit' => false,
205
206                                 'content_format' => $format,
207                         ]
208                 );
209
210                 return $rev;
211         }
212
213         function dataGetContentModel() {
214                 // NOTE: we expect the help namespace to always contain wikitext
215                 return [
216                         [ 'hello world', 'Help:Hello', null, null, CONTENT_MODEL_WIKITEXT ],
217                         [ 'hello world', 'User:hello/there.css', null, null, CONTENT_MODEL_CSS ],
218                         [ serialize( 'hello world' ), 'Dummy:Hello', null, null, "testing" ],
219                 ];
220         }
221
222         /**
223          * @group Database
224          * @dataProvider dataGetContentModel
225          * @covers Revision::getContentModel
226          */
227         public function testGetContentModel( $text, $title, $model, $format, $expectedModel ) {
228                 $rev = $this->newTestRevision( $text, $title, $model, $format );
229
230                 $this->assertEquals( $expectedModel, $rev->getContentModel() );
231         }
232
233         function dataGetContentFormat() {
234                 // NOTE: we expect the help namespace to always contain wikitext
235                 return [
236                         [ 'hello world', 'Help:Hello', null, null, CONTENT_FORMAT_WIKITEXT ],
237                         [ 'hello world', 'Help:Hello', CONTENT_MODEL_CSS, null, CONTENT_FORMAT_CSS ],
238                         [ 'hello world', 'User:hello/there.css', null, null, CONTENT_FORMAT_CSS ],
239                         [ serialize( 'hello world' ), 'Dummy:Hello', null, null, "testing" ],
240                 ];
241         }
242
243         /**
244          * @group Database
245          * @dataProvider dataGetContentFormat
246          * @covers Revision::getContentFormat
247          */
248         public function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) {
249                 $rev = $this->newTestRevision( $text, $title, $model, $format );
250
251                 $this->assertEquals( $expectedFormat, $rev->getContentFormat() );
252         }
253
254         function dataGetContentHandler() {
255                 // NOTE: we expect the help namespace to always contain wikitext
256                 return [
257                         [ 'hello world', 'Help:Hello', null, null, 'WikitextContentHandler' ],
258                         [ 'hello world', 'User:hello/there.css', null, null, 'CssContentHandler' ],
259                         [ serialize( 'hello world' ), 'Dummy:Hello', null, null, 'DummyContentHandlerForTesting' ],
260                 ];
261         }
262
263         /**
264          * @group Database
265          * @dataProvider dataGetContentHandler
266          * @covers Revision::getContentHandler
267          */
268         public function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) {
269                 $rev = $this->newTestRevision( $text, $title, $model, $format );
270
271                 $this->assertEquals( $expectedClass, get_class( $rev->getContentHandler() ) );
272         }
273
274         function dataGetContent() {
275                 // NOTE: we expect the help namespace to always contain wikitext
276                 return [
277                         [ 'hello world', 'Help:Hello', null, null, Revision::FOR_PUBLIC, 'hello world' ],
278                         [
279                                 serialize( 'hello world' ),
280                                 'Hello',
281                                 "testing",
282                                 null,
283                                 Revision::FOR_PUBLIC,
284                                 serialize( 'hello world' )
285                         ],
286                         [
287                                 serialize( 'hello world' ),
288                                 'Dummy:Hello',
289                                 null,
290                                 null,
291                                 Revision::FOR_PUBLIC,
292                                 serialize( 'hello world' )
293                         ],
294                 ];
295         }
296
297         /**
298          * @group Database
299          * @dataProvider dataGetContent
300          * @covers Revision::getContent
301          */
302         public function testGetContent( $text, $title, $model, $format,
303                 $audience, $expectedSerialization
304         ) {
305                 $rev = $this->newTestRevision( $text, $title, $model, $format );
306                 $content = $rev->getContent( $audience );
307
308                 $this->assertEquals(
309                         $expectedSerialization,
310                         is_null( $content ) ? null : $content->serialize( $format )
311                 );
312         }
313
314         public function dataGetSize() {
315                 return [
316                         [ "hello world.", CONTENT_MODEL_WIKITEXT, 12 ],
317                         [ serialize( "hello world." ), "testing", 12 ],
318                 ];
319         }
320
321         /**
322          * @covers Revision::getSize
323          * @group Database
324          * @dataProvider dataGetSize
325          */
326         public function testGetSize( $text, $model, $expected_size ) {
327                 $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSize', $model );
328                 $this->assertEquals( $expected_size, $rev->getSize() );
329         }
330
331         public function dataGetSha1() {
332                 return [
333                         [ "hello world.", CONTENT_MODEL_WIKITEXT, Revision::base36Sha1( "hello world." ) ],
334                         [
335                                 serialize( "hello world." ),
336                                 "testing",
337                                 Revision::base36Sha1( serialize( "hello world." ) )
338                         ],
339                 ];
340         }
341
342         /**
343          * @covers Revision::getSha1
344          * @group Database
345          * @dataProvider dataGetSha1
346          */
347         public function testGetSha1( $text, $model, $expected_hash ) {
348                 $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSha1', $model );
349                 $this->assertEquals( $expected_hash, $rev->getSha1() );
350         }
351
352         /**
353          * @covers Revision::__construct
354          */
355         public function testConstructWithText() {
356                 $rev = new Revision( [
357                         'text' => 'hello world.',
358                         'content_model' => CONTENT_MODEL_JAVASCRIPT
359                 ] );
360
361                 $this->assertNotNull( $rev->getContent(), 'no content object available' );
362                 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModel() );
363                 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
364         }
365
366         /**
367          * @covers Revision::__construct
368          */
369         public function testConstructWithContent() {
370                 $title = Title::newFromText( 'RevisionTest_testConstructWithContent' );
371
372                 $rev = new Revision( [
373                         'content' => ContentHandler::makeContent( 'hello world.', $title, CONTENT_MODEL_JAVASCRIPT ),
374                 ] );
375
376                 $this->assertNotNull( $rev->getContent(), 'no content object available' );
377                 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContent()->getModel() );
378                 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $rev->getContentModel() );
379         }
380
381         /**
382          * Tests whether $rev->getContent() returns a clone when needed.
383          *
384          * @group Database
385          * @covers Revision::getContent
386          */
387         public function testGetContentClone() {
388                 $content = new RevisionTestModifyableContent( "foo" );
389
390                 $rev = new Revision(
391                         [
392                                 'id' => 42,
393                                 'page' => 23,
394                                 'title' => Title::newFromText( "testGetContentClone_dummy" ),
395
396                                 'content' => $content,
397                                 'length' => $content->getSize(),
398                                 'comment' => "testing",
399                                 'minor_edit' => false,
400                         ]
401                 );
402
403                 $content = $rev->getContent( Revision::RAW );
404                 $content->setText( "bar" );
405
406                 $content2 = $rev->getContent( Revision::RAW );
407                 // content is mutable, expect clone
408                 $this->assertNotSame( $content, $content2, "expected a clone" );
409                 // clone should contain the original text
410                 $this->assertEquals( "foo", $content2->getText() );
411
412                 $content2->setText( "bla bla" );
413                 $this->assertEquals( "bar", $content->getText() ); // clones should be independent
414         }
415
416         /**
417          * Tests whether $rev->getContent() returns the same object repeatedly if appropriate.
418          *
419          * @group Database
420          * @covers Revision::getContent
421          */
422         public function testGetContentUncloned() {
423                 $rev = $this->newTestRevision( "hello", "testGetContentUncloned_dummy", CONTENT_MODEL_WIKITEXT );
424                 $content = $rev->getContent( Revision::RAW );
425                 $content2 = $rev->getContent( Revision::RAW );
426
427                 // for immutable content like wikitext, this should be the same object
428                 $this->assertSame( $content, $content2 );
429         }
430 }
431
432 class RevisionTestModifyableContent extends TextContent {
433         public function __construct( $text ) {
434                 parent::__construct( $text, "RevisionTestModifyableContent" );
435         }
436
437         public function copy() {
438                 return new RevisionTestModifyableContent( $this->mText );
439         }
440
441         public function getText() {
442                 return $this->mText;
443         }
444
445         public function setText( $text ) {
446                 $this->mText = $text;
447         }
448 }
449
450 class RevisionTestModifyableContentHandler extends TextContentHandler {
451
452         public function __construct() {
453                 parent::__construct( "RevisionTestModifyableContent", [ CONTENT_FORMAT_TEXT ] );
454         }
455
456         public function unserializeContent( $text, $format = null ) {
457                 $this->checkFormat( $format );
458
459                 return new RevisionTestModifyableContent( $text );
460         }
461
462         public function makeEmptyContent() {
463                 return new RevisionTestModifyableContent( '' );
464         }
465 }