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