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