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