4 * @group ContentHandler
6 class RevisionTest
extends MediaWikiTestCase
{
7 var $saveGlobals = array();
11 $wgContLang = Language
::factory( 'en' );
14 'wgLegacyEncoding' => false,
15 'wgCompressRevisions' => false,
17 'wgContentHandlerTextFallback' => $GLOBALS['wgContentHandlerTextFallback'],
18 'wgExtraNamespaces' => $GLOBALS['wgExtraNamespaces'],
19 'wgNamespaceContentModels' => $GLOBALS['wgNamespaceContentModels'],
20 'wgContentHandlers' => $GLOBALS['wgContentHandlers'],
23 foreach ( $globalSet as $var => $data ) {
24 $this->saveGlobals
[$var] = $GLOBALS[$var];
25 $GLOBALS[$var] = $data;
28 global $wgExtraNamespaces, $wgNamespaceContentModels, $wgContentHandlers, $wgContLang;
29 $wgExtraNamespaces[ 12312 ] = 'Dummy';
30 $wgExtraNamespaces[ 12313 ] = 'Dummy_talk';
32 $wgNamespaceContentModels[ 12312 ] = "testing";
33 $wgContentHandlers[ "testing" ] = 'DummyContentHandlerForTesting';
34 $wgContentHandlers[ "RevisionTestModifyableContent" ] = 'RevisionTestModifyableContentHandler';
36 MWNamespace
::getCanonicalNamespaces( true ); # reset namespace cache
37 $wgContLang->resetNamespaces(); # reset namespace cache
39 global $wgContentHandlerTextFallback;
40 $wgContentHandlerTextFallback = 'ignore';
46 foreach ( $this->saveGlobals
as $var => $data ) {
47 $GLOBALS[$var] = $data;
50 MWNamespace
::getCanonicalNamespaces( true ); # reset namespace cache
51 $wgContLang->resetNamespaces(); # reset namespace cache
54 function testGetRevisionText() {
57 $row->old_text
= 'This is a bunch of revision text.';
59 'This is a bunch of revision text.',
60 Revision
::getRevisionText( $row ) );
63 function testGetRevisionTextGzip() {
64 if ( !function_exists( 'gzdeflate' ) ) {
65 $this->markTestSkipped( 'Gzip compression is not enabled (requires zlib).' );
68 $row->old_flags
= 'gzip';
69 $row->old_text
= gzdeflate( 'This is a bunch of revision text.' );
71 'This is a bunch of revision text.',
72 Revision
::getRevisionText( $row ) );
76 function testGetRevisionTextUtf8Native() {
78 $row->old_flags
= 'utf-8';
79 $row->old_text
= "Wiki est l'\xc3\xa9cole superieur !";
80 $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
82 "Wiki est l'\xc3\xa9cole superieur !",
83 Revision
::getRevisionText( $row ) );
86 function testGetRevisionTextUtf8Legacy() {
89 $row->old_text
= "Wiki est l'\xe9cole superieur !";
90 $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
92 "Wiki est l'\xc3\xa9cole superieur !",
93 Revision
::getRevisionText( $row ) );
96 function testGetRevisionTextUtf8NativeGzip() {
97 if ( !function_exists( 'gzdeflate' ) ) {
98 $this->markTestSkipped( 'Gzip compression is not enabled (requires zlib).' );
101 $row->old_flags
= 'gzip,utf-8';
102 $row->old_text
= gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" );
103 $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
105 "Wiki est l'\xc3\xa9cole superieur !",
106 Revision
::getRevisionText( $row ) );
110 function testGetRevisionTextUtf8LegacyGzip() {
111 if ( !function_exists( 'gzdeflate' ) ) {
112 $this->markTestSkipped( 'Gzip compression is not enabled (requires zlib).' );
115 $row->old_flags
= 'gzip';
116 $row->old_text
= gzdeflate( "Wiki est l'\xe9cole superieur !" );
117 $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1';
119 "Wiki est l'\xc3\xa9cole superieur !",
120 Revision
::getRevisionText( $row ) );
124 function testCompressRevisionTextUtf8() {
126 $row->old_text
= "Wiki est l'\xc3\xa9cole superieur !";
127 $row->old_flags
= Revision
::compressRevisionText( $row->old_text
);
128 $this->assertTrue( false !== strpos( $row->old_flags
, 'utf-8' ),
129 "Flags should contain 'utf-8'" );
130 $this->assertFalse( false !== strpos( $row->old_flags
, 'gzip' ),
131 "Flags should not contain 'gzip'" );
132 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
133 $row->old_text
, "Direct check" );
134 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
135 Revision
::getRevisionText( $row ), "getRevisionText" );
138 function testCompressRevisionTextUtf8Gzip() {
139 $GLOBALS['wgCompressRevisions'] = true;
141 $row->old_text
= "Wiki est l'\xc3\xa9cole superieur !";
142 $row->old_flags
= Revision
::compressRevisionText( $row->old_text
);
143 $this->assertTrue( false !== strpos( $row->old_flags
, 'utf-8' ),
144 "Flags should contain 'utf-8'" );
145 $this->assertTrue( false !== strpos( $row->old_flags
, 'gzip' ),
146 "Flags should contain 'gzip'" );
147 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
148 gzinflate( $row->old_text
), "Direct check" );
149 $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !",
150 Revision
::getRevisionText( $row ), "getRevisionText" );
153 # =================================================================================================================
156 * @param string $text
157 * @param string $title
158 * @param string $model
161 function newTestRevision( $text, $title = "Test", $model = CONTENT_MODEL_WIKITEXT
, $format = null ) {
162 if ( is_string( $title ) ) {
163 $title = Title
::newFromText( $title );
166 $content = ContentHandler
::makeContent( $text, $title, $model, $format );
174 'content' => $content,
175 'length' => $content->getSize(),
176 'comment' => "testing",
177 'minor_edit' => false,
179 'content_format' => $format,
186 function dataGetContentModel() {
187 //NOTE: we expect the help namespace to always contain wikitext
189 array( 'hello world', 'Help:Hello', null, null, CONTENT_MODEL_WIKITEXT
),
190 array( 'hello world', 'User:hello/there.css', null, null, CONTENT_MODEL_CSS
),
191 array( serialize('hello world'), 'Dummy:Hello', null, null, "testing" ),
197 * @dataProvider dataGetContentModel
199 function testGetContentModel( $text, $title, $model, $format, $expectedModel ) {
200 $rev = $this->newTestRevision( $text, $title, $model, $format );
202 $this->assertEquals( $expectedModel, $rev->getContentModel() );
205 function dataGetContentFormat() {
206 //NOTE: we expect the help namespace to always contain wikitext
208 array( 'hello world', 'Help:Hello', null, null, CONTENT_FORMAT_WIKITEXT
),
209 array( 'hello world', 'Help:Hello', CONTENT_MODEL_CSS
, null, CONTENT_FORMAT_CSS
),
210 array( 'hello world', 'User:hello/there.css', null, null, CONTENT_FORMAT_CSS
),
211 array( serialize('hello world'), 'Dummy:Hello', null, null, "testing" ),
217 * @dataProvider dataGetContentFormat
219 function testGetContentFormat( $text, $title, $model, $format, $expectedFormat ) {
220 $rev = $this->newTestRevision( $text, $title, $model, $format );
222 $this->assertEquals( $expectedFormat, $rev->getContentFormat() );
225 function dataGetContentHandler() {
226 //NOTE: we expect the help namespace to always contain wikitext
228 array( 'hello world', 'Help:Hello', null, null, 'WikitextContentHandler' ),
229 array( 'hello world', 'User:hello/there.css', null, null, 'CssContentHandler' ),
230 array( serialize('hello world'), 'Dummy:Hello', null, null, 'DummyContentHandlerForTesting' ),
236 * @dataProvider dataGetContentHandler
238 function testGetContentHandler( $text, $title, $model, $format, $expectedClass ) {
239 $rev = $this->newTestRevision( $text, $title, $model, $format );
241 $this->assertEquals( $expectedClass, get_class( $rev->getContentHandler() ) );
244 function dataGetContent() {
245 //NOTE: we expect the help namespace to always contain wikitext
247 array( 'hello world', 'Help:Hello', null, null, Revision
::FOR_PUBLIC
, 'hello world' ),
248 array( serialize('hello world'), 'Hello', "testing", null, Revision
::FOR_PUBLIC
, serialize('hello world') ),
249 array( serialize('hello world'), 'Dummy:Hello', null, null, Revision
::FOR_PUBLIC
, serialize('hello world') ),
255 * @dataProvider dataGetContent
257 function testGetContent( $text, $title, $model, $format, $audience, $expectedSerialization ) {
258 $rev = $this->newTestRevision( $text, $title, $model, $format );
259 $content = $rev->getContent( $audience );
261 $this->assertEquals( $expectedSerialization, is_null( $content ) ?
null : $content->serialize( $format ) );
264 function dataGetText() {
265 //NOTE: we expect the help namespace to always contain wikitext
267 array( 'hello world', 'Help:Hello', null, null, Revision
::FOR_PUBLIC
, 'hello world' ),
268 array( serialize('hello world'), 'Hello', "testing", null, Revision
::FOR_PUBLIC
, null ),
269 array( serialize('hello world'), 'Dummy:Hello', null, null, Revision
::FOR_PUBLIC
, null ),
275 * @dataProvider dataGetText
277 function testGetText( $text, $title, $model, $format, $audience, $expectedText ) {
278 $this->hideDeprecated( 'Revision::getText' );
280 $rev = $this->newTestRevision( $text, $title, $model, $format );
282 $this->assertEquals( $expectedText, $rev->getText( $audience ) );
287 * @dataProvider dataGetText
289 function testGetRawText( $text, $title, $model, $format, $audience, $expectedText ) {
290 $this->hideDeprecated( 'Revision::getRawText' );
292 $rev = $this->newTestRevision( $text, $title, $model, $format );
294 $this->assertEquals( $expectedText, $rev->getRawText( $audience ) );
298 public function dataGetSize( ) {
300 array( "hello world.", CONTENT_MODEL_WIKITEXT
, 12 ),
301 array( serialize( "hello world." ), "testing", 12 ),
306 * @covers Revision::getSize
308 * @dataProvider dataGetSize
310 public function testGetSize( $text, $model, $expected_size )
312 $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSize', $model );
313 $this->assertEquals( $expected_size, $rev->getSize() );
316 public function dataGetSha1( ) {
318 array( "hello world.", CONTENT_MODEL_WIKITEXT
, Revision
::base36Sha1( "hello world." ) ),
319 array( serialize( "hello world." ), "testing", Revision
::base36Sha1( serialize( "hello world." ) ) ),
324 * @covers Revision::getSha1
326 * @dataProvider dataGetSha1
328 public function testGetSha1( $text, $model, $expected_hash )
330 $rev = $this->newTestRevision( $text, 'RevisionTest_testGetSha1', $model );
331 $this->assertEquals( $expected_hash, $rev->getSha1() );
334 public function testConstructWithText() {
335 $this->hideDeprecated( "Revision::getText" );
337 $rev = new Revision( array(
338 'text' => 'hello world.',
339 'content_model' => CONTENT_MODEL_JAVASCRIPT
342 $this->assertNotNull( $rev->getText(), 'no content text' );
343 $this->assertNotNull( $rev->getContent(), 'no content object available' );
344 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT
, $rev->getContent()->getModel() );
345 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT
, $rev->getContentModel() );
348 public function testConstructWithContent() {
349 $this->hideDeprecated( "Revision::getText" );
351 $title = Title
::newFromText( 'RevisionTest_testConstructWithContent' );
353 $rev = new Revision( array(
354 'content' => ContentHandler
::makeContent( 'hello world.', $title, CONTENT_MODEL_JAVASCRIPT
),
357 $this->assertNotNull( $rev->getText(), 'no content text' );
358 $this->assertNotNull( $rev->getContent(), 'no content object available' );
359 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT
, $rev->getContent()->getModel() );
360 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT
, $rev->getContentModel() );
364 * Tests whether $rev->getContent() returns a clone when needed.
368 function testGetContentClone( ) {
369 $content = new RevisionTestModifyableContent( "foo" );
375 'title' => Title
::newFromText( "testGetContentClone_dummy" ),
377 'content' => $content,
378 'length' => $content->getSize(),
379 'comment' => "testing",
380 'minor_edit' => false,
384 $content = $rev->getContent( Revision
::RAW
);
385 $content->setText( "bar" );
387 $content2 = $rev->getContent( Revision
::RAW
);
388 $this->assertNotSame( $content, $content2, "expected a clone" ); // content is mutable, expect clone
389 $this->assertEquals( "foo", $content2->getText() ); // clone should contain the original text
391 $content2->setText( "bla bla" );
392 $this->assertEquals( "bar", $content->getText() ); // clones should be independent
397 * Tests whether $rev->getContent() returns the same object repeatedly if appropriate.
401 function testGetContentUncloned() {
402 $rev = $this->newTestRevision( "hello", "testGetContentUncloned_dummy", CONTENT_MODEL_WIKITEXT
);
403 $content = $rev->getContent( Revision
::RAW
);
404 $content2 = $rev->getContent( Revision
::RAW
);
406 // for immutable content like wikitext, this should be the same object
407 $this->assertSame( $content, $content2 );
412 class RevisionTestModifyableContent
extends TextContent
{
413 public function __construct( $text ) {
414 parent
::__construct( $text, "RevisionTestModifyableContent" );
417 public function copy( ) {
418 return new RevisionTestModifyableContent( $this->mText
);
421 public function getText() {
425 public function setText( $text ) {
426 $this->mText
= $text;
431 class RevisionTestModifyableContentHandler
extends TextContentHandler
{
433 public function __construct( ) {
434 parent
::__construct( "RevisionTestModifyableContent", array( CONTENT_FORMAT_TEXT
) );
437 public function unserializeContent( $text, $format = null ) {
438 $this->checkFormat( $format );
440 return new RevisionTestModifyableContent( $text );
443 public function makeEmptyContent() {
444 return new RevisionTestModifyableContent( '' );