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