From: Trevor Parscal Date: Tue, 7 Sep 2010 23:02:56 +0000 (+0000) Subject: Merged reorganization work for PHPUnit from branches/phpunit-restructure/ X-Git-Tag: 1.31.0-rc.0~35103 X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/exercices/bilan.php?a=commitdiff_plain;h=8c50f16c24964a74307b33e7510e5fca17793838;p=lhc%2Fweb%2Fwiklou.git Merged reorganization work for PHPUnit from branches/phpunit-restructure/ --- diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index de1838006a..24d728192c 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -693,15 +693,6 @@ $wgAutoloadLocalClasses = array( 'TestFileIterator' => 'maintenance/parserTests.inc', 'TestRecorder' => 'maintenance/parserTests.inc', - # maintenance/tests - 'ApiTestSetup' => 'maintenance/tests/ApiSetup.php', - 'MediaWikiTestSetup' => 'maintenance/tests/MediaWiki_Setup.php', - 'PHPUnitTestRecorder' => 'maintenance/tests/ParserHelpers.php', - 'ParserTestSuiteBackend' => 'maintenance/tests/ParserHelpers.php', - 'ParserUnitTest' => 'maintenance/tests/ParserHelpers.php', - 'SearchEngineTest' => 'maintenance/tests/SearchEngineTest.php', - 'UploadFromUrlTest' => 'maintenance/tests/UploadFromUrlTest.php', - # maintenance/tests/selenium 'SimpleSeleniumTestSuite' => 'maintenance/tests/selenium/SimpleSeleniumTestSuite.php', 'Selenium' => 'maintenance/tests/selenium/Selenium.php', diff --git a/maintenance/tests/ApiSetup.php b/maintenance/tests/ApiSetup.php deleted file mode 100644 index 51d2ff67b5..0000000000 --- a/maintenance/tests/ApiSetup.php +++ /dev/null @@ -1,39 +0,0 @@ -getID() ) { - self::$user = User::createNew( self::$userName, array( - "email" => "test@example.com", - "real_name" => "Test User" ) ); - } - self::$user->setPassword( self::$passWord ); - self::$user->saveSettings(); - } - - $GLOBALS['wgUser'] = self::$user; - } -} diff --git a/maintenance/tests/ApiTest.php b/maintenance/tests/ApiTest.php deleted file mode 100644 index 95afb01858..0000000000 --- a/maintenance/tests/ApiTest.php +++ /dev/null @@ -1,220 +0,0 @@ - null, - 'enablechunks' => false, - 'sessionkey' => null, - ); - } -} - -class ApiTest extends ApiTestSetup { - - function setup() { - parent::setup(); - } - - function testRequireOnlyOneParameterDefault() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => false ), "filename", "enablechunks" ) ); - } - - /** - * @expectedException UsageException - */ - function testRequireOnlyOneParameterZero() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => 0 ), "filename", "enablechunks" ) ); - } - - /** - * @expectedException UsageException - */ - function testRequireOnlyOneParameterTrue() { - $mock = new MockApi(); - - $this->assertEquals( - null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", - "enablechunks" => true ), "filename", "enablechunks" ) ); - } - - function testApi() { - global $wgServerName, $wgServer; - - if ( !isset( $wgServerName ) || !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . - 'be set in LocalSettings.php' ); - } - /* Haven't thought about test ordering yet -- but this depends on HttpTest.php */ - $resp = Http::get( self::$apiUrl . "?format=xml" ); - - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $resp ); - $this->assertNotType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - } - - function testApiLoginNoName() { - global $wgServerName, $wgServer; - - if ( !isset( $wgServerName ) || !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . - 'be set in LocalSettings.php' ); - } - $resp = Http::post( self::$apiUrl . "?action=login&format=xml", - array( "postData" => array( - "lgname" => "", - "lgpassword" => self::$passWord ) ) ); - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $resp ); - $this->assertNotType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - $a = $sxe->login[0]->attributes()->result; - $this->assertEquals( ' result="NoName"', $a->asXML() ); - } - - function testApiLoginBadPass() { - global $wgServerName, $wgServer; - - if ( !isset( $wgServerName ) || !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . - 'be set in LocalSettings.php' ); - } - $resp = Http::post( self::$apiUrl . "?action=login&format=xml", - array( "postData" => array( - "lgname" => self::$userName, - "lgpassword" => "bad" ) ) ); - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $resp ); - $this->assertNotType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - $a = $sxe->login[0]->attributes()->result[0]; - $this->assertEquals( ' result="NeedToken"', $a->asXML() ); - - $token = (string)$sxe->login[0]->attributes()->token; - - $resp = Http::post( self::$apiUrl . "?action=login&format=xml", - array( "postData" => array( - "lgtoken" => $token, - "lgname" => self::$userName, - "lgpassword" => "bad" ) ) ); - - - $sxe = simplexml_load_string( $resp ); - $this->assertNotType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - $a = $sxe->login[0]->attributes()->result[0]; - - $this->assertEquals( ' result="NeedToken"', $a->asXML() ); - } - - function testApiLoginGoodPass() { - global $wgServerName, $wgServer; - - if ( !isset( $wgServerName ) || !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . - 'be set in LocalSettings.php' ); - } - $req = HttpRequest::factory( self::$apiUrl . "?action=login&format=xml", - array( "method" => "POST", - "postData" => array( - "lgname" => self::$userName, - "lgpassword" => self::$passWord ) ) ); - $req->execute(); - - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $req->getContent() ); - $this->assertNotType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - - $a = $sxe->login[0]->attributes()->result[0]; - $this->assertEquals( ' result="NeedToken"', $a->asXML() ); - $token = (string)$sxe->login[0]->attributes()->token; - - $req->setData( array( - "lgtoken" => $token, - "lgname" => self::$userName, - "lgpassword" => self::$passWord ) ); - $req->execute(); - - $sxe = simplexml_load_string( $req->getContent() ); - - $this->assertNotType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - $a = $sxe->login[0]->attributes()->result[0]; - - $this->assertEquals( ' result="Success"', $a->asXML() ); - } - - function testApiGotCookie() { - global $wgServerName, $wgServer, $wgScriptPath; - - if ( !isset( $wgServerName ) || !isset( $wgServer ) ) { - $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . - 'be set in LocalSettings.php' ); - } - $req = HttpRequest::factory( self::$apiUrl . "?action=login&format=xml", - array( "method" => "POST", - "postData" => array( - "lgname" => self::$userName, - "lgpassword" => self::$passWord ) ) ); - $req->execute(); - - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $req->getContent() ); - $this->assertNotType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - - $a = $sxe->login[0]->attributes()->result[0]; - $this->assertEquals( ' result="NeedToken"', $a->asXML() ); - $token = (string)$sxe->login[0]->attributes()->token; - - $req->setData( array( - "lgtoken" => $token, - "lgname" => self::$userName, - "lgpassword" => self::$passWord ) ); - $req->execute(); - - $cj = $req->getCookieJar(); - $this->assertRegexp( '/_session=[^;]*; .*UserID=[0-9]*; .*UserName=' . self::$userName . '; .*Token=/', - $cj->serializeToHttpRequest( $wgScriptPath, $wgServerName ) ); - - - return $cj; - } - - /** - * @depends testApiGotCookie - */ - function testApiListPages( CookieJar $cj ) { - $this->markTestIncomplete( "Not done with this yet" ); - global $wgServerName, $wgServer; - - if ( $wgServerName == "localhost" || $wgServer == "http://localhost" ) { - $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . - 'be set in LocalSettings.php' ); - } - $req = HttpRequest::factory( self::$apiUrl . "?action=query&format=xml&prop=revisions&" . - "titles=Main%20Page&rvprop=timestamp|user|comment|content" ); - $req->setCookieJar( $cj ); - $req->execute(); - libxml_use_internal_errors( true ); - $sxe = simplexml_load_string( $req->getContent() ); - $this->assertNotType( "bool", $sxe ); - $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); - $a = $sxe->query[0]->pages[0]->page[0]->attributes(); - } -} diff --git a/maintenance/tests/ApiWatchTest.php b/maintenance/tests/ApiWatchTest.php deleted file mode 100644 index e12e46d597..0000000000 --- a/maintenance/tests/ApiWatchTest.php +++ /dev/null @@ -1,211 +0,0 @@ -execute(); - - $data[0] = $module->getResultData(); - $data[1] = $req; - $data[2] = $_SESSION; - - return $data; - } - - function testLogin() { - $data = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => 'WikiSysop', - 'lgpassword' => 'none' ), $data ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "NeedToken", $data[0]['login']['result'] ); - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( array( - 'action' => 'login', - "lgtoken" => $token, - "lgname" => 'WikiSysop', - "lgpassword" => 'none' ), $data ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "Success", $data[0]['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] ); - - return $data; - } - - function testGetToken() { - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'titles' => 'Main Page', - 'intoken' => 'edit|delete|protect|move|block|unblock', - 'prop' => 'info' ), $data ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); - - $this->assertArrayHasKey( $key, $data[0]['query']['pages'] ); - $this->assertArrayHasKey( 'edittoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'movetoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'deletetoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'blocktoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'unblocktoken', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'protecttoken', $data[0]['query']['pages'][$key] ); - - return $data; - } - - /** - * @depends testGetToken - */ - function testWatchEdit( $data ) { - $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); - $pageinfo = $data[0]['query']['pages'][$key]; - - $data = $this->doApiRequest( array( - 'action' => 'edit', - 'title' => 'Main Page', - 'text' => 'new text', - 'token' => $pageinfo['edittoken'], - 'watchlist' => 'watch' ), $data ); - $this->assertArrayHasKey( 'edit', $data[0] ); - $this->assertArrayHasKey( 'result', $data[0]['edit'] ); - $this->assertEquals( 'Success', $data[0]['edit']['result'] ); - - return $data; - } - - - /** - * @depends testWatchEdit - */ - function testWatchClear( $data ) { - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ), $data ); - - if ( isset( $data[0]['query']['watchlist'] ) ) { - $wl = $data[0]['query']['watchlist']; - - foreach ( $wl as $page ) { - $data = $this->doApiRequest( array( - 'action' => 'watch', - 'title' => $page['title'], - 'unwatch' => true ), $data ); - } - } - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ), $data ); - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'watchlist', $data[0]['query'] ); - $this->assertEquals( 0, count( $data[0]['query']['watchlist'] ) ); - - return $data; - } - - /** - * @depends testGetToken - */ - function testWatchProtect( $data ) { - $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); - $pageinfo = $data[0]['query']['pages'][$key]; - - $data = $this->doApiRequest( array( - 'action' => 'protect', - 'token' => $pageinfo['protecttoken'], - 'title' => 'Main Page', - 'protections' => 'edit=sysop', - 'watchlist' => 'unwatch' ), $data ); - - $this->assertArrayHasKey( 'protect', $data[0] ); - $this->assertArrayHasKey( 'protections', $data[0]['protect'] ); - $this->assertEquals( 1, count( $data[0]['protect']['protections'] ) ); - $this->assertArrayHasKey( 'edit', $data[0]['protect']['protections'][0] ); - } - - /** - * @depends testGetToken - */ - function testGetRollbackToken( $data ) { - $data = $this->doApiRequest( array( - 'action' => 'query', - 'prop' => 'revisions', - 'titles' => 'Main Page', - 'rvtoken' => 'rollback' ), $data ); - - $this->assertArrayHasKey( 'query', $data[0] ); - $this->assertArrayHasKey( 'pages', $data[0]['query'] ); - $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); - - $this->assertArrayHasKey( 'pageid', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 'revisions', $data[0]['query']['pages'][$key] ); - $this->assertArrayHasKey( 0, $data[0]['query']['pages'][$key]['revisions'] ); - $this->assertArrayHasKey( 'rollbacktoken', $data[0]['query']['pages'][$key]['revisions'][0] ); - - return $data; - } - - /** - * @depends testGetRollbackToken - */ - function testWatchRollback( $data ) { - $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); - $pageinfo = $data[0]['query']['pages'][$key]['revisions'][0]; - - $data = $this->doApiRequest( array( - 'action' => 'rollback', - 'title' => 'Main Page', - 'user' => 'WikiSysop', - 'token' => $pageinfo['rollbacktoken'], - 'watchlist' => 'watch' ), $data ); - - $this->assertArrayHasKey( 'rollback', $data[0] ); - $this->assertArrayHasKey( 'title', $data[0]['rollback'] ); - } - - /** - * @depends testGetToken - */ - function testWatchDelete( $data ) { - $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); - $pageinfo = $data[0]['query']['pages'][$key]; - - $data = $this->doApiRequest( array( - 'action' => 'delete', - 'token' => $pageinfo['deletetoken'], - 'title' => 'Main Page' ), $data ); - $this->assertArrayHasKey( 'delete', $data[0] ); - $this->assertArrayHasKey( 'title', $data[0]['delete'] ); - - $data = $this->doApiRequest( array( - 'action' => 'query', - 'list' => 'watchlist' ), $data ); - } - -} diff --git a/maintenance/tests/CdbTest.php b/maintenance/tests/CdbTest.php deleted file mode 100644 index 8b7afd56ae..0000000000 --- a/maintenance/tests/CdbTest.php +++ /dev/null @@ -1,84 +0,0 @@ -markTestIncomplete( 'This test requires native CDB support to be present.' ); - } - } - - public function testCdb() { - $dir = wfTempDir(); - if ( !is_writable( $dir ) ) { - $this->markTestSkipped( "Temp dir isn't writable" ); - } - - $w1 = new CdbWriter_PHP( "$dir/php.cdb" ); - $w2 = new CdbWriter_DBA( "$dir/dba.cdb" ); - - $data = array(); - for ( $i = 0; $i < 1000; $i++ ) { - $key = $this->randomString(); - $value = $this->randomString(); - $w1->set( $key, $value ); - $w2->set( $key, $value ); - - if ( !isset( $data[$key] ) ) { - $data[$key] = $value; - } - } - - $w1->close(); - $w2->close(); - - $this->assertEquals( - md5_file( "$dir/dba.cdb" ), - md5_file( "$dir/php.cdb" ), - 'same hash' - ); - - $r1 = new CdbReader_PHP( "$dir/php.cdb" ); - $r2 = new CdbReader_DBA( "$dir/dba.cdb" ); - - foreach ( $data as $key => $value ) { - if ( $key === '' ) { - // Known bug - continue; - } - $v1 = $r1->get( $key ); - $v2 = $r2->get( $key ); - - $v1 = $v1 === false ? '(not found)' : $v1; - $v2 = $v2 === false ? '(not found)' : $v2; - - # cdbAssert( 'Mismatch', $key, $v1, $v2 ); - $this->cdbAssert( "PHP error", $key, $v1, $value ); - $this->cdbAssert( "DBA error", $key, $v2, $value ); - } - - unlink( "$dir/dba.cdb" ); - unlink( "$dir/php.cdb" ); - } - - private function randomString() { - $len = mt_rand( 0, 10 ); - $s = ''; - for ( $j = 0; $j < $len; $j++ ) { - $s .= chr( mt_rand( 0, 255 ) ); - } - return $s; - } - - private function cdbAssert( $msg, $key, $v1, $v2 ) { - $this->assertEquals( - $v2, - $v1, - $msg . ', k=' . bin2hex( $key ) - ); - } -} diff --git a/maintenance/tests/DatabaseSqliteTest.php b/maintenance/tests/DatabaseSqliteTest.php deleted file mode 100644 index 29ce6383be..0000000000 --- a/maintenance/tests/DatabaseSqliteTest.php +++ /dev/null @@ -1,70 +0,0 @@ -lastQuery = $sql; - return true; - } - - function replaceVars( $s ) { - return parent::replaceVars( $s ); - } -} - -class DatabaseSqliteTest extends PHPUnit_Framework_TestCase { - var $db; - - function setup() { - if ( !Sqlite::isPresent() ) { - $this->markTestIncomplete( 'No SQLite support detected' ); - } - $this->db = new MockDatabaseSqlite(); - } - - function replaceVars( $sql ) { - // normalize spacing to hide implementation details - return preg_replace( '/\s+/', ' ', $this->db->replaceVars( $sql ) ); - } - - function testReplaceVars() { - $this->assertEquals( 'foo', $this->replaceVars( 'foo' ), "Don't break anything accidentally" ); - - $this->assertEquals( "CREATE TABLE /**/foo (foo_key INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " - . "foo_bar TEXT, foo_name TEXT NOT NULL DEFAULT '', foo_int INTEGER, foo_int2 INTEGER );", - $this->replaceVars( "CREATE TABLE /**/foo (foo_key int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, - foo_bar char(13), foo_name varchar(255) binary NOT NULL DEFAULT '', foo_int tinyint ( 8 ), foo_int2 int(16) ) ENGINE=MyISAM;" ) - ); - - $this->assertEquals( "CREATE TABLE foo ( foo_binary1 BLOB, foo_binary2 BLOB );", - $this->replaceVars( "CREATE TABLE foo ( foo_binary1 binary(16), foo_binary2 varbinary(32) );" ) - ); - - $this->assertEquals( "CREATE TABLE text ( text_foo TEXT );", - $this->replaceVars( "CREATE TABLE text ( text_foo tinytext );" ), - 'Table name changed' - ); - - $this->assertEquals( "CREATE TABLE enums( enum1 TEXT, myenum TEXT)", - $this->replaceVars( "CREATE TABLE enums( enum1 ENUM('A', 'B'), myenum ENUM ('X', 'Y'))" ) - ); - - $this->assertEquals( "ALTER TABLE foo ADD COLUMN foo_bar INTEGER DEFAULT 42", - $this->replaceVars( "ALTER TABLE foo\nADD COLUMN foo_bar int(10) unsigned DEFAULT 42" ) - ); - } - - function testEntireSchema() { - global $IP; - - $result = Sqlite::checkSqlSyntax( "$IP/maintenance/tables.sql" ); - if ( $result !== true ) { - $this->fail( $result ); - } - } -} \ No newline at end of file diff --git a/maintenance/tests/DatabaseTest.php b/maintenance/tests/DatabaseTest.php deleted file mode 100644 index 96a1c1af22..0000000000 --- a/maintenance/tests/DatabaseTest.php +++ /dev/null @@ -1,92 +0,0 @@ -db = wfGetDB( DB_SLAVE ); - } - - function testAddQuotesNull() { - $check = "NULL"; - if ( $this->db->getType() === 'sqlite' ) { - $check = "''"; - } - $this->assertEquals( $check, $this->db->addQuotes( null ) ); - } - - function testAddQuotesInt() { - # returning just "1234" should be ok too, though... - # maybe - $this->assertEquals( - "'1234'", - $this->db->addQuotes( 1234 ) ); - } - - function testAddQuotesFloat() { - # returning just "1234.5678" would be ok too, though - $this->assertEquals( - "'1234.5678'", - $this->db->addQuotes( 1234.5678 ) ); - } - - function testAddQuotesString() { - $this->assertEquals( - "'string'", - $this->db->addQuotes( 'string' ) ); - } - - function testAddQuotesStringQuote() { - $check = "'string''s cause trouble'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "'string\'s cause trouble'"; - } - $this->assertEquals( - $check, - $this->db->addQuotes( "string's cause trouble" ) ); - } - - function testFillPreparedEmpty() { - $sql = $this->db->fillPrepared( - 'SELECT * FROM interwiki', array() ); - $this->assertEquals( - "SELECT * FROM interwiki", - $sql ); - } - - function testFillPreparedQuestion() { - $sql = $this->db->fillPrepared( - 'SELECT * FROM cur WHERE cur_namespace=? AND cur_title=?', - array( 4, "Snicker's_paradox" ) ); - - $check = "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker''s_paradox'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker\'s_paradox'"; - } - $this->assertEquals( $check, $sql ); - } - - function testFillPreparedBang() { - $sql = $this->db->fillPrepared( - 'SELECT user_id FROM ! WHERE user_name=?', - array( '"user"', "Slash's Dot" ) ); - - $check = "SELECT user_id FROM \"user\" WHERE user_name='Slash''s Dot'"; - if ( $this->db->getType() === 'mysql' ) { - $check = "SELECT user_id FROM \"user\" WHERE user_name='Slash\'s Dot'"; - } - $this->assertEquals( $check, $sql ); - } - - function testFillPreparedRaw() { - $sql = $this->db->fillPrepared( - "SELECT * FROM cur WHERE cur_title='This_\\&_that,_WTF\\?\\!'", - array( '"user"', "Slash's Dot" ) ); - $this->assertEquals( - "SELECT * FROM cur WHERE cur_title='This_&_that,_WTF?!'", - $sql ); - } - -} - - diff --git a/maintenance/tests/ExtraParserTest.php b/maintenance/tests/ExtraParserTest.php deleted file mode 100644 index a772d31e37..0000000000 --- a/maintenance/tests/ExtraParserTest.php +++ /dev/null @@ -1,30 +0,0 @@ -assertEquals( "

$longLine

", - $parser->parse( $longLine, $t, $options )->getText() ); - } - } diff --git a/maintenance/tests/GlobalTest.php b/maintenance/tests/GlobalTest.php deleted file mode 100644 index 8dc666070e..0000000000 --- a/maintenance/tests/GlobalTest.php +++ /dev/null @@ -1,212 +0,0 @@ -originals['wgReadOnlyFile'] = $wgReadOnlyFile; - $wgReadOnlyFile = tempnam( wfTempDir(), "mwtest_readonly" ); - unlink( $wgReadOnlyFile ); - } - - function tearDown() { - global $wgReadOnlyFile; - if ( file_exists( $wgReadOnlyFile ) ) { - unlink( $wgReadOnlyFile ); - } - $wgReadOnlyFile = $this->originals['wgReadOnlyFile']; - } - - function testRandom() { - # This could hypothetically fail, but it shouldn't ;) - $this->assertFalse( - wfRandom() == wfRandom() ); - } - - function testUrlencode() { - $this->assertEquals( - "%E7%89%B9%E5%88%A5:Contributions/Foobar", - wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) ); - } - - function testReadOnlyEmpty() { - global $wgReadOnly; - $wgReadOnly = null; - - $this->assertFalse( wfReadOnly() ); - $this->assertFalse( wfReadOnly() ); - } - - function testReadOnlySet() { - global $wgReadOnly, $wgReadOnlyFile; - - $f = fopen( $wgReadOnlyFile, "wt" ); - fwrite( $f, 'Message' ); - fclose( $f ); - $wgReadOnly = null; - - $this->assertTrue( wfReadOnly() ); - $this->assertTrue( wfReadOnly() ); - - unlink( $wgReadOnlyFile ); - $wgReadOnly = null; - - $this->assertFalse( wfReadOnly() ); - $this->assertFalse( wfReadOnly() ); - } - - function testQuotedPrintable() { - $this->assertEquals( - "=?UTF-8?Q?=C4=88u=20legebla=3F?=", - wfQuotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) ); - } - - function testTime() { - $start = wfTime(); - $this->assertType( 'float', $start ); - $end = wfTime(); - $this->assertTrue( $end > $start, "Time is running backwards!" ); - } - - function testArrayToCGI() { - $this->assertEquals( - "baz=AT%26T&foo=bar", - wfArrayToCGI( - array( 'baz' => 'AT&T', 'ignore' => '' ), - array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) ); - } - - function testMimeTypeMatch() { - $this->assertEquals( - 'text/html', - mimeTypeMatch( 'text/html', - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.3 ) ) ); - $this->assertEquals( - 'text/*', - mimeTypeMatch( 'text/html', - array( 'image/*' => 1.0, - 'text/*' => 0.5 ) ) ); - $this->assertEquals( - '*/*', - mimeTypeMatch( 'text/html', - array( '*/*' => 1.0 ) ) ); - $this->assertNull( - mimeTypeMatch( 'text/html', - array( 'image/png' => 1.0, - 'image/svg+xml' => 0.5 ) ) ); - } - - function testNegotiateType() { - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.5, - 'text/*' => 0.2 ), - array( 'text/html' => 1.0 ) ) ); - $this->assertEquals( - 'application/xhtml+xml', - wfNegotiateType( - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.7, - 'text/plain' => 0.5, - 'text/*' => 0.2 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'text/html' => 1.0, - 'text/plain' => 0.5, - 'text/*' => 0.5, - 'application/xhtml+xml' => 0.2 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertEquals( - 'text/html', - wfNegotiateType( - array( 'text/*' => 1.0, - 'image/*' => 0.7, - '*/*' => 0.3 ), - array( 'application/xhtml+xml' => 1.0, - 'text/html' => 0.5 ) ) ); - $this->assertNull( - wfNegotiateType( - array( 'text/*' => 1.0 ), - array( 'application/xhtml+xml' => 1.0 ) ) ); - } - - function testTimestamp() { - $t = gmmktime( 12, 34, 56, 1, 15, 2001 ); - $this->assertEquals( - '20010115123456', - wfTimestamp( TS_MW, $t ), - 'TS_UNIX to TS_MW' ); - $this->assertEquals( - 979562096, - wfTimestamp( TS_UNIX, $t ), - 'TS_UNIX to TS_UNIX' ); - $this->assertEquals( - '2001-01-15 12:34:56', - wfTimestamp( TS_DB, $t ), - 'TS_UNIX to TS_DB' ); - - $this->assertEquals( - '20010115123456', - wfTimestamp( TS_MW, '20010115123456' ), - 'TS_MW to TS_MW' ); - $this->assertEquals( - 979562096, - wfTimestamp( TS_UNIX, '20010115123456' ), - 'TS_MW to TS_UNIX' ); - $this->assertEquals( - '2001-01-15 12:34:56', - wfTimestamp( TS_DB, '20010115123456' ), - 'TS_MW to TS_DB' ); - - $this->assertEquals( - '20010115123456', - wfTimestamp( TS_MW, '2001-01-15 12:34:56' ), - 'TS_DB to TS_MW' ); - $this->assertEquals( - 979562096, - wfTimestamp( TS_UNIX, '2001-01-15 12:34:56' ), - 'TS_DB to TS_UNIX' ); - $this->assertEquals( - '2001-01-15 12:34:56', - wfTimestamp( TS_DB, '2001-01-15 12:34:56' ), - 'TS_DB to TS_DB' ); - } - - function testBasename() { - $sets = array( - '' => '', - '/' => '', - '\\' => '', - '//' => '', - '\\\\' => '', - 'a' => 'a', - 'aaaa' => 'aaaa', - '/a' => 'a', - '\\a' => 'a', - '/aaaa' => 'aaaa', - '\\aaaa' => 'aaaa', - '/aaaa/' => 'aaaa', - '\\aaaa\\' => 'aaaa', - '\\aaaa\\' => 'aaaa', - '/mnt/upload3/wikipedia/en/thumb/8/8b/Zork_Grand_Inquisitor_box_cover.jpg/93px-Zork_Grand_Inquisitor_box_cover.jpg' => '93px-Zork_Grand_Inquisitor_box_cover.jpg', - 'C:\\Progra~1\\Wikime~1\\Wikipe~1\\VIEWER.EXE' => 'VIEWER.EXE', - 'Östergötland_coat_of_arms.png' => 'Östergötland_coat_of_arms.png', - ); - foreach ( $sets as $from => $to ) { - $this->assertEquals( $to, wfBaseName( $from ), - "wfBaseName('$from') => '$to'" ); - } - } - - /* TODO: many more! */ -} - - diff --git a/maintenance/tests/HttpTest.php b/maintenance/tests/HttpTest.php deleted file mode 100644 index 022fa48876..0000000000 --- a/maintenance/tests/HttpTest.php +++ /dev/null @@ -1,567 +0,0 @@ - "review=test" ); - - function setup() { - putenv( "http_proxy" ); /* Remove any proxy env var, so curl doesn't get confused */ - if ( is_array( self::$content ) ) { - return; - } - self::$has_curl = function_exists( 'curl_init' ); - self::$has_fopen = wfIniGetBool( 'allow_url_fopen' ); - - if ( !file_exists( "/usr/bin/curl" ) ) { - $this->markTestIncomplete( "This test requires the curl binary at /usr/bin/curl. If you have curl, please file a bug on this test, or, better yet, provide a patch." ); - } - - $content = tempnam( wfTempDir(), "" ); - $headers = tempnam( wfTempDir(), "" ); - if ( !$content && !$headers ) { - die( "Couldn't create temp file!" ); - } - - // This probably isn't the best test for a proxy, but it works on my system! - system( "curl -0 -o $content -s " . self::$proxy ); - $out = file_get_contents( $content ); - if ( $out ) { - self::$has_proxy = true; - } - - /* Maybe use wget instead of curl here ... just to use a different codebase? */ - foreach ( $this->test_geturl as $u ) { - system( "curl -0 -s -D $headers '$u' -o $content" ); - self::$content["GET $u"] = file_get_contents( $content ); - self::$headers["GET $u"] = file_get_contents( $headers ); - } - foreach ( $this->test_requesturl as $u ) { - system( "curl -0 -s -X POST -H 'Content-Length: 0' -D $headers '$u' -o $content" ); - self::$content["POST $u"] = file_get_contents( $content ); - self::$headers["POST $u"] = file_get_contents( $headers ); - } - foreach ( $this->test_posturl as $u => $postData ) { - system( "curl -0 -s -X POST -d '$postData' -D $headers '$u' -o $content" ); - self::$content["POST $u => $postData"] = file_get_contents( $content ); - self::$headers["POST $u => $postData"] = file_get_contents( $headers ); - } - unlink( $content ); - unlink( $headers ); - } - - - function testInstantiation() { - Http::$httpEngine = false; - - $r = HttpRequest::factory( "http://www.example.com/" ); - if ( self::$has_curl ) { - $this->assertThat( $r, $this->isInstanceOf( 'CurlHttpRequest' ) ); - } else { - $this->assertThat( $r, $this->isInstanceOf( 'PhpHttpRequest' ) ); - } - unset( $r ); - - if ( !self::$has_fopen ) { - $this->setExpectedException( 'MWException' ); - } - Http::$httpEngine = 'php'; - $r = HttpRequest::factory( "http://www.example.com/" ); - $this->assertThat( $r, $this->isInstanceOf( 'PhpHttpRequest' ) ); - unset( $r ); - - if ( !self::$has_curl ) { - $this->setExpectedException( 'MWException' ); - } - Http::$httpEngine = 'curl'; - $r = HttpRequest::factory( "http://www.example.com/" ); - if ( self::$has_curl ) { - $this->assertThat( $r, $this->isInstanceOf( 'CurlHttpRequest' ) ); - } - } - - function runHTTPFailureChecks() { - // Each of the following requests should result in a failure. - - $timeout = 1; - $start_time = time(); - $r = Http::get( "http://www.example.com:1/", $timeout ); - $end_time = time(); - $this->assertLessThan( $timeout + 2, $end_time - $start_time, - "Request took less than {$timeout}s via " . Http::$httpEngine ); - $this->assertEquals( $r, false, "false -- what we get on error from Http::get()" ); - - $r = Http::get( "http://www.example.com/this-file-does-not-exist", $timeout ); - $this->assertFalse( $r, "False on 404s" ); - - - $r = HttpRequest::factory( "http://www.example.com/this-file-does-not-exist" ); - $er = $r->execute(); - if ( is_a( $r, 'PhpHttpRequest' ) && version_compare( '5.2.10', phpversion(), '>' ) ) { - $this->assertRegexp( "/HTTP request failed/", $er->getWikiText() ); - } else { - $this->assertRegexp( "/404 Not Found/", $er->getWikiText() ); - } - } - - function testFailureDefault() { - Http::$httpEngine = false; - $this->runHTTPFailureChecks(); - } - - function testFailurePhp() { - if ( !self::$has_fopen ) { - $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); - } - - Http::$httpEngine = "php"; - $this->runHTTPFailureChecks(); - } - - function testFailureCurl() { - if ( !self::$has_curl ) { - $this->markTestIncomplete( "This test requires curl." ); - } - - Http::$httpEngine = "curl"; - $this->runHTTPFailureChecks(); - } - - /* ./phase3/includes/Import.php:1108: $data = Http::request( $method, $url ); */ - /* ./includes/Import.php:1124: $link = Title::newFromText( "$interwiki:Special:Export/$page" ); */ - /* ./includes/Import.php:1134: return ImportStreamSource::newFromURL( $url, "POST" ); */ - function runHTTPRequests( $proxy = null ) { - $opt = array(); - - if ( $proxy ) { - $opt['proxy'] = $proxy; - } elseif ( $proxy === false ) { - $opt['noProxy'] = true; - } - - /* no postData here because the only request I could find in code so far didn't have any */ - foreach ( $this->test_requesturl as $u ) { - $r = Http::request( "POST", $u, $opt ); - $this->assertEquals( self::$content["POST $u"], "$r", "POST $u with " . Http::$httpEngine ); - } - } - - function testRequestDefault() { - Http::$httpEngine = false; - $this->runHTTPRequests(); - } - - function testRequestPhp() { - if ( !self::$has_fopen ) { - $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); - } - - Http::$httpEngine = "php"; - $this->runHTTPRequests(); - } - - function testRequestCurl() { - if ( !self::$has_curl ) { - $this->markTestIncomplete( "This test requires curl." ); - } - - Http::$httpEngine = "curl"; - $this->runHTTPRequests(); - } - - /* ./extensions/SpamBlacklist/SpamBlacklist_body.php:164: $httpText = Http::get( $fileName ); */ - /* ./extensions/ApiSVGProxy/ApiSVGProxy.body.php:44: $contents = Http::get( $file->getFullUrl() ); */ - /* ./extensions/BookInformation/drivers/IsbnDb.php:24: if( ( $xml = Http::get( $uri ) ) !== false ) { */ - /* ./extensions/BookInformation/drivers/Amazon.php:23: if( ( $xml = Http::get( $uri ) ) !== false ) { */ - /* ./extensions/TitleBlacklist/TitleBlacklist.list.php:217: $result = Http::get( $url ); */ - /* ./extensions/TSPoll/TSPoll.php:68: $get_server = Http::get( 'http://toolserver.org/~jan/poll/dev/main.php?page=wiki_output&id='.$id ); */ - /* ./extensions/TSPoll/TSPoll.php:70: $get_server = Http::get( 'http://toolserver.org/~jan/poll/main.php?page=wiki_output&id='.$id ); */ - /* ./extensions/DoubleWiki/DoubleWiki.php:56: $translation = Http::get( $url.$sep.'action=render' ); */ - /* ./extensions/ExternalPages/ExternalPages_body.php:177: $serializedText = Http::get( $this->mPageURL ); */ - /* ./extensions/Translate/utils/TranslationHelpers.php:143: $suggestions = Http::get( $url, $timeout ); */ - /* ./extensions/Translate/SpecialImportTranslations.php:169: $filedata = Http::get( $url ); ; */ - /* ./extensions/Translate/TranslateEditAddons.php:338: $suggestions = Http::get( $url, $timeout ); */ - /* ./extensions/SecurePoll/includes/user/Auth.php:283: $value = Http::get( $url, 20, $curlParams ); */ - /* ./extensions/DumpHTML/dumpHTML.inc:778: $contents = Http::get( $url ); */ - /* ./extensions/DumpHTML/dumpHTML.inc:1298: $contents = Http::get( $sourceUrl ); */ - /* ./extensions/DumpHTML/dumpHTML.inc:1373: $contents = Http::get( $sourceUrl ); */ - /* ./phase3/maintenance/rebuildInterwiki.inc:101: $intermap = Http::get( 'http://meta.wikimedia.org/w/index.php?title=Interwiki_map&action=raw', 30 ); */ - /* ./phase3/maintenance/findhooks.php:98: $allhookdata = Http::get( 'http://www.mediawiki.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:MediaWiki_hooks&cmlimit=500&format=php' ); */ - /* ./phase3/maintenance/findhooks.php:109: $oldhookdata = Http::get( 'http://www.mediawiki.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Removed_hooks&cmlimit=500&format=php' ); */ - /* ./phase3/maintenance/dumpInterwiki.inc:95: $intermap = Http::get( 'http://meta.wikimedia.org/w/index.php?title=Interwiki_map&action=raw', 30 ); */ - /* ./phase3/includes/parser/Parser.php:3204: $text = Http::get($url); */ - /* ./phase3/includes/filerepo/ForeignAPIRepo.php:131: $data = Http::get( $url ); */ - /* ./phase3/includes/filerepo/ForeignAPIRepo.php:205: $thumb = Http::get( $foreignUrl ); */ - /* ./phase3/includes/filerepo/File.php:1105: $res = Http::get( $renderUrl ); */ - /* ./phase3/includes/GlobalFunctions.php:2760: * @deprecated Use Http::get() instead */ - /* ./phase3/includes/GlobalFunctions.php:2764: return Http::get( $url ); */ - /* ./phase3/includes/ExternalStoreHttp.php:18: $ret = Http::get( $url ); */ - /* ./phase3/includes/Import.php:357: $data = Http::get( $src ); */ - /* ./extensions/ExternalData/ED_Utils.php:291: return Http::get( $url, 'default', array(CURLOPT_SSL_VERIFYPEER => false) ); */ - /* ./extensions/ExternalData/ED_Utils.php:293: return Http::get( $url ); */ - /* ./extensions/ExternalData/ED_Utils.php:306: $page = Http::get( $url, 'default', array(CURLOPT_SSL_VERIFYPEER => false) ); */ - /* ./extensions/ExternalData/ED_Utils.php:308: $page = Http::get( $url ); */ - /* ./extensions/CodeReview/backend/Subversion.php:320: $blob = Http::get( $target, $this->mTimeout ); */ - /* ./extensions/AmazonPlus/AmazonPlus.php:214: $this->response = Http::get( $urlstr ); */ - /* ./extensions/StaticWiki/StaticWiki.php:24: $text = Http::get( $url ) ; */ - /* ./extensions/StaticWiki/StaticWiki.php:64: $history = Http::get ( $wgStaticWikiExternalSite . "index.php?title=" . urlencode ( $url_title ) . "&action=history" ) ; */ - /* ./extensions/Configure/scripts/findSettings.php:126: $cont = Http::get( "http://www.mediawiki.org/w/index.php?title={$page}&action=raw" ); */ - /* ./extensions/TorBlock/TorBlock.class.php:148: $data = Http::get( $url ); */ - /* ./extensions/HoneypotIntegration/HoneypotIntegration.class.php:60: $data = Http::get( $wgHoneypotURLSource, 'default', */ - /* ./extensions/SemanticForms/includes/SF_Utils.inc:378: $page_contents = Http::get($url); */ - /* ./extensions/LocalisationUpdate/LocalisationUpdate.class.php:172: $basefilecontents = Http::get( $basefile ); */ - /* ./extensions/APC/SpecialAPC.php:245: $rss = Http::get( 'http://pecl.php.net/feeds/pkg_apc.rss' ); */ - /* ./extensions/Interlanguage/Interlanguage.php:56: $a = Http::get( $url ); */ - /* ./extensions/MWSearch/MWSearch_body.php:492: $data = Http::get( $searchUrl, $wgLuceneSearchTimeout, $httpOpts); */ - function runHTTPGets( $proxy = null ) { - $opt = array(); - - if ( $proxy ) { - $opt['proxy'] = $proxy; - } elseif ( $proxy === false ) { - $opt['noProxy'] = true; - } - - foreach ( $this->test_geturl as $u ) { - $r = Http::get( $u, 30, $opt ); /* timeout of 30s */ - $this->assertEquals( self::$content["GET $u"], "$r", "Get $u with " . Http::$httpEngine ); - } - } - - function testGetDefault() { - Http::$httpEngine = false; - $this->runHTTPGets(); - } - - function testGetPhp() { - if ( !self::$has_fopen ) { - $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); - } - - Http::$httpEngine = "php"; - $this->runHTTPGets(); - } - - function testGetCurl() { - if ( !self::$has_curl ) { - $this->markTestIncomplete( "This test requires curl." ); - } - - Http::$httpEngine = "curl"; - $this->runHTTPGets(); - } - - /* ./phase3/maintenance/parserTests.inc:1618: return Http::post( $url, array( 'postData' => wfArrayToCGI( $data ) ) ); */ - function runHTTPPosts( $proxy = null ) { - $opt = array(); - - if ( $proxy ) { - $opt['proxy'] = $proxy; - } elseif ( $proxy === false ) { - $opt['noProxy'] = true; - } - - foreach ( $this->test_posturl as $u => $postData ) { - $opt['postData'] = $postData; - $r = Http::post( $u, $opt ); - $this->assertEquals( self::$content["POST $u => $postData"], "$r", - "POST $u (postData=$postData) with " . Http::$httpEngine ); - } - } - - function testPostDefault() { - Http::$httpEngine = false; - $this->runHTTPPosts(); - } - - function testPostPhp() { - if ( !self::$has_fopen ) { - $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); - } - - Http::$httpEngine = "php"; - $this->runHTTPPosts(); - } - - function testPostCurl() { - if ( !self::$has_curl ) { - $this->markTestIncomplete( "This test requires curl." ); - } - - Http::$httpEngine = "curl"; - $this->runHTTPPosts(); - } - - function runProxyRequests() { - if ( !self::$has_proxy ) { - $this->markTestIncomplete( "This test requires a proxy." ); - } - $this->runHTTPGets( self::$proxy ); - $this->runHTTPPosts( self::$proxy ); - $this->runHTTPRequests( self::$proxy ); - - // Set false here to do noProxy - $this->runHTTPGets( false ); - $this->runHTTPPosts( false ); - $this->runHTTPRequests( false ); - } - - function testProxyDefault() { - Http::$httpEngine = false; - $this->runProxyRequests(); - } - - function testProxyPhp() { - if ( !self::$has_fopen ) { - $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); - } - - Http::$httpEngine = 'php'; - $this->runProxyRequests(); - } - - function testProxyCurl() { - if ( !self::$has_curl ) { - $this->markTestIncomplete( "This test requires curl." ); - } - - Http::$httpEngine = 'curl'; - $this->runProxyRequests(); - } - - function testIsLocalUrl() { - } - - /* ./extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.body.php:559: $user_agent = Http::userAgent(); */ - function testUserAgent() { - } - - function testIsValidUrl() { - } - - function testValidateCookieDomain() { - $this->assertFalse( Cookie::validateCookieDomain( "co.uk" ) ); - $this->assertFalse( Cookie::validateCookieDomain( ".co.uk" ) ); - $this->assertFalse( Cookie::validateCookieDomain( "gov.uk" ) ); - $this->assertFalse( Cookie::validateCookieDomain( ".gov.uk" ) ); - $this->assertTrue( Cookie::validateCookieDomain( "supermarket.uk" ) ); - $this->assertFalse( Cookie::validateCookieDomain( "uk" ) ); - $this->assertFalse( Cookie::validateCookieDomain( ".uk" ) ); - $this->assertFalse( Cookie::validateCookieDomain( "127.0.0." ) ); - $this->assertFalse( Cookie::validateCookieDomain( "127." ) ); - $this->assertFalse( Cookie::validateCookieDomain( "127.0.0.1." ) ); - $this->assertTrue( Cookie::validateCookieDomain( "127.0.0.1" ) ); - $this->assertFalse( Cookie::validateCookieDomain( "333.0.0.1" ) ); - $this->assertTrue( Cookie::validateCookieDomain( "example.com" ) ); - $this->assertFalse( Cookie::validateCookieDomain( "example.com." ) ); - $this->assertTrue( Cookie::validateCookieDomain( ".example.com" ) ); - - $this->assertTrue( Cookie::validateCookieDomain( ".example.com", "www.example.com" ) ); - $this->assertFalse( Cookie::validateCookieDomain( "example.com", "www.example.com" ) ); - $this->assertTrue( Cookie::validateCookieDomain( "127.0.0.1", "127.0.0.1" ) ); - $this->assertFalse( Cookie::validateCookieDomain( "127.0.0.1", "localhost" ) ); - - - } - - function testSetCooke() { - $c = new MockCookie( "name", "value", - array( - "domain" => "ac.th", - "path" => "/path/", - ) ); - $this->assertFalse( $c->canServeDomain( "ac.th" ) ); - - $c = new MockCookie( "name", "value", - array( - "domain" => "example.com", - "path" => "/path/", - ) ); - - $this->assertTrue( $c->canServeDomain( "example.com" ) ); - $this->assertFalse( $c->canServeDomain( "www.example.com" ) ); - - $c = new MockCookie( "name", "value", - array( - "domain" => ".example.com", - "path" => "/path/", - ) ); - - $this->assertFalse( $c->canServeDomain( "www.example.net" ) ); - $this->assertFalse( $c->canServeDomain( "example.com" ) ); - $this->assertTrue( $c->canServeDomain( "www.example.com" ) ); - - $this->assertFalse( $c->canServePath( "/" ) ); - $this->assertFalse( $c->canServePath( "/bogus/path/" ) ); - $this->assertFalse( $c->canServePath( "/path" ) ); - $this->assertTrue( $c->canServePath( "/path/" ) ); - - $this->assertTrue( $c->isUnExpired() ); - - $this->assertEquals( "", $c->serializeToHttpRequest( "/path/", "www.example.net" ) ); - $this->assertEquals( "", $c->serializeToHttpRequest( "/", "www.example.com" ) ); - $this->assertEquals( "name=value", $c->serializeToHttpRequest( "/path/", "www.example.com" ) ); - - $c = new MockCookie( "name", "value", - array( - "domain" => "www.example.com", - "path" => "/path/", - ) ); - $this->assertFalse( $c->canServeDomain( "example.com" ) ); - $this->assertFalse( $c->canServeDomain( "www.example.net" ) ); - $this->assertTrue( $c->canServeDomain( "www.example.com" ) ); - - $c = new MockCookie( "name", "value", - array( - "domain" => ".example.com", - "path" => "/path/", - "expires" => "-1 day", - ) ); - $this->assertFalse( $c->isUnExpired() ); - $this->assertEquals( "", $c->serializeToHttpRequest( "/path/", "www.example.com" ) ); - - $c = new MockCookie( "name", "value", - array( - "domain" => ".example.com", - "path" => "/path/", - "expires" => "+1 day", - ) ); - $this->assertTrue( $c->isUnExpired() ); - $this->assertEquals( "name=value", $c->serializeToHttpRequest( "/path/", "www.example.com" ) ); - } - - function testCookieJarSetCookie() { - $cj = new CookieJar; - $cj->setCookie( "name", "value", - array( - "domain" => ".example.com", - "path" => "/path/", - ) ); - $cj->setCookie( "name2", "value", - array( - "domain" => ".example.com", - "path" => "/path/sub", - ) ); - $cj->setCookie( "name3", "value", - array( - "domain" => ".example.com", - "path" => "/", - ) ); - $cj->setCookie( "name4", "value", - array( - "domain" => ".example.net", - "path" => "/path/", - ) ); - $cj->setCookie( "name5", "value", - array( - "domain" => ".example.net", - "path" => "/path/", - "expires" => "-1 day", - ) ); - - $this->assertEquals( "name4=value", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); - $this->assertEquals( "name3=value", $cj->serializeToHttpRequest( "/", "www.example.com" ) ); - $this->assertEquals( "name=value; name3=value", $cj->serializeToHttpRequest( "/path/", "www.example.com" ) ); - - $cj->setCookie( "name5", "value", - array( - "domain" => ".example.net", - "path" => "/path/", - "expires" => "+1 day", - ) ); - $this->assertEquals( "name4=value; name5=value", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); - - $cj->setCookie( "name4", "value", - array( - "domain" => ".example.net", - "path" => "/path/", - "expires" => "-1 day", - ) ); - $this->assertEquals( "name5=value", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); - } - - function testParseResponseHeader() { - $cj = new CookieJar; - - $h[] = "Set-Cookie: name4=value; domain=.example.com; path=/; expires=Mon, 09-Dec-2029 13:46:00 GMT"; - $cj->parseCookieResponseHeader( $h[0], "www.example.com" ); - $this->assertEquals( "name4=value", $cj->serializeToHttpRequest( "/", "www.example.com" ) ); - - $h[] = "name4=value2; domain=.example.com; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT"; - $cj->parseCookieResponseHeader( $h[1], "www.example.com" ); - $this->assertEquals( "", $cj->serializeToHttpRequest( "/", "www.example.com" ) ); - $this->assertEquals( "name4=value2", $cj->serializeToHttpRequest( "/path/", "www.example.com" ) ); - - $h[] = "name5=value3; domain=.example.com; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT"; - $cj->parseCookieResponseHeader( $h[2], "www.example.com" ); - $this->assertEquals( "name4=value2; name5=value3", $cj->serializeToHttpRequest( "/path/", "www.example.com" ) ); - - $h[] = "name6=value3; domain=.example.net; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT"; - $cj->parseCookieResponseHeader( $h[3], "www.example.com" ); - $this->assertEquals( "", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); - - $h[] = "name6=value0; domain=.example.net; path=/path/; expires=Mon, 09-Dec-1999 13:46:00 GMT"; - $cj->parseCookieResponseHeader( $h[4], "www.example.net" ); - $this->assertEquals( "", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); - - $h[] = "name6=value4; domain=.example.net; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT"; - $cj->parseCookieResponseHeader( $h[5], "www.example.net" ); - $this->assertEquals( "name6=value4", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); - } - - function runCookieRequests() { - $r = HttpRequest::factory( "http://www.php.net/manual", array( 'followRedirects' => true ) ); - $r->execute(); - - $jar = $r->getCookieJar(); - $this->assertThat( $jar, $this->isInstanceOf( 'CookieJar' ) ); - - if ( is_a( $r, 'PhpHttpRequest' ) && version_compare( '5.1.7', phpversion(), '>' ) ) { - $this->markTestSkipped( 'Redirection fails or crashes PHP on 5.1.6 and prior' ); - } - $serialized = $jar->serializeToHttpRequest( "/search?q=test", "www.php.net" ); - $this->assertRegExp( '/\bCOUNTRY=[^=;]+/', $serialized ); - $this->assertRegExp( '/\bLAST_LANG=[^=;]+/', $serialized ); - $this->assertEquals( '', $jar->serializeToHttpRequest( "/search?q=test", "www.php.com" ) ); - } - - function testCookieRequestDefault() { - Http::$httpEngine = false; - $this->runCookieRequests(); - } - function testCookieRequestPhp() { - if ( !self::$has_fopen ) { - $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); - } - - Http::$httpEngine = 'php'; - $this->runCookieRequests(); - } - function testCookieRequestCurl() { - if ( !self::$has_curl ) { - $this->markTestIncomplete( "This test requires curl." ); - } - - Http::$httpEngine = 'curl'; - $this->runCookieRequests(); - } -} diff --git a/maintenance/tests/IPTest.php b/maintenance/tests/IPTest.php deleted file mode 100644 index 9db77f72c6..0000000000 --- a/maintenance/tests/IPTest.php +++ /dev/null @@ -1,52 +0,0 @@ -assertTrue( IP::isValid( $ip ) , "$ip is a valid IPv4 address" ); - } - } - } - - public function testInvalidIPs() { - foreach ( range( 256, 999 ) as $i ) { - $a = sprintf( "%03d", $i ); - $b = sprintf( "%02d", $i ); - $c = sprintf( "%01d", $i ); - foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { - $ip = "$f.$f.$f.$f"; - $this->assertFalse( IP::isValid( $ip ), "$ip is not a valid IPv4 address" ); - } - } - } - - public function testBogusIPs() { - $invalid = array( - 'www.xn--var-xla.net', - '216.17.184.G', - '216.17.184.1.', - '216.17.184', - '216.17.184.', - '256.17.184.1' - ); - foreach ( $invalid as $i ) { - $this->assertFalse( IP::isValid( $i ), "$i is an invalid IPv4 address" ); - } - } - - public function testPrivateIPs() { - $private = array( '10.0.0.1', '172.16.0.1', '192.168.0.1' ); - foreach ( $private as $p ) { - $this->assertFalse( IP::isPublic( $p ), "$p is not a public IP address" ); - } - } -} diff --git a/maintenance/tests/ImageFunctionsTest.php b/maintenance/tests/ImageFunctionsTest.php deleted file mode 100644 index 4de4e63d4f..0000000000 --- a/maintenance/tests/ImageFunctionsTest.php +++ /dev/null @@ -1,48 +0,0 @@ - 50, - 'height' => 50, - 'tests' => array( - 50 => 50, - 17 => 17, - 18 => 18 ) ), - array( - 'width' => 366, - 'height' => 300, - 'tests' => array( - 50 => 61, - 17 => 21, - 18 => 22 ) ), - array( - 'width' => 300, - 'height' => 366, - 'tests' => array( - 50 => 41, - 17 => 14, - 18 => 15 ) ), - array( - 'width' => 100, - 'height' => 400, - 'tests' => array( - 50 => 12, - 17 => 4, - 18 => 4 ) ) ); - foreach ( $vals as $row ) { - extract( $row ); - foreach ( $tests as $max => $expected ) { - $y = round( $expected * $height / $width ); - $result = wfFitBoxWidth( $width, $height, $max ); - $y2 = round( $result * $height / $width ); - $this->assertEquals( $expected, - $result, - "($width, $height, $max) wanted: {$expected}x$y, got: {$result}x$y2" ); - } - } - } -} - - diff --git a/maintenance/tests/LanguageConverterTest.php b/maintenance/tests/LanguageConverterTest.php deleted file mode 100644 index 9fdcedc68d..0000000000 --- a/maintenance/tests/LanguageConverterTest.php +++ /dev/null @@ -1,150 +0,0 @@ -lang = new LanguageTest(); - $this->lc = new TestConverter( $this->lang, 'tg', - array( 'tg', 'tg-latn' ) ); - } - - function tearDown() { - global $wgMemc, $wgContLang; - unset( $wgMemc ); - unset( $this->lc ); - unset( $this->lang ); - $wgContLang = null; - } - - function testGetPreferredVariantDefaults() { - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, true ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); - } - - function testGetPreferredVariantHeaders() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg-latn' ); - - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( false, true ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); - } - - function testGetPreferredVariantHeaderWeight() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg;q=1' ); - - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, true ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); - } - - function testGetPreferredVariantHeaderWeight2() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'tg-latn;q=1' ); - - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( false, true ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); - } - - function testGetPreferredVariantHeaderMulti() { - global $wgRequest; - $wgRequest->setHeader( 'Accept-Language', 'en, tg-latn;q=1' ); - - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( false, true ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); - } - - function testGetPreferredVariantUserOption() { - global $wgUser; - - $wgUser = new User; - $wgUser->setId( 1 ); - $wgUser->mDataLoaded = true; - $wgUser->setOption( 'variant', 'tg-latn' ); - - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, true ) ); - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, false ) ); - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, true ) ); - } - - function testGetPreferredVariantHeaderUserVsUrl() { - global $wgRequest, $wgUser, $wgContLang; - - $wgContLang = Language::factory( 'tg-latn' ); - $wgRequest->setVal( 'variant', 'tg' ); - $wgUser = User::newFromId( "admin" ); - $wgUser->setId( 1 ); - $wgUser->setOption( 'variant', 'tg-latn' ); // The user's data is ignored - // because the variant is set in the URL. - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); - } - - - function testGetPreferredVariantDefaultLanguageVariant() { - global $wgDefaultLanguageVariant; - - $wgDefaultLanguageVariant = 'tg-latn'; - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( false, false ) ); - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( false, true ) ); - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, false ) ); - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, true ) ); - } - - function testGetPreferredVariantDefaultLanguageVsUrlVariant() { - global $wgDefaultLanguageVariant, $wgRequest, $wgContLang; - - $wgContLang = Language::factory( 'tg-latn' ); - $wgDefaultLanguageVariant = 'tg'; - $wgRequest->setVal( 'variant', null ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); - $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, true ) ); - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, false ) ); - $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, true ) ); - } -} - -/** - * Test converter (from Tajiki to latin orthography) - */ -class TestConverter extends LanguageConverter { - private $table = array( - 'б' => 'b', - 'в' => 'v', - 'г' => 'g', - ); - - function loadDefaultTables() { - $this->mTables = array( - 'tg-latn' => new ReplacementArray( $this->table ), - 'tg' => new ReplacementArray() - ); - } - -} - -class LanguageTest extends Language { - function __construct() { - parent::__construct(); - $variants = array( 'tg', 'tg-latn' ); - $this->mConverter = new TestConverter( $this, 'tg', $variants ); - } -} diff --git a/maintenance/tests/LicensesTest.php b/maintenance/tests/LicensesTest.php deleted file mode 100644 index c5357f89b8..0000000000 --- a/maintenance/tests/LicensesTest.php +++ /dev/null @@ -1,17 +0,0 @@ -assertTrue( is_a( $lc, 'Licenses' ), 'Correct class' ); - } -} \ No newline at end of file diff --git a/maintenance/tests/LocalFileTest.php b/maintenance/tests/LocalFileTest.php deleted file mode 100644 index 29682b18b5..0000000000 --- a/maintenance/tests/LocalFileTest.php +++ /dev/null @@ -1,104 +0,0 @@ - 'test', - 'directory' => '/testdir', - 'url' => '/testurl', - 'hashLevels' => 2, - 'transformVia404' => false, - ); - $this->repo_hl0 = new LocalRepo( array( 'hashLevels' => 0 ) + $info ); - $this->repo_hl2 = new LocalRepo( array( 'hashLevels' => 2 ) + $info ); - $this->repo_lc = new LocalRepo( array( 'initialCapital' => false ) + $info ); - $this->file_hl0 = $this->repo_hl0->newFile( 'test!' ); - $this->file_hl2 = $this->repo_hl2->newFile( 'test!' ); - $this->file_lc = $this->repo_lc->newFile( 'test!' ); - } - - function tearDown() { - global $wgContLang; - unset( $wgContLang ); - } - - function testGetHashPath() { - $this->assertEquals( '', $this->file_hl0->getHashPath() ); - $this->assertEquals( 'a/a2/', $this->file_hl2->getHashPath() ); - $this->assertEquals( 'c/c4/', $this->file_lc->getHashPath() ); - } - - function testGetRel() { - $this->assertEquals( 'Test!', $this->file_hl0->getRel() ); - $this->assertEquals( 'a/a2/Test!', $this->file_hl2->getRel() ); - $this->assertEquals( 'c/c4/test!', $this->file_lc->getRel() ); - } - - function testGetUrlRel() { - $this->assertEquals( 'Test%21', $this->file_hl0->getUrlRel() ); - $this->assertEquals( 'a/a2/Test%21', $this->file_hl2->getUrlRel() ); - $this->assertEquals( 'c/c4/test%21', $this->file_lc->getUrlRel() ); - } - - function testGetArchivePath() { - $this->assertEquals( '/testdir/archive', $this->file_hl0->getArchivePath() ); - $this->assertEquals( '/testdir/archive/a/a2', $this->file_hl2->getArchivePath() ); - $this->assertEquals( '/testdir/archive/!', $this->file_hl0->getArchivePath( '!' ) ); - $this->assertEquals( '/testdir/archive/a/a2/!', $this->file_hl2->getArchivePath( '!' ) ); - } - - function testGetThumbPath() { - $this->assertEquals( '/testdir/thumb/Test!', $this->file_hl0->getThumbPath() ); - $this->assertEquals( '/testdir/thumb/a/a2/Test!', $this->file_hl2->getThumbPath() ); - $this->assertEquals( '/testdir/thumb/Test!/x', $this->file_hl0->getThumbPath( 'x' ) ); - $this->assertEquals( '/testdir/thumb/a/a2/Test!/x', $this->file_hl2->getThumbPath( 'x' ) ); - } - - function testGetArchiveUrl() { - $this->assertEquals( '/testurl/archive', $this->file_hl0->getArchiveUrl() ); - $this->assertEquals( '/testurl/archive/a/a2', $this->file_hl2->getArchiveUrl() ); - $this->assertEquals( '/testurl/archive/%21', $this->file_hl0->getArchiveUrl( '!' ) ); - $this->assertEquals( '/testurl/archive/a/a2/%21', $this->file_hl2->getArchiveUrl( '!' ) ); - } - - function testGetThumbUrl() { - $this->assertEquals( '/testurl/thumb/Test%21', $this->file_hl0->getThumbUrl() ); - $this->assertEquals( '/testurl/thumb/a/a2/Test%21', $this->file_hl2->getThumbUrl() ); - $this->assertEquals( '/testurl/thumb/Test%21/x', $this->file_hl0->getThumbUrl( 'x' ) ); - $this->assertEquals( '/testurl/thumb/a/a2/Test%21/x', $this->file_hl2->getThumbUrl( 'x' ) ); - } - - function testGetArchiveVirtualUrl() { - $this->assertEquals( 'mwrepo://test/public/archive', $this->file_hl0->getArchiveVirtualUrl() ); - $this->assertEquals( 'mwrepo://test/public/archive/a/a2', $this->file_hl2->getArchiveVirtualUrl() ); - $this->assertEquals( 'mwrepo://test/public/archive/%21', $this->file_hl0->getArchiveVirtualUrl( '!' ) ); - $this->assertEquals( 'mwrepo://test/public/archive/a/a2/%21', $this->file_hl2->getArchiveVirtualUrl( '!' ) ); - } - - function testGetThumbVirtualUrl() { - $this->assertEquals( 'mwrepo://test/thumb/Test%21', $this->file_hl0->getThumbVirtualUrl() ); - $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21', $this->file_hl2->getThumbVirtualUrl() ); - $this->assertEquals( 'mwrepo://test/thumb/Test%21/%21', $this->file_hl0->getThumbVirtualUrl( '!' ) ); - $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21/%21', $this->file_hl2->getThumbVirtualUrl( '!' ) ); - } - - function testGetUrl() { - $this->assertEquals( '/testurl/Test%21', $this->file_hl0->getUrl() ); - $this->assertEquals( '/testurl/a/a2/Test%21', $this->file_hl2->getUrl() ); - } - - function testWfLocalFile() { - $file = wfLocalFile( "File:Some_file_that_probably_doesn't exist.png" ); - $this->assertThat( $file, $this->isInstanceOf( 'LocalFile' ), 'wfLocalFile() returns LocalFile for valid Titles' ); - } -} - - diff --git a/maintenance/tests/Makefile b/maintenance/tests/Makefile deleted file mode 100644 index d489c24faa..0000000000 --- a/maintenance/tests/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# If you have problems with excessive memory usage, use the "tap" or "separate" targets. - -TEST_FILES=$(shell php -r 'include( "./TestFileList.php" ); echo implode( " ", $$testFiles );') -TEST_FILE_TARGETS=$(subst .php,.target,$(TEST_FILES)) - -.PHONY: help test phpunit tap separate install $(TEST_FILE_TARGETS) - -all test: phpunit - -phpunit: - php phpunit.php - -tap: - prove -e 'php phpunit.php --tap' *Test*.php - -separate: $(TEST_FILE_TARGETS) - -# Need --tap because without it, the target specification doesn't work -$(TEST_FILE_TARGETS) : %.target : %.php - php phpunit.php --tap $< - -install: - pear channel-discover pear.phpunit.de - pear install phpunit/PHPUnit - -help: - # Targets: - # phpunit (default) Run all the tests with phpunit - # separate Run each test file in a separate process - # tap Run the tests individually through Test::Harness's prove(1) - # install Install PHPUnit from phpunit.de - # help You're looking at it! diff --git a/maintenance/tests/MediaWikiParserTest.php b/maintenance/tests/MediaWikiParserTest.php deleted file mode 100644 index 121e11aa18..0000000000 --- a/maintenance/tests/MediaWikiParserTest.php +++ /dev/null @@ -1,55 +0,0 @@ -backend = new ParserTestSuiteBackend; - parent::__construct(); - $this->setName( 'Parser tests' ); - } - - public function run( PHPUnit_Framework_TestResult $result = null, $filter = false, - array $groups = array(), array $excludeGroups = array(), $processIsolation = false - ) { - global $IP, $wgContLang, $wgMemc; - $wgContLang = Language::factory( 'en' ); - $wgMemc = new FakeMemCachedClient; - $this->backend->setupDatabase(); - - $iter = new TestFileIterator( "$IP/maintenance/parserTests.txt" ); - $iter->setParser( $this->backend ); - $this->count = 0; - - foreach ( $iter as $test ) { - $this->addTest( new ParserUnitTest( $this, $test ) ); - $this->count++; - } - - parent::run( $result, $filter, $groups, $excludeGroups, $processIsolation ); - - $this->backend->teardownDatabase(); - } - - public function count() { - return $this->count; - } - - public function toString() { - return "MediaWiki Parser Tests"; - } - - public function getBackend() { - return $this->backend; - } - - public function getIterator() { - return $this->iterator; - } -} - diff --git a/maintenance/tests/MediaWiki_Setup.php b/maintenance/tests/MediaWiki_Setup.php deleted file mode 100644 index 85c43d18aa..0000000000 --- a/maintenance/tests/MediaWiki_Setup.php +++ /dev/null @@ -1,34 +0,0 @@ -tableName( $table ); - if ( $db->getType() == 'oracle' ) { - $wgDBprefix = 'pt_'; - } else { - $wgDBprefix = 'parsertest_'; - } - - $db->tablePrefix( $wgDBprefix ); - - if ( $db->isOpen() ) { - foreach ( $tables as $tbl ) { - $newTableName = $db->tableName( $tbl ); - $tableName = $oldTableNames[$tbl]; - $db->query( "DROP TABLE IF EXISTS $newTableName", __METHOD__ ); - $db->duplicateTableStructure( $tableName, $newTableName, __METHOD__ ); - } - return $db; - } else { - // Something amiss - return null; - } - } -} - diff --git a/maintenance/tests/MessageTest.php b/maintenance/tests/MessageTest.php deleted file mode 100644 index 6c5580294e..0000000000 --- a/maintenance/tests/MessageTest.php +++ /dev/null @@ -1,40 +0,0 @@ -assertTrue( wfMessage( 'mainpage' )->exists() ); - $this->assertTrue( wfMessage( 'mainpage' )->params( array() )->exists() ); - $this->assertTrue( wfMessage( 'mainpage' )->rawParams( 'foo', 123 )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->params( array() )->exists() ); - $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->rawParams( 'foo', 123 )->exists() ); - } - - function testKey() { - $this->assertType( 'Message', wfMessage( 'mainpage' ) ); - $this->assertType( 'Message', wfMessage( 'i-dont-exist-evar' ) ); - $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->text() ); - $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->text() ); - } - - function testInLanguage() { - $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( 'en' )->text() ); - $this->assertEquals( 'Заглавная страница', wfMessage( 'mainpage' )->inLanguage( 'ru' )->text() ); - $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( Language::factory( 'en' ) )->text() ); - $this->assertEquals( 'Заглавная страница', wfMessage( 'mainpage' )->inLanguage( Language::factory( 'ru' ) )->text() ); - } - - /** - * @expectedException MWException - */ - function testInLanguageThrows() { - wfMessage( 'foo' )->inLanguage( 123 ); - } -} diff --git a/maintenance/tests/ParserHelpers.php b/maintenance/tests/ParserHelpers.php deleted file mode 100644 index 893bf8b420..0000000000 --- a/maintenance/tests/ParserHelpers.php +++ /dev/null @@ -1,88 +0,0 @@ -suite = $suite; - $this->test = $test; - } - - function count() { return 1; } - - public function run( PHPUnit_Framework_TestResult $result = null ) { - PHPUnit_Framework_Assert::resetCount(); - if ( $result === NULL ) { - $result = new PHPUnit_Framework_TestResult; - } - - $backend = $this->suite->getBackend(); - $result->startTest( $this ); - PHPUnit_Util_Timer::start(); - - $r = false; - try { - # Run the test. - # On failure, the subclassed backend will throw an exception with - # the details. - $r = $backend->runTest( - $this->test['test'], - $this->test['input'], - $this->test['result'], - $this->test['options'], - $this->test['config'] - ); - } - catch ( PHPUnit_Framework_AssertionFailedError $e ) { - $result->addFailure( $this, $e, PHPUnit_Util_Timer::stop() ); - } - catch ( Exception $e ) { - $result->addError( $this, $e, PHPUnit_Util_Timer::stop() ); - } - - $result->endTest( $this, PHPUnit_Util_Timer::stop() ); - - $backend->recorder->record( $this->test['test'], $r ); - $this->addToAssertionCount( PHPUnit_Framework_Assert::getCount() ); - - return $result; - } - - public function toString() { - return $this->test['test']; - } - -} - -class ParserTestSuiteBackend extends ParserTest { - function showTesting( $desc ) { - } - - function showRunFile( $path ) { - } - - function showSuccess( $desc ) { - PHPUnit_Framework_Assert::assertTrue( true, $desc ); - return true; - } - - function showFailure( $desc, $expected, $got ) { - PHPUnit_Framework_Assert::assertEquals( $expected, $got, $desc ); - } - - public function setupRecorder( $options ) { - $this->recorder = new PHPUnitTestRecorder( $this ); - } -} - -class PHPUnitTestRecorder extends TestRecorder { - function record( $test, $result ) { - $this->total++; - $this->success += $result; - - } - - function reportPercentage( $success, $total ) { } -} - diff --git a/maintenance/tests/README b/maintenance/tests/README deleted file mode 100644 index b52e790e1d..0000000000 --- a/maintenance/tests/README +++ /dev/null @@ -1,24 +0,0 @@ -Some quickie unit tests done with the PHPUnit testing framework. To run the -test suite, run 'make test' in this dir. This directly invokes 'phpunit.' - -PHPUnit is no longer maintained by PEAR. To get the current version of -PHPUnit, first uninstall any old version of PHPUnit or PHPUnit2 from PEAR, -then install the current version from phpunit.de like this: - -# pear channel-discover pear.phpunit.de -# pear install phpunit/PHPUnit - -You also may wish to install this via your normal package mechanism: - -# aptitude install phpunit - - or - -# yum install phpunit - -Notes: -- Label currently broken tests in the group Broken and they will not - be run by phpunit. You can add them to the group by putting the - following comment at the top of the file: - /** - * @group Broken - */ -- Need to fix some broken tests diff --git a/maintenance/tests/ResourceLoaderFileModuleTest.php b/maintenance/tests/ResourceLoaderFileModuleTest.php deleted file mode 100644 index 5ad7d9373d..0000000000 --- a/maintenance/tests/ResourceLoaderFileModuleTest.php +++ /dev/null @@ -1,15 +0,0 @@ - false, - 'wgCompressRevisions' => false, - 'wgInputEncoding' => 'utf-8', - 'wgOutputEncoding' => 'utf-8' ); - foreach ( $globalSet as $var => $data ) { - $this->saveGlobals[$var] = $GLOBALS[$var]; - $GLOBALS[$var] = $data; - } - } - - function tearDown() { - foreach ( $this->saveGlobals as $var => $data ) { - $GLOBALS[$var] = $data; - } - } - - function testGetRevisionText() { - $row = new stdClass; - $row->old_flags = ''; - $row->old_text = 'This is a bunch of revision text.'; - $this->assertEquals( - 'This is a bunch of revision text.', - Revision::getRevisionText( $row ) ); - } - - function testGetRevisionTextGzip() { - $row = new stdClass; - $row->old_flags = 'gzip'; - $row->old_text = gzdeflate( 'This is a bunch of revision text.' ); - $this->assertEquals( - 'This is a bunch of revision text.', - Revision::getRevisionText( $row ) ); - } - - function testGetRevisionTextUtf8Native() { - $row = new stdClass; - $row->old_flags = 'utf-8'; - $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - function testGetRevisionTextUtf8Legacy() { - $row = new stdClass; - $row->old_flags = ''; - $row->old_text = "Wiki est l'\xe9cole superieur !"; - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - function testGetRevisionTextUtf8NativeGzip() { - $row = new stdClass; - $row->old_flags = 'gzip,utf-8'; - $row->old_text = gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" ); - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - function testGetRevisionTextUtf8LegacyGzip() { - $row = new stdClass; - $row->old_flags = 'gzip'; - $row->old_text = gzdeflate( "Wiki est l'\xe9cole superieur !" ); - $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; - $this->assertEquals( - "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ) ); - } - - function testCompressRevisionTextUtf8() { - $row = new stdClass; - $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; - $row->old_flags = Revision::compressRevisionText( $row->old_text ); - $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ), - "Flags should contain 'utf-8'" ); - $this->assertFalse( false !== strpos( $row->old_flags, 'gzip' ), - "Flags should not contain 'gzip'" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - $row->old_text, "Direct check" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ), "getRevisionText" ); - } - - function testCompressRevisionTextUtf8Gzip() { - $GLOBALS['wgCompressRevisions'] = true; - $row = new stdClass; - $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; - $row->old_flags = Revision::compressRevisionText( $row->old_text ); - $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ), - "Flags should contain 'utf-8'" ); - $this->assertTrue( false !== strpos( $row->old_flags, 'gzip' ), - "Flags should contain 'gzip'" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - gzinflate( $row->old_text ), "Direct check" ); - $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", - Revision::getRevisionText( $row ), "getRevisionText" ); - } -} - - diff --git a/maintenance/tests/SanitizerTest.php b/maintenance/tests/SanitizerTest.php deleted file mode 100644 index a12f9013f0..0000000000 --- a/maintenance/tests/SanitizerTest.php +++ /dev/null @@ -1,72 +0,0 @@ -assertEquals( - "\xc3\xa9cole", - Sanitizer::decodeCharReferences( 'école' ), - 'decode named entities' - ); - } - - function testDecodeNumericEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole!", - Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), - 'decode numeric entities' - ); - } - - function testDecodeMixedEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole!", - Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), - 'decode mixed numeric/named entities' - ); - } - - function testDecodeMixedComplexEntities() { - $this->assertEquals( - "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas Ĉio dans l'école)", - Sanitizer::decodeCharReferences( - "Ĉio bonas dans l'école! (mais pas &#x108;io dans l'&eacute;cole)" - ), - 'decode mixed complex entities' - ); - } - - function testInvalidAmpersand() { - $this->assertEquals( - 'a & b', - Sanitizer::decodeCharReferences( 'a & b' ), - 'Invalid ampersand' - ); - } - - function testInvalidEntities() { - $this->assertEquals( - '&foo;', - Sanitizer::decodeCharReferences( '&foo;' ), - 'Invalid named entity' - ); - } - - function testInvalidNumberedEntities() { - $this->assertEquals( UTF8_REPLACEMENT, Sanitizer::decodeCharReferences( "�" ), 'Invalid numbered entity' ); - } - - function testSelfClosingTag() { - $GLOBALS['wgUseTidy'] = false; - $this->assertEquals( - '
Hello world
', - Sanitizer::removeHTMLtags( '
Hello world
' ), - 'Self-closing closing div' - ); - } -} - diff --git a/maintenance/tests/SearchDbTest.php b/maintenance/tests/SearchDbTest.php deleted file mode 100644 index e727b65a3e..0000000000 --- a/maintenance/tests/SearchDbTest.php +++ /dev/null @@ -1,31 +0,0 @@ -db = wfGetDB( DB_MASTER ); - if ( !$this->db ) { - $this->markTestIncomplete( "Can't find a database to test with." ); - } - - $GLOBALS['wgContLang'] = new Language; - $this->insertSearchData(); - - $this->insertSearchData(); - $searchType = preg_replace( "/Database/", "Search", - get_class( $this->db ) ); - $this->search = new $searchType( $this->db ); - } - - function tearDown() { - $this->removeSearchData(); - if ( !is_null( $this->db ) ) { - wfGetLB()->closeConnecton( $this->db ); - } - unset( $this->db ); - unset( $this->search ); - $GLOBALS['wgContLang'] = null; - } -} - - diff --git a/maintenance/tests/SearchEngineTest.php b/maintenance/tests/SearchEngineTest.php deleted file mode 100644 index b34ad7df7e..0000000000 --- a/maintenance/tests/SearchEngineTest.php +++ /dev/null @@ -1,176 +0,0 @@ -pageExists( 'Not_Main_Page' ) ) { - return; - } - $this->insertPage( "Not_Main_Page", "This is not a main page", 0 ); - $this->insertPage( 'Talk:Not_Main_Page', 'This is not a talk page to the main page, see [[smithee]]', 1 ); - $this->insertPage( 'Smithee', 'A smithee is one who smiths. See also [[Alan Smithee]]', 0 ); - $this->insertPage( 'Talk:Smithee', 'This article sucks.', 1 ); - $this->insertPage( 'Unrelated_page', 'Nothing in this page is about the S word.', 0 ); - $this->insertPage( 'Another_page', 'This page also is unrelated.', 0 ); - $this->insertPage( 'Help:Help', 'Help me!', 4 ); - $this->insertPage( 'Thppt', 'Blah blah', 0 ); - $this->insertPage( 'Alan_Smithee', 'yum', 0 ); - $this->insertPage( 'Pages', 'are\'food', 0 ); - $this->insertPage( 'HalfOneUp', 'AZ', 0 ); - $this->insertPage( 'FullOneUp', 'AZ', 0 ); - $this->insertPage( 'HalfTwoLow', 'az', 0 ); - $this->insertPage( 'FullTwoLow', 'az', 0 ); - $this->insertPage( 'HalfNumbers', '1234567890', 0 ); - $this->insertPage( 'FullNumbers', '1234567890', 0 ); - $this->insertPage( 'DomainName', 'example.com', 0 ); - } - - function removeSearchData() { - return; - /*while ( count( $this->pageList ) ) { - list( $title, $id ) = array_pop( $this->pageList ); - $article = new Article( $title, $id ); - $article->doDeleteArticle( "Search Test" ); - }*/ - } - - function fetchIds( $results ) { - $this->assertTrue( is_object( $results ) ); - - if ( $this->db->getType() !== 'mysql' && $this->db->getType() !== 'sqlite' ) { - $this->markTestSkipped( "MySQL or SQLite only" ); - } - $matches = array(); - while ( $row = $results->next() ) { - $matches[] = $row->getTitle()->getPrefixedText(); - } - $results->free(); - # Search is not guaranteed to return results in a certain order; - # sort them numerically so we will compare simply that we received - # the expected matches. - sort( $matches ); - return $matches; - } - - // Modified version of WikiRevision::importOldRevision() - function insertPage( $pageName, $text, $ns ) { - $dbw = $this->db; - $title = Title::newFromText( $pageName ); - - $userId = 0; - $userText = 'WikiSysop'; - $comment = 'Search Test'; - - // avoid memory leak...? - $linkCache = LinkCache::singleton(); - $linkCache->clear(); - - $article = new Article( $title ); - $pageId = $article->getId(); - $created = false; - if ( $pageId == 0 ) { - # must create the page... - $pageId = $article->insertOn( $dbw ); - $created = true; - } - - # FIXME: Use original rev_id optionally (better for backups) - # Insert the row - $revision = new Revision( array( - 'page' => $pageId, - 'text' => $text, - 'comment' => $comment, - 'user' => $userId, - 'user_text' => $userText, - 'timestamp' => 0, - 'minor_edit' => false, - ) ); - $revId = $revision->insertOn( $dbw ); - $changed = $article->updateIfNewerOn( $dbw, $revision ); - - $GLOBALS['wgTitle'] = $title; - if ( $created ) { - Article::onArticleCreate( $title ); - $article->createUpdates( $revision ); - } elseif ( $changed ) { - Article::onArticleEdit( $title ); - $article->editUpdates( - $text, $comment, false, 0, $revId ); - } - - $su = new SearchUpdate( $article->getId(), $pageName, $text ); - $su->doUpdate(); - - $this->pageList[] = array( $title, $article->getId() ); - - return true; - } - - function testFullWidth() { - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'AZ' ) ), - "Search for normalized from Half-width Upper" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'az' ) ), - "Search for normalized from Half-width Lower" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'AZ' ) ), - "Search for normalized from Full-width Upper" ); - $this->assertEquals( - array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), - $this->fetchIds( $this->search->searchText( 'az' ) ), - "Search for normalized from Full-width Lower" ); - } - - function testTextSearch() { - $this->assertEquals( - array( 'Smithee' ), - $this->fetchIds( $this->search->searchText( 'smithee' ) ), - "Plain search failed" ); - } - - function testTextPowerSearch() { - $this->search->setNamespaces( array( 0, 1, 4 ) ); - $this->assertEquals( - array( - 'Smithee', - 'Talk:Not Main Page', - ), - $this->fetchIds( $this->search->searchText( 'smithee' ) ), - "Power search failed" ); - } - - function testTitleSearch() { - $this->assertEquals( - array( - 'Alan Smithee', - 'Smithee', - ), - $this->fetchIds( $this->search->searchTitle( 'smithee' ) ), - "Title search failed" ); - } - - function testTextTitlePowerSearch() { - $this->search->setNamespaces( array( 0, 1, 4 ) ); - $this->assertEquals( - array( - 'Alan Smithee', - 'Smithee', - 'Talk:Smithee', - ), - $this->fetchIds( $this->search->searchTitle( 'smithee' ) ), - "Title power search failed" ); - } - -} diff --git a/maintenance/tests/SearchUpdateTest.php b/maintenance/tests/SearchUpdateTest.php deleted file mode 100644 index fd7230d327..0000000000 --- a/maintenance/tests/SearchUpdateTest.php +++ /dev/null @@ -1,123 +0,0 @@ -mConn = true; - $this->mOpened = true; - } - - function open( $server, $user, $password, $dbName ) { return true; } - function doQuery( $sql ) { } - function fetchObject( $res ) { } - function fetchRow( $res ) { } - function numRows( $res ) { } - function numFields( $res ) { } - function fieldName( $res, $n ) { } - function insertId() { } - function dataSeek( $res, $row ) { } - function lastErrno() { return 0; } - function lastError() { return ''; } - function affectedRows() { } - function fieldInfo( $table, $field ) { } - function strencode( $s ) { } - static function getSoftwareLink() { } - function getServerVersion() { } - function getType() { } - function getSearchEngine() { } -} - -class MockSearch extends SearchEngine { - public static $id; - public static $title; - public static $text; - - public function __construct( $db ) { - } - - public function update( $id, $title, $text ) { - self::$id = $id; - self::$title = $title; - self::$text = $text; - } -} - -class SearchUpdateTest extends PHPUnit_Framework_TestCase { - static $searchType; - static $dbtype; - static $factoryconf; - static $dbservers; - - function update( $text, $title = 'Test', $id = 1 ) { - $u = new SearchUpdate( $id, $title, $text ); - $u->doUpdate(); - return array( MockSearch::$title, MockSearch::$text ); - } - - function updateText( $text ) { - list( $title, $resultText ) = $this->update( $text ); - $resultText = trim( $resultText ); // abstract from some implementation details - return $resultText; - } - - function setUp() { - global $wgSearchType, $wgDBtype, $wgLBFactoryConf, $wgDBservers, $wgContLang; - - self::$searchType = $wgSearchType; - self::$dbtype = $wgDBtype; - self::$factoryconf = $wgLBFactoryConf; - self::$dbservers = $wgDBservers; - - $wgSearchType = 'MockSearch'; - $wgDBtype = 'mock'; - $wgLBFactoryConf['class'] = 'LBFactory_Simple'; - $wgDBservers = null; - $wgContLang = Language::factory( 'en' ); - LBFactory::destroyInstance(); - } - - function tearDown() { - global $wgSearchType, $wgDBtype, $wgLBFactoryConf, $wgDBservers, $wgContLang; - - LBFactory::destroyInstance(); - - $wgSearchType = self::$searchType; - $wgDBtype = self::$dbtype; - $wgLBFactoryConf = self::$factoryconf; - $wgDBservers = self::$dbservers; - $wgContLang = null; - } - - function testUpdateText() { - $this->assertEquals( - 'test', - $this->updateText( '
TeSt
' ), - 'HTML stripped, text lowercased' - ); - - $this->assertEquals( - 'foo bar boz quux', - $this->updateText( << -
foo
bar - bozquux - -EOT - ), 'Stripping HTML tables' ); - - $this->assertEquals( - 'a b', - $this->updateText( 'a > b' ), - 'Handle unclosed tags' - ); - - $text = str_pad( "foo assertNotEquals( - '', - $this->updateText( $text ), - 'Bug 18609' - ); - } -} diff --git a/maintenance/tests/SiteConfigurationTest.php b/maintenance/tests/SiteConfigurationTest.php deleted file mode 100644 index dec5d5fa02..0000000000 --- a/maintenance/tests/SiteConfigurationTest.php +++ /dev/null @@ -1,311 +0,0 @@ -suffixes as $suffix ) { - if ( substr( $wiki, -strlen( $suffix ) ) == $suffix ) { - $site = $suffix; - $lang = substr( $wiki, 0, -strlen( $suffix ) ); - break; - } - } - return array( - 'suffix' => $site, - 'lang' => $lang, - 'params' => array( - 'lang' => $lang, - 'site' => $site, - 'wiki' => $wiki, - ), - 'tags' => array( 'tag' ), - ); -} - -class SiteConfigurationTest extends PHPUnit_Framework_TestCase { - var $mConf; - - function setUp() { - $this->mConf = new SiteConfiguration; - - $this->mConf->suffixes = array( 'wiki' ); - $this->mConf->wikis = array( 'enwiki', 'dewiki', 'frwiki' ); - $this->mConf->settings = array( - 'simple' => array( - 'wiki' => 'wiki', - 'tag' => 'tag', - 'enwiki' => 'enwiki', - 'dewiki' => 'dewiki', - 'frwiki' => 'frwiki', - ), - - 'fallback' => array( - 'default' => 'default', - 'wiki' => 'wiki', - 'tag' => 'tag', - ), - - 'params' => array( - 'default' => '$lang $site $wiki', - ), - - '+global' => array( - 'wiki' => array( - 'wiki' => 'wiki', - ), - 'tag' => array( - 'tag' => 'tag', - ), - 'enwiki' => array( - 'enwiki' => 'enwiki', - ), - 'dewiki' => array( - 'dewiki' => 'dewiki', - ), - 'frwiki' => array( - 'frwiki' => 'frwiki', - ), - ), - - 'merge' => array( - '+wiki' => array( - 'wiki' => 'wiki', - ), - '+tag' => array( - 'tag' => 'tag', - ), - 'default' => array( - 'default' => 'default', - ), - '+enwiki' => array( - 'enwiki' => 'enwiki', - ), - '+dewiki' => array( - 'dewiki' => 'dewiki', - ), - '+frwiki' => array( - 'frwiki' => 'frwiki', - ), - ), - ); - - $GLOBALS['global'] = array( 'global' => 'global' ); - } - - - function testSiteFromDB() { - $this->assertEquals( - array( 'wikipedia', 'en' ), - $this->mConf->siteFromDB( 'enwiki' ), - 'siteFromDB()' - ); - $this->assertEquals( - array( 'wikipedia', '' ), - $this->mConf->siteFromDB( 'wiki' ), - 'siteFromDB() on a suffix' - ); - $this->assertEquals( - array( null, null ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() on a non-existing wiki' - ); - - $this->mConf->suffixes = array( 'wiki', '' ); - $this->assertEquals( - array( '', 'wikien' ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() on a non-existing wiki (2)' - ); - } - - function testGetLocalDatabases() { - $this->assertEquals( - array( 'enwiki', 'dewiki', 'frwiki' ), - $this->mConf->getLocalDatabases(), - 'getLocalDatabases()' - ); - } - - function testGet() { - $this->assertEquals( - 'enwiki', - $this->mConf->get( 'simple', 'enwiki', 'wiki' ), - 'get(): simple setting on an existing wiki' - ); - $this->assertEquals( - 'dewiki', - $this->mConf->get( 'simple', 'dewiki', 'wiki' ), - 'get(): simple setting on an existing wiki (2)' - ); - $this->assertEquals( - 'frwiki', - $this->mConf->get( 'simple', 'frwiki', 'wiki' ), - 'get(): simple setting on an existing wiki (3)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'simple', 'wiki', 'wiki' ), - 'get(): simple setting on an suffix' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'simple', 'eswiki', 'wiki' ), - 'get(): simple setting on an non-existing wiki' - ); - - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'enwiki', 'wiki' ), - 'get(): fallback setting on an existing wiki' - ); - $this->assertEquals( - 'tag', - $this->mConf->get( 'fallback', 'dewiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an existing wiki (with wiki tag)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'wiki', 'wiki' ), - 'get(): fallback setting on an suffix' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'wiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an suffix (with wiki tag)' - ); - $this->assertEquals( - 'wiki', - $this->mConf->get( 'fallback', 'eswiki', 'wiki' ), - 'get(): fallback setting on an non-existing wiki' - ); - $this->assertEquals( - 'tag', - $this->mConf->get( 'fallback', 'eswiki', 'wiki', array(), array( 'tag' ) ), - 'get(): fallback setting on an non-existing wiki (with wiki tag)' - ); - - $common = array( 'wiki' => 'wiki', 'default' => 'default' ); - $commonTag = array( 'tag' => 'tag', 'wiki' => 'wiki', 'default' => 'default' ); - $this->assertEquals( - array( 'enwiki' => 'enwiki' ) + $common, - $this->mConf->get( 'merge', 'enwiki', 'wiki' ), - 'get(): merging setting on an existing wiki' - ); - $this->assertEquals( - array( 'enwiki' => 'enwiki' ) + $commonTag, - $this->mConf->get( 'merge', 'enwiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (with tag)' - ); - $this->assertEquals( - array( 'dewiki' => 'dewiki' ) + $common, - $this->mConf->get( 'merge', 'dewiki', 'wiki' ), - 'get(): merging setting on an existing wiki (2)' - ); - $this->assertEquals( - array( 'dewiki' => 'dewiki' ) + $commonTag, - $this->mConf->get( 'merge', 'dewiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (2) (with tag)' - ); - $this->assertEquals( - array( 'frwiki' => 'frwiki' ) + $common, - $this->mConf->get( 'merge', 'frwiki', 'wiki' ), - 'get(): merging setting on an existing wiki (3)' - ); - $this->assertEquals( - array( 'frwiki' => 'frwiki' ) + $commonTag, - $this->mConf->get( 'merge', 'frwiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an existing wiki (3) (with tag)' - ); - $this->assertEquals( - array( 'wiki' => 'wiki' ) + $common, - $this->mConf->get( 'merge', 'wiki', 'wiki' ), - 'get(): merging setting on an suffix' - ); - $this->assertEquals( - array( 'wiki' => 'wiki' ) + $commonTag, - $this->mConf->get( 'merge', 'wiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an suffix (with tag)' - ); - $this->assertEquals( - $common, - $this->mConf->get( 'merge', 'eswiki', 'wiki' ), - 'get(): merging setting on an non-existing wiki' - ); - $this->assertEquals( - $commonTag, - $this->mConf->get( 'merge', 'eswiki', 'wiki', array(), array( 'tag' ) ), - 'get(): merging setting on an non-existing wiki (with tag)' - ); - } - - function testSiteFromDBWithCallback() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $this->assertEquals( - array( 'wiki', 'en' ), - $this->mConf->siteFromDB( 'enwiki' ), - 'siteFromDB() with callback' - ); - $this->assertEquals( - array( 'wiki', '' ), - $this->mConf->siteFromDB( 'wiki' ), - 'siteFromDB() with callback on a suffix' - ); - $this->assertEquals( - array( null, null ), - $this->mConf->siteFromDB( 'wikien' ), - 'siteFromDB() with callback on a non-existing wiki' - ); - } - - function testParamReplacement() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $this->assertEquals( - 'en wiki enwiki', - $this->mConf->get( 'params', 'enwiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki' - ); - $this->assertEquals( - 'de wiki dewiki', - $this->mConf->get( 'params', 'dewiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki (2)' - ); - $this->assertEquals( - 'fr wiki frwiki', - $this->mConf->get( 'params', 'frwiki', 'wiki' ), - 'get(): parameter replacement on an existing wiki (3)' - ); - $this->assertEquals( - ' wiki wiki', - $this->mConf->get( 'params', 'wiki', 'wiki' ), - 'get(): parameter replacement on an suffix' - ); - $this->assertEquals( - 'es wiki eswiki', - $this->mConf->get( 'params', 'eswiki', 'wiki' ), - 'get(): parameter replacement on an non-existing wiki' - ); - } - - function testGetAll() { - $this->mConf->siteParamsCallback = 'getSiteParams'; - - $getall = array( - 'simple' => 'enwiki', - 'fallback' => 'tag', - 'params' => 'en wiki enwiki', - 'global' => array( 'enwiki' => 'enwiki' ) + $GLOBALS['global'], - 'merge' => array( 'enwiki' => 'enwiki', 'tag' => 'tag', 'wiki' => 'wiki', 'default' => 'default' ), - ); - $this->assertEquals( $getall, $this->mConf->getAll( 'enwiki' ), 'getAll()' ); - - $this->mConf->extractAllGlobals( 'enwiki', 'wiki' ); - - $this->assertEquals( $getall['simple'], $GLOBALS['simple'], 'extractAllGlobals(): simple setting' ); - $this->assertEquals( $getall['fallback'], $GLOBALS['fallback'], 'extractAllGlobals(): fallback setting' ); - $this->assertEquals( $getall['params'], $GLOBALS['params'], 'extractAllGlobals(): parameter replacement' ); - $this->assertEquals( $getall['global'], $GLOBALS['global'], 'extractAllGlobals(): merging with global' ); - $this->assertEquals( $getall['merge'], $GLOBALS['merge'], 'extractAllGlobals(): merging setting' ); - } -} diff --git a/maintenance/tests/TestFileList.php b/maintenance/tests/TestFileList.php deleted file mode 100644 index f3d86ff4bc..0000000000 --- a/maintenance/tests/TestFileList.php +++ /dev/null @@ -1,30 +0,0 @@ -iniSet( 'precision', 15 ); - } - - public function tearDown() { - global $wgLocalTZoffset; - $wgLocalTZoffset = self::$offset; - } - - # Test offset usage for a given language::userAdjust - function testUserAdjust() { - global $wgLocalTZoffset, $wgContLang; - - $wgContLang = $en = Language::factory( 'en' ); - - #  Collection of parameters for Language_t_Offset. - # Format: date to be formatted, localTZoffset value, expected date - $userAdjust_tests = array( - array( 20061231235959, 0, 20061231235959 ), - array( 20061231235959, 5, 20070101000459 ), - array( 20061231235959, 15, 20070101001459 ), - array( 20061231235959, 60, 20070101005959 ), - array( 20061231235959, 90, 20070101012959 ), - array( 20061231235959, 120, 20070101015959 ), - array( 20061231235959, 540, 20070101085959 ), - array( 20061231235959, -5, 20061231235459 ), - array( 20061231235959, -30, 20061231232959 ), - array( 20061231235959, -60, 20061231225959 ), - ); - - foreach ( $userAdjust_tests as $data ) { - $wgLocalTZoffset = $data[1]; - - $this->assertEquals( - strval( $data[2] ), - strval( $en->userAdjust( $data[0], '' ) ), - "User adjust {$data[0]} by {$data[1]} minutes should give {$data[2]}" - ); - } - } -} diff --git a/maintenance/tests/TitlePermissionTest.php b/maintenance/tests/TitlePermissionTest.php deleted file mode 100644 index a3270fa35c..0000000000 --- a/maintenance/tests/TitlePermissionTest.php +++ /dev/null @@ -1,651 +0,0 @@ -getID() ) { - self::$userUser = User::createNew( self::$userName, array( - "email" => "test@example.com", - "real_name" => "Test User" ) ); - } - - self::$altUser = User::newFromName( self::$altUserName ); - if ( !self::$altUser->getID() ) { - self::$altUser = User::createNew( self::$altUserName, array( - "email" => "alttest@example.com", - "real_name" => "Test User Alt" ) ); - } - - self::$anonUser = User::newFromId( 0 ); - - self::$user = self::$userUser; - } - } - - function tearDown() { - global $wgMemc, $wgContLang, $wgLang; - $wgMemc = $wgContLang = $wgLang = null; - } - - function setUserPerm( $perm ) { - if ( is_array( $perm ) ) { - self::$user->mRights = $perm; - } else { - self::$user->mRights = array( $perm ); - } - } - - function setTitle( $ns, $title = "Main_Page" ) { - self::$title = Title::makeTitle( $ns, $title ); - } - - function setUser( $userName = null ) { - if ( $userName === 'anon' ) { - self::$user = self::$anonUser; - } else if ( $userName === null || $userName === self::$userName ) { - self::$user = self::$userUser; - } else { - self::$user = self::$altUser; - } - - global $wgUser; - $wgUser = self::$user; - } - - function testQuickPermissions() { - global $wgContLang; - $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array(), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array( array( "nocreatetext" ) ), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array( array( 'nocreatetext' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array( ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array( array( 'nocreatetext' ) ), $res ); - - $this->setUser( self::$userName ); - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array( ), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array( ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( "" ); - $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); - $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_USER, self::$userName . '' ); - $this->setUserPerm( "" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'cant-move-user-page' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, self::$userName . '/subpage' ); - $this->setUserPerm( "" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, self::$userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, self::$userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, self::$userName . '' ); - $this->setUserPerm( "" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'cant-move-user-page' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, self::$userName . '/subpage' ); - $this->setUserPerm( "" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, self::$userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_USER, self::$userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setUser( self::$userName ); - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ), $res ); - - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'movenotallowed' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ), $res ); - - $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); - $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); - $this->assertEquals( array( array( 'movenologintext' ) ), $res ); - - $this->setUser( self::$userName ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ) ) ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ) ); - - $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ) ) ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ), - array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ) ); - - $this->setTitle( NS_MAIN ); - $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( ) ); - - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ), - array( array( 'movenologintext' ) ) ); - - $this->setUser( self::$userName ); - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ) ); - - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', array( ) ); - - $this->setUser( 'anon' ); - $this->setUserPerm( 'move' ); - $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); - $this->assertEquals( array( ), $res ); - - $this->setUserPerm( '' ); - $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); - $this->assertEquals( array( array( 'movenotallowed' ) ), $res ); - - $this->setTitle( NS_USER ); - $this->setUser( self::$userName ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); - $this->assertEquals( array( ), $res ); - - $this->setUserPerm( "move" ); - $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); - $this->assertEquals( array( array( 'cant-move-to-user-page' ) ), $res ); - - $this->setUser( 'anon' ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); - $this->assertEquals( array( ), $res ); - - $this->setTitle( NS_USER, "User/subpage" ); - $this->setUserPerm( array( "move", "move-rootuserpages" ) ); - $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); - $this->assertEquals( array( ), $res ); - - $this->setUserPerm( "move" ); - $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); - $this->assertEquals( array( ), $res ); - - $this->setUser( 'anon' ); - $check = array( 'edit' => array( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ) ), - array( array( 'badaccess-group0' ) ), - array( ), true ), - 'protect' => array( array( array( 'badaccess-groups', "[[$prefix:Administrators|Administrators]]", 1 ), array( 'protect-cantedit' ) ), - array( array( 'badaccess-group0' ), array( 'protect-cantedit' ) ), - array( array( 'protect-cantedit' ) ), false ), - '' => array( array( ), array( ), array( ), true ) ); - global $wgUser; - $wgUser = self::$user; - foreach ( array( "edit", "protect", "" ) as $action ) { - $this->setUserPerm( null ); - $this->assertEquals( $check[$action][0], - self::$title->getUserPermissionsErrors( $action, self::$user, true ) ); - - global $wgGroupPermissions; - $old = $wgGroupPermissions; - $wgGroupPermissions = array(); - - $this->assertEquals( $check[$action][1], - self::$title->getUserPermissionsErrors( $action, self::$user, true ) ); - $wgGroupPermissions = $old; - - $this->setUserPerm( $action ); - $this->assertEquals( $check[$action][2], - self::$title->getUserPermissionsErrors( $action, self::$user, true ) ); - - $this->setUserPerm( $action ); - $this->assertEquals( $check[$action][3], - self::$title->userCan( $action, true ) ); - $this->assertEquals( $check[$action][3], - self::$title->quickUserCan( $action, false ) ); - - # count( User::getGroupsWithPermissions( $action ) ) < 1 - } - } - - function runGroupPermissions( $action, $result, $result2 = null ) { - global $wgGroupPermissions; - - if ( $result2 === null ) $result2 = $result; - - $wgGroupPermissions['autoconfirmed']['move'] = false; - $wgGroupPermissions['user']['move'] = false; - $res = self::$title->getUserPermissionsErrors( $action, self::$user ); - $this->assertEquals( $result, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = true; - $wgGroupPermissions['user']['move'] = false; - $res = self::$title->getUserPermissionsErrors( $action, self::$user ); - $this->assertEquals( $result2, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = true; - $wgGroupPermissions['user']['move'] = true; - $res = self::$title->getUserPermissionsErrors( $action, self::$user ); - $this->assertEquals( $result2, $res ); - - $wgGroupPermissions['autoconfirmed']['move'] = false; - $wgGroupPermissions['user']['move'] = true; - $res = self::$title->getUserPermissionsErrors( $action, self::$user ); - $this->assertEquals( $result2, $res ); - } - - function testPermissionHooks() { } - function testSpecialsAndNSPermissions() { - $this->setUser( self::$userName ); - global $wgUser, $wgContLang; - $wgUser = self::$user; - $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); - - $this->setTitle( NS_SPECIAL ); - - $this->assertEquals( array( array( 'badaccess-group0' ), array( 'ns-specialprotected' ) ), - self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); - $this->assertEquals( array( array( 'badaccess-groups', "*, [[$prefix:Administrators|Administrators]]", 2 ) ), - self::$title->getUserPermissionsErrors( 'createaccount', self::$user ) ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - self::$title->getUserPermissionsErrors( 'execute', self::$user ) ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( ), - self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); - - $this->setTitle( NS_MAIN ); - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); - - global $wgNamespaceProtection; - $wgNamespaceProtection[NS_USER] = array ( 'bogus' ); - $this->setTitle( NS_USER ); - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ), array( 'namespaceprotected', 'User' ) ), - self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); - - $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( array( 'protectedinterface' ) ), - self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); - - $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( array( 'protectedinterface' ) ), - self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); - - $wgNamespaceProtection = null; - $this->setUserPerm( 'bogus' ); - $this->assertEquals( array( ), - self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); - $this->assertEquals( true, - self::$title->userCan( 'bogus' ) ); - - $this->setUserPerm( '' ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); - $this->assertEquals( false, - self::$title->userCan( 'bogus' ) ); - } - - function testCSSandJSPermissions() { - $this->setUser( self::$userName ); - global $wgUser; - $wgUser = self::$user; - - $this->setTitle( NS_USER, self::$altUserName . '/test.js' ); - $this->runCSSandJSPermissions( - array( array( 'badaccess-group0' ), array( 'customcssjsprotected' ) ), - array( array( 'badaccess-group0' ), array( 'customcssjsprotected' ) ), - array( array( 'badaccess-group0' ) ) ); - - $this->setTitle( NS_USER, self::$altUserName . '/test.css' ); - $this->runCSSandJSPermissions( - array( array( 'badaccess-group0' ), array( 'customcssjsprotected' ) ), - array( array( 'badaccess-group0' ) ), - array( array( 'badaccess-group0' ), array( 'customcssjsprotected' ) ) ); - - $this->setTitle( NS_USER, self::$altUserName . '/tempo' ); - $this->runCSSandJSPermissions( - array( array( 'badaccess-group0' ) ), - array( array( 'badaccess-group0' ) ), - array( array( 'badaccess-group0' ) ) ); - } - - function runCSSandJSPermissions( $result0, $result1, $result2 ) { - $this->setUserPerm( '' ); - $this->assertEquals( $result0, - self::$title->getUserPermissionsErrors( 'bogus', - self::$user ) ); - - $this->setUserPerm( 'editusercss' ); - $this->assertEquals( $result1, - self::$title->getUserPermissionsErrors( 'bogus', - self::$user ) ); - - $this->setUserPerm( 'edituserjs' ); - $this->assertEquals( $result2, - self::$title->getUserPermissionsErrors( 'bogus', - self::$user ) ); - - $this->setUserPerm( 'editusercssjs' ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - self::$title->getUserPermissionsErrors( 'bogus', - self::$user ) ); - - $this->setUserPerm( array( 'edituserjs', 'editusercss' ) ); - $this->assertEquals( array( array( 'badaccess-group0' ) ), - self::$title->getUserPermissionsErrors( 'bogus', - self::$user ) ); - } - - function testPageRestrictions() { - global $wgUser, $wgContLang; - - $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); - - $wgUser = self::$user; - $this->setTitle( NS_MAIN ); - self::$title->mRestrictionsLoaded = true; - $this->setUserPerm( "edit" ); - self::$title->mRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $this->assertEquals( array( ), - self::$title->getUserPermissionsErrors( 'edit', - self::$user ) ); - - $this->assertEquals( true, - self::$title->quickUserCan( 'edit', false ) ); - self::$title->mRestrictions = array( "edit" => array( 'bogus', "sysop", "protect", "" ), - "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $this->assertEquals( array( array( 'badaccess-group0' ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - self::$title->getUserPermissionsErrors( 'bogus', - self::$user ) ); - $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - self::$title->getUserPermissionsErrors( 'edit', - self::$user ) ); - $this->setUserPerm( "" ); - $this->assertEquals( array( array( 'badaccess-group0' ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - self::$title->getUserPermissionsErrors( 'bogus', - self::$user ) ); - $this->assertEquals( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - self::$title->getUserPermissionsErrors( 'edit', - self::$user ) ); - $this->setUserPerm( array( "edit", "editprotected" ) ); - $this->assertEquals( array( array( 'badaccess-group0' ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - self::$title->getUserPermissionsErrors( 'bogus', - self::$user ) ); - $this->assertEquals( array( ), - self::$title->getUserPermissionsErrors( 'edit', - self::$user ) ); - self::$title->mCascadeRestriction = true; - $this->assertEquals( false, - self::$title->quickUserCan( 'bogus', false ) ); - $this->assertEquals( false, - self::$title->quickUserCan( 'edit', false ) ); - $this->assertEquals( array( array( 'badaccess-group0' ), - array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - self::$title->getUserPermissionsErrors( 'bogus', - self::$user ) ); - $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), - array( 'protectedpagetext', 'protect' ), - array( 'protectedpagetext', 'protect' ) ), - self::$title->getUserPermissionsErrors( 'edit', - self::$user ) ); - } - - function testCascadingSourcesRestrictions() { - global $wgUser; - $wgUser = self::$user; - $this->setTitle( NS_MAIN, "test page" ); - $this->setUserPerm( array( "edit", "bogus" ) ); - - self::$title->mCascadeSources = array( Title::makeTitle( NS_MAIN, "Bogus" ), Title::makeTitle( NS_MAIN, "UnBogus" ) ); - self::$title->mCascadingRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) ); - - $this->assertEquals( false, - self::$title->userCan( 'bogus' ) ); - $this->assertEquals( array( array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ), - array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ) ), - self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); - - $this->assertEquals( true, - self::$title->userCan( 'edit' ) ); - $this->assertEquals( array( ), - self::$title->getUserPermissionsErrors( 'edit', self::$user ) ); - - } - - function testActionPermissions() { - global $wgUser; - $wgUser = self::$user; - - $this->setUserPerm( array( "createpage" ) ); - $this->setTitle( NS_MAIN, "test page" ); - self::$title->mTitleProtection['pt_create_perm'] = ''; - self::$title->mTitleProtection['pt_user'] = self::$user->getID(); - self::$title->mTitleProtection['pt_expiry'] = Block::infinity(); - self::$title->mTitleProtection['pt_reason'] = 'test'; - self::$title->mCascadeRestriction = false; - - $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), - self::$title->getUserPermissionsErrors( 'create', self::$user ) ); - $this->assertEquals( false, - self::$title->userCan( 'create' ) ); - - self::$title->mTitleProtection['pt_create_perm'] = 'sysop'; - $this->setUserPerm( array( 'createpage', 'protect' ) ); - $this->assertEquals( array( ), - self::$title->getUserPermissionsErrors( 'create', self::$user ) ); - $this->assertEquals( true, - self::$title->userCan( 'create' ) ); - - - $this->setUserPerm( array( 'createpage' ) ); - $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), - self::$title->getUserPermissionsErrors( 'create', self::$user ) ); - $this->assertEquals( false, - self::$title->userCan( 'create' ) ); - - $this->setTitle( NS_MEDIA, "test page" ); - $this->setUserPerm( array( "move" ) ); - $this->assertEquals( false, - self::$title->userCan( 'move' ) ); - $this->assertEquals( array( array( 'immobile-source-namespace', 'Media' ) ), - self::$title->getUserPermissionsErrors( 'move', self::$user ) ); - - $this->setTitle( NS_MAIN, "test page" ); - $this->assertEquals( array( ), - self::$title->getUserPermissionsErrors( 'move', self::$user ) ); - $this->assertEquals( true, - self::$title->userCan( 'move' ) ); - - self::$title->mInterwiki = "no"; - $this->assertEquals( array( array( 'immobile-page' ) ), - self::$title->getUserPermissionsErrors( 'move', self::$user ) ); - $this->assertEquals( false, - self::$title->userCan( 'move' ) ); - - $this->setTitle( NS_MEDIA, "test page" ); - $this->assertEquals( false, - self::$title->userCan( 'move-target' ) ); - $this->assertEquals( array( array( 'immobile-target-namespace', 'Media' ) ), - self::$title->getUserPermissionsErrors( 'move-target', self::$user ) ); - - $this->setTitle( NS_MAIN, "test page" ); - $this->assertEquals( array( ), - self::$title->getUserPermissionsErrors( 'move-target', self::$user ) ); - $this->assertEquals( true, - self::$title->userCan( 'move-target' ) ); - - self::$title->mInterwiki = "no"; - $this->assertEquals( array( array( 'immobile-target-page' ) ), - self::$title->getUserPermissionsErrors( 'move-target', self::$user ) ); - $this->assertEquals( false, - self::$title->userCan( 'move-target' ) ); - - } - - function testUserBlock() { - global $wgUser, $wgEmailConfirmToEdit, $wgEmailAuthentication; - $wgEmailConfirmToEdit = true; - $wgEmailAuthentication = true; - $wgUser = self::$user; - - $this->setUserPerm( array( "createpage", "move" ) ); - $this->setTitle( NS_MAIN, "test page" ); - - # $short - $this->assertEquals( array( array( 'confirmedittext' ) ), - self::$title->getUserPermissionsErrors( 'move-target', self::$user ) ); - $this->assertEquals( true, self::$title->userCan( 'move-target' ) ); - - $wgEmailConfirmToEdit = false; - # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount' - $this->assertEquals( array( ), - self::$title->getUserPermissionsErrors( 'move-target', - self::$user ) ); - - global $wgLang; - $prev = time(); - $now = time() + 120; - self::$user->mBlockedby = self::$user->getId(); - self::$user->mBlock = new Block( '127.0.8.1', self::$user->getId(), self::$user->getId(), - 'no reason given', $prev + 3600, 1, 0 ); - self::$user->mBlock->mTimestamp = 0; - $this->assertEquals( array( array( 'autoblockedtext', - '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', - 'Useruser', 0, 'infinite', '127.0.8.1', - $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ) ), - self::$title->getUserPermissionsErrors( 'move-target', - self::$user ) ); - - $this->assertEquals( true, - self::$title->userCan( 'move-target', self::$user ) ); - - global $wgLocalTZoffset; - $wgLocalTZoffset = -60; - self::$user->mBlockedby = self::$user->getName(); - self::$user->mBlock = new Block( '127.0.8.1', 2, 1, 'no reason given', $now, 0, 10 ); - $this->assertEquals( array( array( 'blockedtext', - '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', - 'Useruser', 0, '23:00, 31 December 1969', '127.0.8.1', - $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ) ), - self::$title->getUserPermissionsErrors( 'move-target', self::$user ) ); - - # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this ) - # $user->blockedFor() == '' - # $user->mBlock->mExpiry == 'infinity' - } -} diff --git a/maintenance/tests/TitleTest.php b/maintenance/tests/TitleTest.php deleted file mode 100644 index 5b42c1c575..0000000000 --- a/maintenance/tests/TitleTest.php +++ /dev/null @@ -1,17 +0,0 @@ -|", $chr ) !== false || preg_match( "/[\\x00-\\x1f\\x7f]/", $chr ) ) { - $this->assertFalse( (bool)preg_match( "/[$titlechars]/", $chr ), "chr($num) = $chr is not a valid titlechar" ); - } else { - $this->assertTrue( (bool)preg_match( "/[$titlechars]/", $chr ), "chr($num) = $chr is a valid titlechar" ); - } - } - } -} diff --git a/maintenance/tests/UploadFromUrlTest.php b/maintenance/tests/UploadFromUrlTest.php deleted file mode 100644 index c2c244630b..0000000000 --- a/maintenance/tests/UploadFromUrlTest.php +++ /dev/null @@ -1,349 +0,0 @@ -exists() ) { - $this->deleteFile( 'UploadFromUrlTest.png' ); - } - } - - protected function doApiRequest( $params ) { - $sessionId = session_id(); - session_write_close(); - - $req = new FauxRequest( $params, true, $_SESSION ); - $module = new ApiMain( $req, true ); - $module->execute(); - - wfSetupSession( $sessionId ); - return array( $module->getResultData(), $req ); - } - - /** - * Ensure that the job queue is empty before continuing - */ - public function testClearQueue() { - while ( $job = Job::pop() ) { } - $this->assertFalse( $job ); - } - - /** - * @todo Document why we test login, since the $wgUser hack used doesn't - * require login - */ - public function testLogin() { - $data = $this->doApiRequest( array( - 'action' => 'login', - 'lgname' => self::$userName, - 'lgpassword' => self::$passWord ) ); - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "NeedToken", $data[0]['login']['result'] ); - $token = $data[0]['login']['token']; - - $data = $this->doApiRequest( array( - 'action' => 'login', - "lgtoken" => $token, - "lgname" => self::$userName, - "lgpassword" => self::$passWord ) ); - - $this->assertArrayHasKey( "login", $data[0] ); - $this->assertArrayHasKey( "result", $data[0]['login'] ); - $this->assertEquals( "Success", $data[0]['login']['result'] ); - $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testSetupUrlDownload( $data ) { - $token = self::$user->editToken(); - $exception = false; - - try { - $this->doApiRequest( array( - 'action' => 'upload', - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The token parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "One of the parameters sessionkey, file, url, statuskey is required", - $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://www.example.com/test.png', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "The filename parameter must be set", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - self::$user->removeGroup( 'sysop' ); - $exception = false; - try { - $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://www.example.com/test.png', - 'filename' => 'UploadFromUrlTest.png', - 'token' => $token, - ), $data ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( "Permission denied", $e->getMessage() ); - } - $this->assertTrue( $exception, "Got exception" ); - - self::$user->addGroup( '*' ); - self::$user->addGroup( 'sysop' ); - $exception = false; - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'filename' => 'UploadFromUrlTest.png', - 'token' => $token, - ), $data ); - - $this->assertEquals( $data[0]['upload']['result'], 'Queued', 'Queued upload' ); - - $job = Job::pop(); - $this->assertThat( $job, $this->isInstanceOf( 'UploadFromUrlJob' ), 'Queued upload inserted' ); - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testAsyncUpload( $data ) { - $token = self::$user->editToken(); - - self::$user->addGroup( 'users' ); - - $data = $this->doAsyncUpload( $token, true ); - $this->assertEquals( $data[0]['upload']['result'], 'Success' ); - $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' ); - $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testAsyncUploadWarning( $data ) { - $token = self::$user->editToken(); - - self::$user->addGroup( 'users' ); - - - $data = $this->doAsyncUpload( $token ); - - $this->assertEquals( $data[0]['upload']['result'], 'Warning' ); - $this->assertTrue( isset( $data[0]['upload']['sessionkey'] ) ); - - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'sessionkey' => $data[0]['upload']['sessionkey'], - 'filename' => 'UploadFromUrlTest.png', - 'ignorewarnings' => 1, - 'token' => $token, - ) ); - $this->assertEquals( $data[0]['upload']['result'], 'Success' ); - $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' ); - $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - /** - * @depends testLogin - * @depends testClearQueue - */ - public function testSyncDownload( $data ) { - $token = self::$user->editToken(); - - $job = Job::pop(); - $this->assertFalse( $job, 'Starting with an empty jobqueue' ); - - self::$user->addGroup( 'users' ); - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'ignorewarnings' => true, - 'token' => $token, - ), $data ); - - $job = Job::pop(); - $this->assertFalse( $job ); - - $this->assertEquals( 'Success', $data[0]['upload']['result'] ); - $this->deleteFile( 'UploadFromUrlTest.png' ); - - return $data; - } - - public function testLeaveMessage() { - $token = self::$user->editToken(); - - $talk = self::$user->getTalkPage(); - if ( $talk->exists() ) { - $a = new Article( $talk ); - $a->doDeleteArticle( '' ); - } - - $this->assertFalse( (bool)$talk->getArticleId( GAID_FOR_UPDATE ), 'User talk does not exist' ); - - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - 'leavemessage' => 1, - 'ignorewarnings' => 1, - ) ); - - $job = Job::pop(); - $job->run(); - - $this->assertTrue( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ); - $this->assertTrue( (bool)$talk->getArticleId( GAID_FOR_UPDATE ), 'User talk exists' ); - - $this->deleteFile( 'UploadFromUrlTest.png' ); - - $talkRev = Revision::newFromTitle( $talk ); - $talkSize = $talkRev->getSize(); - - $exception = false; - try { - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - 'leavemessage' => 1, - ) ); - } catch ( UsageException $e ) { - $exception = true; - $this->assertEquals( 'Using leavemessage without ignorewarnings is not supported', $e->getMessage() ); - } - $this->assertTrue( $exception ); - - $job = Job::pop(); - $this->assertFalse( $job ); - - return; - - // Broken until using leavemessage with ignorewarnings is supported - $job->run(); - - $this->assertFalse( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ); - - $talkRev = Revision::newFromTitle( $talk ); - $this->assertTrue( $talkRev->getSize() > $talkSize, 'New message left' ); - - - } - - /** - * Helper function to perform an async upload, execute the job and fetch - * the status - * - * @return array The result of action=upload&statuskey=key - */ - private function doAsyncUpload( $token, $ignoreWarnings = false, $leaveMessage = false ) { - $params = array( - 'action' => 'upload', - 'filename' => 'UploadFromUrlTest.png', - 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', - 'asyncdownload' => 1, - 'token' => $token, - ); - if ( $ignoreWarnings ) { - $params['ignorewarnings'] = 1; - } - if ( $leaveMessage ) { - $params['leavemessage'] = 1; - } - - $data = $this->doApiRequest( $params ); - $this->assertEquals( $data[0]['upload']['result'], 'Queued' ); - $this->assertTrue( isset( $data[0]['upload']['statuskey'] ) ); - $statusKey = $data[0]['upload']['statuskey']; - - $job = Job::pop(); - $this->assertEquals( 'UploadFromUrlJob', get_class( $job ) ); - - $status = $job->run(); - $this->assertTrue( $status ); - - $data = $this->doApiRequest( array( - 'action' => 'upload', - 'statuskey' => $statusKey, - 'token' => $token, - ) ); - - return $data; - } - - - /** - * - */ - protected function deleteFile( $name ) { - $t = Title::newFromText( $name, NS_FILE ); - $this->assertTrue($t->exists(), "File '$name' exists"); - - if ( $t->exists() ) { - $file = wfFindFile( $name, array( 'ignoreRedirect' => true ) ); - $empty = ""; - FileDeleteForm::doDelete( $t, $file, $empty, "none", true ); - $a = new Article ( $t ); - $a->doDeleteArticle( "testing" ); - } - $t = Title::newFromText( $name, NS_FILE ); - - $this->assertFalse($t->exists(), "File '$name' was deleted"); - } - } diff --git a/maintenance/tests/UploadFromUrlTestSuite.php b/maintenance/tests/UploadFromUrlTestSuite.php deleted file mode 100644 index 5966a6ebf7..0000000000 --- a/maintenance/tests/UploadFromUrlTestSuite.php +++ /dev/null @@ -1,179 +0,0 @@ - 'LocalRepo', - 'name' => 'local', - 'directory' => wfTempDir() . '/test-repo', - 'url' => 'http://example.com/images', - 'deletedDir' => wfTempDir() . '/test-repo/delete', - 'hashLevels' => 2, - 'transformVia404' => false, - ); - $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; - $wgNamespaceAliases['Image'] = NS_FILE; - $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; - - - $wgEnableParserCache = false; - $wgDeferredUpdateList = array(); - $wgMemc =& wfGetMainCache(); - $messageMemc =& wfGetMessageCacheStorage(); - $parserMemc =& wfGetParserCacheStorage(); - - // $wgContLang = new StubContLang; - $wgUser = new User; - $wgLang = new StubUserLang; - $wgOut = new StubObject( 'wgOut', 'OutputPage' ); - $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) ); - $wgRequest = new WebRequest; - - $wgMessageCache = new StubObject( 'wgMessageCache', 'MessageCache', - array( $messageMemc, $wgUseDatabaseMessages, - $wgMsgCacheExpiry ) ); - if ( $wgStyleDirectory === false ) { - $wgStyleDirectory = "$IP/skins"; - } - - } - - public function tearDown() { - $this->teardownUploadDir( $this->uploadDir ); - } - - private $uploadDir; - private $keepUploads; - - /** - * Remove the dummy uploads directory - */ - private function teardownUploadDir( $dir ) { - if ( $this->keepUploads ) { - return; - } - - // delete the files first, then the dirs. - self::deleteFiles( - array ( - "$dir/3/3a/Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg", - "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg", - - "$dir/0/09/Bad.jpg", - ) - ); - - self::deleteDirs( - array ( - "$dir/3/3a", - "$dir/3", - "$dir/thumb/6/65", - "$dir/thumb/6", - "$dir/thumb/3/3a/Foobar.jpg", - "$dir/thumb/3/3a", - "$dir/thumb/3", - - "$dir/0/09/", - "$dir/0/", - - "$dir/thumb", - "$dir", - ) - ); - } - - /** - * Delete the specified files, if they exist. - * - * @param $files Array: full paths to files to delete. - */ - private static function deleteFiles( $files ) { - foreach ( $files as $file ) { - if ( file_exists( $file ) ) { - unlink( $file ); - } - } - } - - /** - * Delete the specified directories, if they exist. Must be empty. - * - * @param $dirs Array: full paths to directories to delete. - */ - private static function deleteDirs( $dirs ) { - foreach ( $dirs as $dir ) { - if ( is_dir( $dir ) ) { - rmdir( $dir ); - } - } - } - - /** - * Create a dummy uploads directory which will contain a couple - * of files in order to pass existence tests. - * - * @return String: the directory - */ - private function setupUploadDir() { - global $IP; - - if ( $this->keepUploads ) { - $dir = wfTempDir() . '/mwParser-images'; - - if ( is_dir( $dir ) ) { - return $dir; - } - } else { - $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; - } - - wfDebug( "Creating upload directory $dir\n" ); - - if ( file_exists( $dir ) ) { - wfDebug( "Already exists!\n" ); - return $dir; - } - - wfMkdirParents( $dir . '/3/3a' ); - copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); - - wfMkdirParents( $dir . '/0/09' ); - copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" ); - - return $dir; - } - - public static function suite() { - // Hack to invoke the autoloader required to get phpunit to recognize - // the UploadFromUrlTest class - class_exists( 'UploadFromUrlTest' ); - $suite = new UploadFromUrlTestSuite( 'UploadFromUrlTest' ); - return $suite; - } -} diff --git a/maintenance/tests/UploadTest.php b/maintenance/tests/UploadTest.php deleted file mode 100644 index 41c9d80d56..0000000000 --- a/maintenance/tests/UploadTest.php +++ /dev/null @@ -1,90 +0,0 @@ -upload = new UploadTestHandler; - } - - /** - * Test various forms of valid and invalid titles that can be supplied. - */ - public function testTitleValidation() { - - - /* Test a valid title */ - $this->assertUploadTitleAndCode( 'ValidTitle.jpg', - 'ValidTitle.jpg', UploadTestHandler::OK, - 'upload valid title' ); - - /* A title with a slash */ - $this->assertUploadTitleAndCode( 'A/B.jpg', - 'B.jpg', UploadTestHandler::OK, - 'upload title with slash' ); - - /* A title with illegal char */ - $this->assertUploadTitleAndCode( 'A:B.jpg', - 'A-B.jpg', UploadTestHandler::OK, - 'upload title with colon' ); - - /* A title without extension */ - $this->assertUploadTitleAndCode( 'A', - null, UploadTestHandler::FILETYPE_MISSING, - 'upload title without extension' ); - - /* A title with no basename */ - $this->assertUploadTitleAndCode( '.jpg', - null, UploadTestHandler::MIN_LENGTH_PARTNAME, - 'upload title without basename' ); - - } - /** - * Helper function for testTitleValidation. First checks the return code - * of UploadBase::getTitle() and then the actual returned titl - */ - private function assertUploadTitleAndCode( $srcFilename, $dstFilename, $code, $msg ) { - /* Check the result code */ - $this->assertEquals( $code, - $this->upload->testTitleValidation( $srcFilename ), - "$msg code" ); - - /* If we expect a valid title, check the title itself. */ - if ( $code == UploadTestHandler::OK ) { - $this->assertEquals( $dstFilename, - $this->upload->getTitle()->getText(), - "$msg text" ); - } - } - - /** - * Test the upload verification functions - */ - public function testVerifyUpload() { - /* Setup with zero file size */ - $this->upload->initializePathInfo( '', '', 0 ); - $result = $this->upload->verifyUpload(); - $this->assertEquals( UploadTestHandler::EMPTY_FILE, - $result['status'], - 'upload empty file' ); - } - -} - -class UploadTestHandler extends UploadBase { - public function initializeFromRequest( &$request ) { } - public function testTitleValidation( $name ) { - $this->mTitle = false; - $this->mDesiredDestName = $name; - $this->getTitle(); - return $this->mTitleError; - } - - -} diff --git a/maintenance/tests/XmlTest.php b/maintenance/tests/XmlTest.php deleted file mode 100644 index 330e60c677..0000000000 --- a/maintenance/tests/XmlTest.php +++ /dev/null @@ -1,115 +0,0 @@ -assertEquals( - '', - Xml::element( 'element', null, null ), - 'Opening element with no attributes' - ); - } - - function testElementEmpty() { - $this->assertEquals( - '', - Xml::element( 'element', null, '' ), - 'Terminated empty element' - ); - } - - function testElementEscaping() { - $this->assertEquals( - 'hello <there> you & you', - Xml::element( 'element', null, 'hello you & you' ), - 'Element with no attributes and content that needs escaping' - ); - } - - function testElementAttributes() { - $this->assertEquals( - '="<>">', - Xml::element( 'element', array( 'key' => 'value', '<>' => '<>' ), null ), - 'Element attributes, keys are not escaped' - ); - } - - function testOpenElement() { - $this->assertEquals( - '', - Xml::openElement( 'element', array( 'k' => 'v' ) ), - 'openElement() shortcut' - ); - } - - function testCloseElement() { - $this->assertEquals( '', Xml::closeElement( 'element' ), 'closeElement() shortcut' ); - } - - # - # textarea - # - function testTextareaNoContent() { - $this->assertEquals( - '', - Xml::textarea( 'name', '' ), - 'textarea() with not content' - ); - } - - function testTextareaAttribs() { - $this->assertEquals( - '', - Xml::textarea( 'name', '', 20, 10 ), - 'textarea() with custom attribs' - ); - } - - # - # JS - # - function testEscapeJsStringSpecialChars() { - $this->assertEquals( - '\\\\\r\n', - Xml::escapeJsString( "\\\r\n" ), - 'escapeJsString() with special characters' - ); - } - - function testEncodeJsVarBoolean() { - $this->assertEquals( - 'true', - Xml::encodeJsVar( true ), - 'encodeJsVar() with boolean' - ); - } - - function testEncodeJsVarNull() { - $this->assertEquals( - 'null', - Xml::encodeJsVar( null ), - 'encodeJsVar() with null' - ); - } - - function testEncodeJsVarArray() { - $this->assertEquals( - '["a", 1]', - Xml::encodeJsVar( array( 'a', 1 ) ), - 'encodeJsVar() with array' - ); - $this->assertEquals( - '{"a": "a", "b": 1}', - Xml::encodeJsVar( array( 'a' => 'a', 'b' => 1 ) ), - 'encodeJsVar() with associative array' - ); - } - - function testEncodeJsVarObject() { - $this->assertEquals( - '{"a": "a", "b": 1}', - Xml::encodeJsVar( (object)array( 'a' => 'a', 'b' => 1 ) ), - 'encodeJsVar() with object' - ); - } -} diff --git a/maintenance/tests/bootstrap.php b/maintenance/tests/bootstrap.php deleted file mode 100644 index 231413cce7..0000000000 --- a/maintenance/tests/bootstrap.php +++ /dev/null @@ -1,6 +0,0 @@ -= 3.5 - require_once 'PHPUnit/Autoload.php'; -} else { - // Works for PHPUnit < 3.5 - require_once 'PHPUnit/TextUI/Command.php'; -} -define( 'MW_PHPUNIT_TEST', 1 ); - -$wgLocaltimezone = 'UTC'; - -/* Tests were failing with sqlite */ -global $wgCaches; -$wgCaches[CACHE_DB] = false; - -if ( !version_compare( PHPUnit_Runner_Version::id(), "3.4.1", ">" ) ) { - echo <<options[1] ) ) { - $files = $this->options[1]; - } else { - require( dirname( __FILE__ ) . '/TestFileList.php' ); - $files = $testFiles; - wfRunHooks( 'UnitTestsList', array( &$files ) ); - } - foreach ( $files as $file ) { - $suite->addTestFile( $file ); - } - $suite->setName( 'MediaWiki test suite' ); - $this->arguments['test'] = $suite; - } -} - -$command = new MWPHPUnitCommand; -$command->run( $argv ); - diff --git a/maintenance/tests/phpunit.xml b/maintenance/tests/phpunit.xml deleted file mode 100644 index d7eeda4837..0000000000 --- a/maintenance/tests/phpunit.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - Broken - Stub - - - diff --git a/maintenance/tests/phpunit/Makefile b/maintenance/tests/phpunit/Makefile new file mode 100644 index 0000000000..ddad378cdf --- /dev/null +++ b/maintenance/tests/phpunit/Makefile @@ -0,0 +1,16 @@ +.PHONY: help test phpunit install + +all test: phpunit + +phpunit: + phpunit --configuration suite.xml + +install: + pear channel-discover pear.phpunit.de + pear install phpunit/PHPUnit + +help: + # Targets: + # phpunit (default) Run all the tests with phpunit + # install Install PHPUnit from phpunit.de + # help You're looking at it! \ No newline at end of file diff --git a/maintenance/tests/phpunit/README b/maintenance/tests/phpunit/README new file mode 100644 index 0000000000..cdd6a83729 --- /dev/null +++ b/maintenance/tests/phpunit/README @@ -0,0 +1,29 @@ +== MediaWiki PHPUnit Tests == + +Some quickie unit tests done with the PHPUnit testing framework. To run the +test suite, run 'make test' in this (maintenance/tests/phpunit) directory. + +=== Installation === + +PHPUnit is no longer maintained by PEAR. To get the current version of +PHPUnit, first uninstall any old version of PHPUnit or PHPUnit2 from PEAR, +then install the current version from phpunit.de like this: + + pear channel-discover pear.phpunit.de + pear install phpunit/PHPUnit + +You also may wish to install this via your normal package mechanism: + + aptitude install phpunit +- or - + yum install phpunit + +=== Notes === + +* Label currently broken tests in the group Broken and they will not be run +by phpunit. You can add them to the group by putting the following comment at +the top of the file: + /** + * @group Broken + */ +* Need to fix some broken tests \ No newline at end of file diff --git a/maintenance/tests/phpunit/TODO b/maintenance/tests/phpunit/TODO new file mode 100644 index 0000000000..774b5a633a --- /dev/null +++ b/maintenance/tests/phpunit/TODO @@ -0,0 +1,11 @@ +== Things To Do == + +* Most of the tests are named poorly; naming should describe a use case in story-like language, not simply identify the +unit under test. An example would be the difference between testCalculate and testAddingIntegersTogetherWorks. +* Many of the tests make multiple assertions, and are thus not unitary tests. By using data-providers and more use-case +oriented test selection nearly all of these cases can be easily resolved. +* Some of the test files are either incorrectly named or in the wrong folder. Tests should be organized in a mirrored +structure to the source they are testing, and named the same, with the exception of the word "Test" at the end. +* Shared set-up code or base classes are present, but usually named improperly or appear to be poorly factored. Support +code should share as much of the same naming as the code it's supporting, and test and test-case depenencies should be +considered to resolve other shared needs. \ No newline at end of file diff --git a/maintenance/tests/phpunit/bootstrap.php b/maintenance/tests/phpunit/bootstrap.php new file mode 100644 index 0000000000..0e608b52e6 --- /dev/null +++ b/maintenance/tests/phpunit/bootstrap.php @@ -0,0 +1,76 @@ +" ) ) { + echo <<tableName( $table ); + if ( $db->getType() == 'oracle' ) { + $wgDBprefix = 'pt_'; + } else { + $wgDBprefix = 'parsertest_'; + } + + $db->tablePrefix( $wgDBprefix ); + + if ( $db->isOpen() ) { + foreach ( $tables as $tbl ) { + $newTableName = $db->tableName( $tbl ); + $tableName = $oldTableNames[$tbl]; + $db->query( "DROP TABLE IF EXISTS $newTableName", __METHOD__ ); + $db->duplicateTableStructure( $tableName, $newTableName, __METHOD__ ); + } + return $db; + } else { + // Something amiss + return null; + } + } +} \ No newline at end of file diff --git a/maintenance/tests/phpunit/includes/CdbTest.php b/maintenance/tests/phpunit/includes/CdbTest.php new file mode 100644 index 0000000000..8b7afd56ae --- /dev/null +++ b/maintenance/tests/phpunit/includes/CdbTest.php @@ -0,0 +1,84 @@ +markTestIncomplete( 'This test requires native CDB support to be present.' ); + } + } + + public function testCdb() { + $dir = wfTempDir(); + if ( !is_writable( $dir ) ) { + $this->markTestSkipped( "Temp dir isn't writable" ); + } + + $w1 = new CdbWriter_PHP( "$dir/php.cdb" ); + $w2 = new CdbWriter_DBA( "$dir/dba.cdb" ); + + $data = array(); + for ( $i = 0; $i < 1000; $i++ ) { + $key = $this->randomString(); + $value = $this->randomString(); + $w1->set( $key, $value ); + $w2->set( $key, $value ); + + if ( !isset( $data[$key] ) ) { + $data[$key] = $value; + } + } + + $w1->close(); + $w2->close(); + + $this->assertEquals( + md5_file( "$dir/dba.cdb" ), + md5_file( "$dir/php.cdb" ), + 'same hash' + ); + + $r1 = new CdbReader_PHP( "$dir/php.cdb" ); + $r2 = new CdbReader_DBA( "$dir/dba.cdb" ); + + foreach ( $data as $key => $value ) { + if ( $key === '' ) { + // Known bug + continue; + } + $v1 = $r1->get( $key ); + $v2 = $r2->get( $key ); + + $v1 = $v1 === false ? '(not found)' : $v1; + $v2 = $v2 === false ? '(not found)' : $v2; + + # cdbAssert( 'Mismatch', $key, $v1, $v2 ); + $this->cdbAssert( "PHP error", $key, $v1, $value ); + $this->cdbAssert( "DBA error", $key, $v2, $value ); + } + + unlink( "$dir/dba.cdb" ); + unlink( "$dir/php.cdb" ); + } + + private function randomString() { + $len = mt_rand( 0, 10 ); + $s = ''; + for ( $j = 0; $j < $len; $j++ ) { + $s .= chr( mt_rand( 0, 255 ) ); + } + return $s; + } + + private function cdbAssert( $msg, $key, $v1, $v2 ) { + $this->assertEquals( + $v2, + $v1, + $msg . ', k=' . bin2hex( $key ) + ); + } +} diff --git a/maintenance/tests/phpunit/includes/ExtraParserTest.php b/maintenance/tests/phpunit/includes/ExtraParserTest.php new file mode 100644 index 0000000000..a772d31e37 --- /dev/null +++ b/maintenance/tests/phpunit/includes/ExtraParserTest.php @@ -0,0 +1,30 @@ +assertEquals( "

$longLine

", + $parser->parse( $longLine, $t, $options )->getText() ); + } + } diff --git a/maintenance/tests/phpunit/includes/GlobalTest.php b/maintenance/tests/phpunit/includes/GlobalTest.php new file mode 100644 index 0000000000..8dc666070e --- /dev/null +++ b/maintenance/tests/phpunit/includes/GlobalTest.php @@ -0,0 +1,212 @@ +originals['wgReadOnlyFile'] = $wgReadOnlyFile; + $wgReadOnlyFile = tempnam( wfTempDir(), "mwtest_readonly" ); + unlink( $wgReadOnlyFile ); + } + + function tearDown() { + global $wgReadOnlyFile; + if ( file_exists( $wgReadOnlyFile ) ) { + unlink( $wgReadOnlyFile ); + } + $wgReadOnlyFile = $this->originals['wgReadOnlyFile']; + } + + function testRandom() { + # This could hypothetically fail, but it shouldn't ;) + $this->assertFalse( + wfRandom() == wfRandom() ); + } + + function testUrlencode() { + $this->assertEquals( + "%E7%89%B9%E5%88%A5:Contributions/Foobar", + wfUrlencode( "\xE7\x89\xB9\xE5\x88\xA5:Contributions/Foobar" ) ); + } + + function testReadOnlyEmpty() { + global $wgReadOnly; + $wgReadOnly = null; + + $this->assertFalse( wfReadOnly() ); + $this->assertFalse( wfReadOnly() ); + } + + function testReadOnlySet() { + global $wgReadOnly, $wgReadOnlyFile; + + $f = fopen( $wgReadOnlyFile, "wt" ); + fwrite( $f, 'Message' ); + fclose( $f ); + $wgReadOnly = null; + + $this->assertTrue( wfReadOnly() ); + $this->assertTrue( wfReadOnly() ); + + unlink( $wgReadOnlyFile ); + $wgReadOnly = null; + + $this->assertFalse( wfReadOnly() ); + $this->assertFalse( wfReadOnly() ); + } + + function testQuotedPrintable() { + $this->assertEquals( + "=?UTF-8?Q?=C4=88u=20legebla=3F?=", + wfQuotedPrintable( "\xc4\x88u legebla?", "UTF-8" ) ); + } + + function testTime() { + $start = wfTime(); + $this->assertType( 'float', $start ); + $end = wfTime(); + $this->assertTrue( $end > $start, "Time is running backwards!" ); + } + + function testArrayToCGI() { + $this->assertEquals( + "baz=AT%26T&foo=bar", + wfArrayToCGI( + array( 'baz' => 'AT&T', 'ignore' => '' ), + array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) ); + } + + function testMimeTypeMatch() { + $this->assertEquals( + 'text/html', + mimeTypeMatch( 'text/html', + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.7, + 'text/plain' => 0.3 ) ) ); + $this->assertEquals( + 'text/*', + mimeTypeMatch( 'text/html', + array( 'image/*' => 1.0, + 'text/*' => 0.5 ) ) ); + $this->assertEquals( + '*/*', + mimeTypeMatch( 'text/html', + array( '*/*' => 1.0 ) ) ); + $this->assertNull( + mimeTypeMatch( 'text/html', + array( 'image/png' => 1.0, + 'image/svg+xml' => 0.5 ) ) ); + } + + function testNegotiateType() { + $this->assertEquals( + 'text/html', + wfNegotiateType( + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.7, + 'text/plain' => 0.5, + 'text/*' => 0.2 ), + array( 'text/html' => 1.0 ) ) ); + $this->assertEquals( + 'application/xhtml+xml', + wfNegotiateType( + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.7, + 'text/plain' => 0.5, + 'text/*' => 0.2 ), + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.5 ) ) ); + $this->assertEquals( + 'text/html', + wfNegotiateType( + array( 'text/html' => 1.0, + 'text/plain' => 0.5, + 'text/*' => 0.5, + 'application/xhtml+xml' => 0.2 ), + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.5 ) ) ); + $this->assertEquals( + 'text/html', + wfNegotiateType( + array( 'text/*' => 1.0, + 'image/*' => 0.7, + '*/*' => 0.3 ), + array( 'application/xhtml+xml' => 1.0, + 'text/html' => 0.5 ) ) ); + $this->assertNull( + wfNegotiateType( + array( 'text/*' => 1.0 ), + array( 'application/xhtml+xml' => 1.0 ) ) ); + } + + function testTimestamp() { + $t = gmmktime( 12, 34, 56, 1, 15, 2001 ); + $this->assertEquals( + '20010115123456', + wfTimestamp( TS_MW, $t ), + 'TS_UNIX to TS_MW' ); + $this->assertEquals( + 979562096, + wfTimestamp( TS_UNIX, $t ), + 'TS_UNIX to TS_UNIX' ); + $this->assertEquals( + '2001-01-15 12:34:56', + wfTimestamp( TS_DB, $t ), + 'TS_UNIX to TS_DB' ); + + $this->assertEquals( + '20010115123456', + wfTimestamp( TS_MW, '20010115123456' ), + 'TS_MW to TS_MW' ); + $this->assertEquals( + 979562096, + wfTimestamp( TS_UNIX, '20010115123456' ), + 'TS_MW to TS_UNIX' ); + $this->assertEquals( + '2001-01-15 12:34:56', + wfTimestamp( TS_DB, '20010115123456' ), + 'TS_MW to TS_DB' ); + + $this->assertEquals( + '20010115123456', + wfTimestamp( TS_MW, '2001-01-15 12:34:56' ), + 'TS_DB to TS_MW' ); + $this->assertEquals( + 979562096, + wfTimestamp( TS_UNIX, '2001-01-15 12:34:56' ), + 'TS_DB to TS_UNIX' ); + $this->assertEquals( + '2001-01-15 12:34:56', + wfTimestamp( TS_DB, '2001-01-15 12:34:56' ), + 'TS_DB to TS_DB' ); + } + + function testBasename() { + $sets = array( + '' => '', + '/' => '', + '\\' => '', + '//' => '', + '\\\\' => '', + 'a' => 'a', + 'aaaa' => 'aaaa', + '/a' => 'a', + '\\a' => 'a', + '/aaaa' => 'aaaa', + '\\aaaa' => 'aaaa', + '/aaaa/' => 'aaaa', + '\\aaaa\\' => 'aaaa', + '\\aaaa\\' => 'aaaa', + '/mnt/upload3/wikipedia/en/thumb/8/8b/Zork_Grand_Inquisitor_box_cover.jpg/93px-Zork_Grand_Inquisitor_box_cover.jpg' => '93px-Zork_Grand_Inquisitor_box_cover.jpg', + 'C:\\Progra~1\\Wikime~1\\Wikipe~1\\VIEWER.EXE' => 'VIEWER.EXE', + 'Östergötland_coat_of_arms.png' => 'Östergötland_coat_of_arms.png', + ); + foreach ( $sets as $from => $to ) { + $this->assertEquals( $to, wfBaseName( $from ), + "wfBaseName('$from') => '$to'" ); + } + } + + /* TODO: many more! */ +} + + diff --git a/maintenance/tests/phpunit/includes/HttpTest.php b/maintenance/tests/phpunit/includes/HttpTest.php new file mode 100644 index 0000000000..022fa48876 --- /dev/null +++ b/maintenance/tests/phpunit/includes/HttpTest.php @@ -0,0 +1,567 @@ + "review=test" ); + + function setup() { + putenv( "http_proxy" ); /* Remove any proxy env var, so curl doesn't get confused */ + if ( is_array( self::$content ) ) { + return; + } + self::$has_curl = function_exists( 'curl_init' ); + self::$has_fopen = wfIniGetBool( 'allow_url_fopen' ); + + if ( !file_exists( "/usr/bin/curl" ) ) { + $this->markTestIncomplete( "This test requires the curl binary at /usr/bin/curl. If you have curl, please file a bug on this test, or, better yet, provide a patch." ); + } + + $content = tempnam( wfTempDir(), "" ); + $headers = tempnam( wfTempDir(), "" ); + if ( !$content && !$headers ) { + die( "Couldn't create temp file!" ); + } + + // This probably isn't the best test for a proxy, but it works on my system! + system( "curl -0 -o $content -s " . self::$proxy ); + $out = file_get_contents( $content ); + if ( $out ) { + self::$has_proxy = true; + } + + /* Maybe use wget instead of curl here ... just to use a different codebase? */ + foreach ( $this->test_geturl as $u ) { + system( "curl -0 -s -D $headers '$u' -o $content" ); + self::$content["GET $u"] = file_get_contents( $content ); + self::$headers["GET $u"] = file_get_contents( $headers ); + } + foreach ( $this->test_requesturl as $u ) { + system( "curl -0 -s -X POST -H 'Content-Length: 0' -D $headers '$u' -o $content" ); + self::$content["POST $u"] = file_get_contents( $content ); + self::$headers["POST $u"] = file_get_contents( $headers ); + } + foreach ( $this->test_posturl as $u => $postData ) { + system( "curl -0 -s -X POST -d '$postData' -D $headers '$u' -o $content" ); + self::$content["POST $u => $postData"] = file_get_contents( $content ); + self::$headers["POST $u => $postData"] = file_get_contents( $headers ); + } + unlink( $content ); + unlink( $headers ); + } + + + function testInstantiation() { + Http::$httpEngine = false; + + $r = HttpRequest::factory( "http://www.example.com/" ); + if ( self::$has_curl ) { + $this->assertThat( $r, $this->isInstanceOf( 'CurlHttpRequest' ) ); + } else { + $this->assertThat( $r, $this->isInstanceOf( 'PhpHttpRequest' ) ); + } + unset( $r ); + + if ( !self::$has_fopen ) { + $this->setExpectedException( 'MWException' ); + } + Http::$httpEngine = 'php'; + $r = HttpRequest::factory( "http://www.example.com/" ); + $this->assertThat( $r, $this->isInstanceOf( 'PhpHttpRequest' ) ); + unset( $r ); + + if ( !self::$has_curl ) { + $this->setExpectedException( 'MWException' ); + } + Http::$httpEngine = 'curl'; + $r = HttpRequest::factory( "http://www.example.com/" ); + if ( self::$has_curl ) { + $this->assertThat( $r, $this->isInstanceOf( 'CurlHttpRequest' ) ); + } + } + + function runHTTPFailureChecks() { + // Each of the following requests should result in a failure. + + $timeout = 1; + $start_time = time(); + $r = Http::get( "http://www.example.com:1/", $timeout ); + $end_time = time(); + $this->assertLessThan( $timeout + 2, $end_time - $start_time, + "Request took less than {$timeout}s via " . Http::$httpEngine ); + $this->assertEquals( $r, false, "false -- what we get on error from Http::get()" ); + + $r = Http::get( "http://www.example.com/this-file-does-not-exist", $timeout ); + $this->assertFalse( $r, "False on 404s" ); + + + $r = HttpRequest::factory( "http://www.example.com/this-file-does-not-exist" ); + $er = $r->execute(); + if ( is_a( $r, 'PhpHttpRequest' ) && version_compare( '5.2.10', phpversion(), '>' ) ) { + $this->assertRegexp( "/HTTP request failed/", $er->getWikiText() ); + } else { + $this->assertRegexp( "/404 Not Found/", $er->getWikiText() ); + } + } + + function testFailureDefault() { + Http::$httpEngine = false; + $this->runHTTPFailureChecks(); + } + + function testFailurePhp() { + if ( !self::$has_fopen ) { + $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); + } + + Http::$httpEngine = "php"; + $this->runHTTPFailureChecks(); + } + + function testFailureCurl() { + if ( !self::$has_curl ) { + $this->markTestIncomplete( "This test requires curl." ); + } + + Http::$httpEngine = "curl"; + $this->runHTTPFailureChecks(); + } + + /* ./phase3/includes/Import.php:1108: $data = Http::request( $method, $url ); */ + /* ./includes/Import.php:1124: $link = Title::newFromText( "$interwiki:Special:Export/$page" ); */ + /* ./includes/Import.php:1134: return ImportStreamSource::newFromURL( $url, "POST" ); */ + function runHTTPRequests( $proxy = null ) { + $opt = array(); + + if ( $proxy ) { + $opt['proxy'] = $proxy; + } elseif ( $proxy === false ) { + $opt['noProxy'] = true; + } + + /* no postData here because the only request I could find in code so far didn't have any */ + foreach ( $this->test_requesturl as $u ) { + $r = Http::request( "POST", $u, $opt ); + $this->assertEquals( self::$content["POST $u"], "$r", "POST $u with " . Http::$httpEngine ); + } + } + + function testRequestDefault() { + Http::$httpEngine = false; + $this->runHTTPRequests(); + } + + function testRequestPhp() { + if ( !self::$has_fopen ) { + $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); + } + + Http::$httpEngine = "php"; + $this->runHTTPRequests(); + } + + function testRequestCurl() { + if ( !self::$has_curl ) { + $this->markTestIncomplete( "This test requires curl." ); + } + + Http::$httpEngine = "curl"; + $this->runHTTPRequests(); + } + + /* ./extensions/SpamBlacklist/SpamBlacklist_body.php:164: $httpText = Http::get( $fileName ); */ + /* ./extensions/ApiSVGProxy/ApiSVGProxy.body.php:44: $contents = Http::get( $file->getFullUrl() ); */ + /* ./extensions/BookInformation/drivers/IsbnDb.php:24: if( ( $xml = Http::get( $uri ) ) !== false ) { */ + /* ./extensions/BookInformation/drivers/Amazon.php:23: if( ( $xml = Http::get( $uri ) ) !== false ) { */ + /* ./extensions/TitleBlacklist/TitleBlacklist.list.php:217: $result = Http::get( $url ); */ + /* ./extensions/TSPoll/TSPoll.php:68: $get_server = Http::get( 'http://toolserver.org/~jan/poll/dev/main.php?page=wiki_output&id='.$id ); */ + /* ./extensions/TSPoll/TSPoll.php:70: $get_server = Http::get( 'http://toolserver.org/~jan/poll/main.php?page=wiki_output&id='.$id ); */ + /* ./extensions/DoubleWiki/DoubleWiki.php:56: $translation = Http::get( $url.$sep.'action=render' ); */ + /* ./extensions/ExternalPages/ExternalPages_body.php:177: $serializedText = Http::get( $this->mPageURL ); */ + /* ./extensions/Translate/utils/TranslationHelpers.php:143: $suggestions = Http::get( $url, $timeout ); */ + /* ./extensions/Translate/SpecialImportTranslations.php:169: $filedata = Http::get( $url ); ; */ + /* ./extensions/Translate/TranslateEditAddons.php:338: $suggestions = Http::get( $url, $timeout ); */ + /* ./extensions/SecurePoll/includes/user/Auth.php:283: $value = Http::get( $url, 20, $curlParams ); */ + /* ./extensions/DumpHTML/dumpHTML.inc:778: $contents = Http::get( $url ); */ + /* ./extensions/DumpHTML/dumpHTML.inc:1298: $contents = Http::get( $sourceUrl ); */ + /* ./extensions/DumpHTML/dumpHTML.inc:1373: $contents = Http::get( $sourceUrl ); */ + /* ./phase3/maintenance/rebuildInterwiki.inc:101: $intermap = Http::get( 'http://meta.wikimedia.org/w/index.php?title=Interwiki_map&action=raw', 30 ); */ + /* ./phase3/maintenance/findhooks.php:98: $allhookdata = Http::get( 'http://www.mediawiki.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:MediaWiki_hooks&cmlimit=500&format=php' ); */ + /* ./phase3/maintenance/findhooks.php:109: $oldhookdata = Http::get( 'http://www.mediawiki.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Removed_hooks&cmlimit=500&format=php' ); */ + /* ./phase3/maintenance/dumpInterwiki.inc:95: $intermap = Http::get( 'http://meta.wikimedia.org/w/index.php?title=Interwiki_map&action=raw', 30 ); */ + /* ./phase3/includes/parser/Parser.php:3204: $text = Http::get($url); */ + /* ./phase3/includes/filerepo/ForeignAPIRepo.php:131: $data = Http::get( $url ); */ + /* ./phase3/includes/filerepo/ForeignAPIRepo.php:205: $thumb = Http::get( $foreignUrl ); */ + /* ./phase3/includes/filerepo/File.php:1105: $res = Http::get( $renderUrl ); */ + /* ./phase3/includes/GlobalFunctions.php:2760: * @deprecated Use Http::get() instead */ + /* ./phase3/includes/GlobalFunctions.php:2764: return Http::get( $url ); */ + /* ./phase3/includes/ExternalStoreHttp.php:18: $ret = Http::get( $url ); */ + /* ./phase3/includes/Import.php:357: $data = Http::get( $src ); */ + /* ./extensions/ExternalData/ED_Utils.php:291: return Http::get( $url, 'default', array(CURLOPT_SSL_VERIFYPEER => false) ); */ + /* ./extensions/ExternalData/ED_Utils.php:293: return Http::get( $url ); */ + /* ./extensions/ExternalData/ED_Utils.php:306: $page = Http::get( $url, 'default', array(CURLOPT_SSL_VERIFYPEER => false) ); */ + /* ./extensions/ExternalData/ED_Utils.php:308: $page = Http::get( $url ); */ + /* ./extensions/CodeReview/backend/Subversion.php:320: $blob = Http::get( $target, $this->mTimeout ); */ + /* ./extensions/AmazonPlus/AmazonPlus.php:214: $this->response = Http::get( $urlstr ); */ + /* ./extensions/StaticWiki/StaticWiki.php:24: $text = Http::get( $url ) ; */ + /* ./extensions/StaticWiki/StaticWiki.php:64: $history = Http::get ( $wgStaticWikiExternalSite . "index.php?title=" . urlencode ( $url_title ) . "&action=history" ) ; */ + /* ./extensions/Configure/scripts/findSettings.php:126: $cont = Http::get( "http://www.mediawiki.org/w/index.php?title={$page}&action=raw" ); */ + /* ./extensions/TorBlock/TorBlock.class.php:148: $data = Http::get( $url ); */ + /* ./extensions/HoneypotIntegration/HoneypotIntegration.class.php:60: $data = Http::get( $wgHoneypotURLSource, 'default', */ + /* ./extensions/SemanticForms/includes/SF_Utils.inc:378: $page_contents = Http::get($url); */ + /* ./extensions/LocalisationUpdate/LocalisationUpdate.class.php:172: $basefilecontents = Http::get( $basefile ); */ + /* ./extensions/APC/SpecialAPC.php:245: $rss = Http::get( 'http://pecl.php.net/feeds/pkg_apc.rss' ); */ + /* ./extensions/Interlanguage/Interlanguage.php:56: $a = Http::get( $url ); */ + /* ./extensions/MWSearch/MWSearch_body.php:492: $data = Http::get( $searchUrl, $wgLuceneSearchTimeout, $httpOpts); */ + function runHTTPGets( $proxy = null ) { + $opt = array(); + + if ( $proxy ) { + $opt['proxy'] = $proxy; + } elseif ( $proxy === false ) { + $opt['noProxy'] = true; + } + + foreach ( $this->test_geturl as $u ) { + $r = Http::get( $u, 30, $opt ); /* timeout of 30s */ + $this->assertEquals( self::$content["GET $u"], "$r", "Get $u with " . Http::$httpEngine ); + } + } + + function testGetDefault() { + Http::$httpEngine = false; + $this->runHTTPGets(); + } + + function testGetPhp() { + if ( !self::$has_fopen ) { + $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); + } + + Http::$httpEngine = "php"; + $this->runHTTPGets(); + } + + function testGetCurl() { + if ( !self::$has_curl ) { + $this->markTestIncomplete( "This test requires curl." ); + } + + Http::$httpEngine = "curl"; + $this->runHTTPGets(); + } + + /* ./phase3/maintenance/parserTests.inc:1618: return Http::post( $url, array( 'postData' => wfArrayToCGI( $data ) ) ); */ + function runHTTPPosts( $proxy = null ) { + $opt = array(); + + if ( $proxy ) { + $opt['proxy'] = $proxy; + } elseif ( $proxy === false ) { + $opt['noProxy'] = true; + } + + foreach ( $this->test_posturl as $u => $postData ) { + $opt['postData'] = $postData; + $r = Http::post( $u, $opt ); + $this->assertEquals( self::$content["POST $u => $postData"], "$r", + "POST $u (postData=$postData) with " . Http::$httpEngine ); + } + } + + function testPostDefault() { + Http::$httpEngine = false; + $this->runHTTPPosts(); + } + + function testPostPhp() { + if ( !self::$has_fopen ) { + $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); + } + + Http::$httpEngine = "php"; + $this->runHTTPPosts(); + } + + function testPostCurl() { + if ( !self::$has_curl ) { + $this->markTestIncomplete( "This test requires curl." ); + } + + Http::$httpEngine = "curl"; + $this->runHTTPPosts(); + } + + function runProxyRequests() { + if ( !self::$has_proxy ) { + $this->markTestIncomplete( "This test requires a proxy." ); + } + $this->runHTTPGets( self::$proxy ); + $this->runHTTPPosts( self::$proxy ); + $this->runHTTPRequests( self::$proxy ); + + // Set false here to do noProxy + $this->runHTTPGets( false ); + $this->runHTTPPosts( false ); + $this->runHTTPRequests( false ); + } + + function testProxyDefault() { + Http::$httpEngine = false; + $this->runProxyRequests(); + } + + function testProxyPhp() { + if ( !self::$has_fopen ) { + $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); + } + + Http::$httpEngine = 'php'; + $this->runProxyRequests(); + } + + function testProxyCurl() { + if ( !self::$has_curl ) { + $this->markTestIncomplete( "This test requires curl." ); + } + + Http::$httpEngine = 'curl'; + $this->runProxyRequests(); + } + + function testIsLocalUrl() { + } + + /* ./extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.body.php:559: $user_agent = Http::userAgent(); */ + function testUserAgent() { + } + + function testIsValidUrl() { + } + + function testValidateCookieDomain() { + $this->assertFalse( Cookie::validateCookieDomain( "co.uk" ) ); + $this->assertFalse( Cookie::validateCookieDomain( ".co.uk" ) ); + $this->assertFalse( Cookie::validateCookieDomain( "gov.uk" ) ); + $this->assertFalse( Cookie::validateCookieDomain( ".gov.uk" ) ); + $this->assertTrue( Cookie::validateCookieDomain( "supermarket.uk" ) ); + $this->assertFalse( Cookie::validateCookieDomain( "uk" ) ); + $this->assertFalse( Cookie::validateCookieDomain( ".uk" ) ); + $this->assertFalse( Cookie::validateCookieDomain( "127.0.0." ) ); + $this->assertFalse( Cookie::validateCookieDomain( "127." ) ); + $this->assertFalse( Cookie::validateCookieDomain( "127.0.0.1." ) ); + $this->assertTrue( Cookie::validateCookieDomain( "127.0.0.1" ) ); + $this->assertFalse( Cookie::validateCookieDomain( "333.0.0.1" ) ); + $this->assertTrue( Cookie::validateCookieDomain( "example.com" ) ); + $this->assertFalse( Cookie::validateCookieDomain( "example.com." ) ); + $this->assertTrue( Cookie::validateCookieDomain( ".example.com" ) ); + + $this->assertTrue( Cookie::validateCookieDomain( ".example.com", "www.example.com" ) ); + $this->assertFalse( Cookie::validateCookieDomain( "example.com", "www.example.com" ) ); + $this->assertTrue( Cookie::validateCookieDomain( "127.0.0.1", "127.0.0.1" ) ); + $this->assertFalse( Cookie::validateCookieDomain( "127.0.0.1", "localhost" ) ); + + + } + + function testSetCooke() { + $c = new MockCookie( "name", "value", + array( + "domain" => "ac.th", + "path" => "/path/", + ) ); + $this->assertFalse( $c->canServeDomain( "ac.th" ) ); + + $c = new MockCookie( "name", "value", + array( + "domain" => "example.com", + "path" => "/path/", + ) ); + + $this->assertTrue( $c->canServeDomain( "example.com" ) ); + $this->assertFalse( $c->canServeDomain( "www.example.com" ) ); + + $c = new MockCookie( "name", "value", + array( + "domain" => ".example.com", + "path" => "/path/", + ) ); + + $this->assertFalse( $c->canServeDomain( "www.example.net" ) ); + $this->assertFalse( $c->canServeDomain( "example.com" ) ); + $this->assertTrue( $c->canServeDomain( "www.example.com" ) ); + + $this->assertFalse( $c->canServePath( "/" ) ); + $this->assertFalse( $c->canServePath( "/bogus/path/" ) ); + $this->assertFalse( $c->canServePath( "/path" ) ); + $this->assertTrue( $c->canServePath( "/path/" ) ); + + $this->assertTrue( $c->isUnExpired() ); + + $this->assertEquals( "", $c->serializeToHttpRequest( "/path/", "www.example.net" ) ); + $this->assertEquals( "", $c->serializeToHttpRequest( "/", "www.example.com" ) ); + $this->assertEquals( "name=value", $c->serializeToHttpRequest( "/path/", "www.example.com" ) ); + + $c = new MockCookie( "name", "value", + array( + "domain" => "www.example.com", + "path" => "/path/", + ) ); + $this->assertFalse( $c->canServeDomain( "example.com" ) ); + $this->assertFalse( $c->canServeDomain( "www.example.net" ) ); + $this->assertTrue( $c->canServeDomain( "www.example.com" ) ); + + $c = new MockCookie( "name", "value", + array( + "domain" => ".example.com", + "path" => "/path/", + "expires" => "-1 day", + ) ); + $this->assertFalse( $c->isUnExpired() ); + $this->assertEquals( "", $c->serializeToHttpRequest( "/path/", "www.example.com" ) ); + + $c = new MockCookie( "name", "value", + array( + "domain" => ".example.com", + "path" => "/path/", + "expires" => "+1 day", + ) ); + $this->assertTrue( $c->isUnExpired() ); + $this->assertEquals( "name=value", $c->serializeToHttpRequest( "/path/", "www.example.com" ) ); + } + + function testCookieJarSetCookie() { + $cj = new CookieJar; + $cj->setCookie( "name", "value", + array( + "domain" => ".example.com", + "path" => "/path/", + ) ); + $cj->setCookie( "name2", "value", + array( + "domain" => ".example.com", + "path" => "/path/sub", + ) ); + $cj->setCookie( "name3", "value", + array( + "domain" => ".example.com", + "path" => "/", + ) ); + $cj->setCookie( "name4", "value", + array( + "domain" => ".example.net", + "path" => "/path/", + ) ); + $cj->setCookie( "name5", "value", + array( + "domain" => ".example.net", + "path" => "/path/", + "expires" => "-1 day", + ) ); + + $this->assertEquals( "name4=value", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); + $this->assertEquals( "name3=value", $cj->serializeToHttpRequest( "/", "www.example.com" ) ); + $this->assertEquals( "name=value; name3=value", $cj->serializeToHttpRequest( "/path/", "www.example.com" ) ); + + $cj->setCookie( "name5", "value", + array( + "domain" => ".example.net", + "path" => "/path/", + "expires" => "+1 day", + ) ); + $this->assertEquals( "name4=value; name5=value", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); + + $cj->setCookie( "name4", "value", + array( + "domain" => ".example.net", + "path" => "/path/", + "expires" => "-1 day", + ) ); + $this->assertEquals( "name5=value", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); + } + + function testParseResponseHeader() { + $cj = new CookieJar; + + $h[] = "Set-Cookie: name4=value; domain=.example.com; path=/; expires=Mon, 09-Dec-2029 13:46:00 GMT"; + $cj->parseCookieResponseHeader( $h[0], "www.example.com" ); + $this->assertEquals( "name4=value", $cj->serializeToHttpRequest( "/", "www.example.com" ) ); + + $h[] = "name4=value2; domain=.example.com; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT"; + $cj->parseCookieResponseHeader( $h[1], "www.example.com" ); + $this->assertEquals( "", $cj->serializeToHttpRequest( "/", "www.example.com" ) ); + $this->assertEquals( "name4=value2", $cj->serializeToHttpRequest( "/path/", "www.example.com" ) ); + + $h[] = "name5=value3; domain=.example.com; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT"; + $cj->parseCookieResponseHeader( $h[2], "www.example.com" ); + $this->assertEquals( "name4=value2; name5=value3", $cj->serializeToHttpRequest( "/path/", "www.example.com" ) ); + + $h[] = "name6=value3; domain=.example.net; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT"; + $cj->parseCookieResponseHeader( $h[3], "www.example.com" ); + $this->assertEquals( "", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); + + $h[] = "name6=value0; domain=.example.net; path=/path/; expires=Mon, 09-Dec-1999 13:46:00 GMT"; + $cj->parseCookieResponseHeader( $h[4], "www.example.net" ); + $this->assertEquals( "", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); + + $h[] = "name6=value4; domain=.example.net; path=/path/; expires=Mon, 09-Dec-2029 13:46:00 GMT"; + $cj->parseCookieResponseHeader( $h[5], "www.example.net" ); + $this->assertEquals( "name6=value4", $cj->serializeToHttpRequest( "/path/", "www.example.net" ) ); + } + + function runCookieRequests() { + $r = HttpRequest::factory( "http://www.php.net/manual", array( 'followRedirects' => true ) ); + $r->execute(); + + $jar = $r->getCookieJar(); + $this->assertThat( $jar, $this->isInstanceOf( 'CookieJar' ) ); + + if ( is_a( $r, 'PhpHttpRequest' ) && version_compare( '5.1.7', phpversion(), '>' ) ) { + $this->markTestSkipped( 'Redirection fails or crashes PHP on 5.1.6 and prior' ); + } + $serialized = $jar->serializeToHttpRequest( "/search?q=test", "www.php.net" ); + $this->assertRegExp( '/\bCOUNTRY=[^=;]+/', $serialized ); + $this->assertRegExp( '/\bLAST_LANG=[^=;]+/', $serialized ); + $this->assertEquals( '', $jar->serializeToHttpRequest( "/search?q=test", "www.php.com" ) ); + } + + function testCookieRequestDefault() { + Http::$httpEngine = false; + $this->runCookieRequests(); + } + function testCookieRequestPhp() { + if ( !self::$has_fopen ) { + $this->markTestIncomplete( "This test requires allow_url_fopen=true." ); + } + + Http::$httpEngine = 'php'; + $this->runCookieRequests(); + } + function testCookieRequestCurl() { + if ( !self::$has_curl ) { + $this->markTestIncomplete( "This test requires curl." ); + } + + Http::$httpEngine = 'curl'; + $this->runCookieRequests(); + } +} diff --git a/maintenance/tests/phpunit/includes/IPTest.php b/maintenance/tests/phpunit/includes/IPTest.php new file mode 100644 index 0000000000..9db77f72c6 --- /dev/null +++ b/maintenance/tests/phpunit/includes/IPTest.php @@ -0,0 +1,52 @@ +assertTrue( IP::isValid( $ip ) , "$ip is a valid IPv4 address" ); + } + } + } + + public function testInvalidIPs() { + foreach ( range( 256, 999 ) as $i ) { + $a = sprintf( "%03d", $i ); + $b = sprintf( "%02d", $i ); + $c = sprintf( "%01d", $i ); + foreach ( array_unique( array( $a, $b, $c ) ) as $f ) { + $ip = "$f.$f.$f.$f"; + $this->assertFalse( IP::isValid( $ip ), "$ip is not a valid IPv4 address" ); + } + } + } + + public function testBogusIPs() { + $invalid = array( + 'www.xn--var-xla.net', + '216.17.184.G', + '216.17.184.1.', + '216.17.184', + '216.17.184.', + '256.17.184.1' + ); + foreach ( $invalid as $i ) { + $this->assertFalse( IP::isValid( $i ), "$i is an invalid IPv4 address" ); + } + } + + public function testPrivateIPs() { + $private = array( '10.0.0.1', '172.16.0.1', '192.168.0.1' ); + foreach ( $private as $p ) { + $this->assertFalse( IP::isPublic( $p ), "$p is not a public IP address" ); + } + } +} diff --git a/maintenance/tests/phpunit/includes/ImageFunctionsTest.php b/maintenance/tests/phpunit/includes/ImageFunctionsTest.php new file mode 100644 index 0000000000..4de4e63d4f --- /dev/null +++ b/maintenance/tests/phpunit/includes/ImageFunctionsTest.php @@ -0,0 +1,48 @@ + 50, + 'height' => 50, + 'tests' => array( + 50 => 50, + 17 => 17, + 18 => 18 ) ), + array( + 'width' => 366, + 'height' => 300, + 'tests' => array( + 50 => 61, + 17 => 21, + 18 => 22 ) ), + array( + 'width' => 300, + 'height' => 366, + 'tests' => array( + 50 => 41, + 17 => 14, + 18 => 15 ) ), + array( + 'width' => 100, + 'height' => 400, + 'tests' => array( + 50 => 12, + 17 => 4, + 18 => 4 ) ) ); + foreach ( $vals as $row ) { + extract( $row ); + foreach ( $tests as $max => $expected ) { + $y = round( $expected * $height / $width ); + $result = wfFitBoxWidth( $width, $height, $max ); + $y2 = round( $result * $height / $width ); + $this->assertEquals( $expected, + $result, + "($width, $height, $max) wanted: {$expected}x$y, got: {$result}x$y2" ); + } + } + } +} + + diff --git a/maintenance/tests/phpunit/includes/LanguageConverterTest.php b/maintenance/tests/phpunit/includes/LanguageConverterTest.php new file mode 100644 index 0000000000..9fdcedc68d --- /dev/null +++ b/maintenance/tests/phpunit/includes/LanguageConverterTest.php @@ -0,0 +1,150 @@ +lang = new LanguageTest(); + $this->lc = new TestConverter( $this->lang, 'tg', + array( 'tg', 'tg-latn' ) ); + } + + function tearDown() { + global $wgMemc, $wgContLang; + unset( $wgMemc ); + unset( $this->lc ); + unset( $this->lang ); + $wgContLang = null; + } + + function testGetPreferredVariantDefaults() { + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, true ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); + } + + function testGetPreferredVariantHeaders() { + global $wgRequest; + $wgRequest->setHeader( 'Accept-Language', 'tg-latn' ); + + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( false, true ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); + } + + function testGetPreferredVariantHeaderWeight() { + global $wgRequest; + $wgRequest->setHeader( 'Accept-Language', 'tg;q=1' ); + + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, true ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); + } + + function testGetPreferredVariantHeaderWeight2() { + global $wgRequest; + $wgRequest->setHeader( 'Accept-Language', 'tg-latn;q=1' ); + + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( false, true ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); + } + + function testGetPreferredVariantHeaderMulti() { + global $wgRequest; + $wgRequest->setHeader( 'Accept-Language', 'en, tg-latn;q=1' ); + + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( false, true ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); + } + + function testGetPreferredVariantUserOption() { + global $wgUser; + + $wgUser = new User; + $wgUser->setId( 1 ); + $wgUser->mDataLoaded = true; + $wgUser->setOption( 'variant', 'tg-latn' ); + + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, true ) ); + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, false ) ); + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, true ) ); + } + + function testGetPreferredVariantHeaderUserVsUrl() { + global $wgRequest, $wgUser, $wgContLang; + + $wgContLang = Language::factory( 'tg-latn' ); + $wgRequest->setVal( 'variant', 'tg' ); + $wgUser = User::newFromId( "admin" ); + $wgUser->setId( 1 ); + $wgUser->setOption( 'variant', 'tg-latn' ); // The user's data is ignored + // because the variant is set in the URL. + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, false ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( true, true ) ); + } + + + function testGetPreferredVariantDefaultLanguageVariant() { + global $wgDefaultLanguageVariant; + + $wgDefaultLanguageVariant = 'tg-latn'; + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( false, false ) ); + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( false, true ) ); + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, false ) ); + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, true ) ); + } + + function testGetPreferredVariantDefaultLanguageVsUrlVariant() { + global $wgDefaultLanguageVariant, $wgRequest, $wgContLang; + + $wgContLang = Language::factory( 'tg-latn' ); + $wgDefaultLanguageVariant = 'tg'; + $wgRequest->setVal( 'variant', null ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, false ) ); + $this->assertEquals( 'tg', $this->lc->getPreferredVariant( false, true ) ); + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, false ) ); + $this->assertEquals( 'tg-latn', $this->lc->getPreferredVariant( true, true ) ); + } +} + +/** + * Test converter (from Tajiki to latin orthography) + */ +class TestConverter extends LanguageConverter { + private $table = array( + 'б' => 'b', + 'в' => 'v', + 'г' => 'g', + ); + + function loadDefaultTables() { + $this->mTables = array( + 'tg-latn' => new ReplacementArray( $this->table ), + 'tg' => new ReplacementArray() + ); + } + +} + +class LanguageTest extends Language { + function __construct() { + parent::__construct(); + $variants = array( 'tg', 'tg-latn' ); + $this->mConverter = new TestConverter( $this, 'tg', $variants ); + } +} diff --git a/maintenance/tests/phpunit/includes/LicensesTest.php b/maintenance/tests/phpunit/includes/LicensesTest.php new file mode 100644 index 0000000000..c5357f89b8 --- /dev/null +++ b/maintenance/tests/phpunit/includes/LicensesTest.php @@ -0,0 +1,17 @@ +assertTrue( is_a( $lc, 'Licenses' ), 'Correct class' ); + } +} \ No newline at end of file diff --git a/maintenance/tests/phpunit/includes/LocalFileTest.php b/maintenance/tests/phpunit/includes/LocalFileTest.php new file mode 100644 index 0000000000..29682b18b5 --- /dev/null +++ b/maintenance/tests/phpunit/includes/LocalFileTest.php @@ -0,0 +1,104 @@ + 'test', + 'directory' => '/testdir', + 'url' => '/testurl', + 'hashLevels' => 2, + 'transformVia404' => false, + ); + $this->repo_hl0 = new LocalRepo( array( 'hashLevels' => 0 ) + $info ); + $this->repo_hl2 = new LocalRepo( array( 'hashLevels' => 2 ) + $info ); + $this->repo_lc = new LocalRepo( array( 'initialCapital' => false ) + $info ); + $this->file_hl0 = $this->repo_hl0->newFile( 'test!' ); + $this->file_hl2 = $this->repo_hl2->newFile( 'test!' ); + $this->file_lc = $this->repo_lc->newFile( 'test!' ); + } + + function tearDown() { + global $wgContLang; + unset( $wgContLang ); + } + + function testGetHashPath() { + $this->assertEquals( '', $this->file_hl0->getHashPath() ); + $this->assertEquals( 'a/a2/', $this->file_hl2->getHashPath() ); + $this->assertEquals( 'c/c4/', $this->file_lc->getHashPath() ); + } + + function testGetRel() { + $this->assertEquals( 'Test!', $this->file_hl0->getRel() ); + $this->assertEquals( 'a/a2/Test!', $this->file_hl2->getRel() ); + $this->assertEquals( 'c/c4/test!', $this->file_lc->getRel() ); + } + + function testGetUrlRel() { + $this->assertEquals( 'Test%21', $this->file_hl0->getUrlRel() ); + $this->assertEquals( 'a/a2/Test%21', $this->file_hl2->getUrlRel() ); + $this->assertEquals( 'c/c4/test%21', $this->file_lc->getUrlRel() ); + } + + function testGetArchivePath() { + $this->assertEquals( '/testdir/archive', $this->file_hl0->getArchivePath() ); + $this->assertEquals( '/testdir/archive/a/a2', $this->file_hl2->getArchivePath() ); + $this->assertEquals( '/testdir/archive/!', $this->file_hl0->getArchivePath( '!' ) ); + $this->assertEquals( '/testdir/archive/a/a2/!', $this->file_hl2->getArchivePath( '!' ) ); + } + + function testGetThumbPath() { + $this->assertEquals( '/testdir/thumb/Test!', $this->file_hl0->getThumbPath() ); + $this->assertEquals( '/testdir/thumb/a/a2/Test!', $this->file_hl2->getThumbPath() ); + $this->assertEquals( '/testdir/thumb/Test!/x', $this->file_hl0->getThumbPath( 'x' ) ); + $this->assertEquals( '/testdir/thumb/a/a2/Test!/x', $this->file_hl2->getThumbPath( 'x' ) ); + } + + function testGetArchiveUrl() { + $this->assertEquals( '/testurl/archive', $this->file_hl0->getArchiveUrl() ); + $this->assertEquals( '/testurl/archive/a/a2', $this->file_hl2->getArchiveUrl() ); + $this->assertEquals( '/testurl/archive/%21', $this->file_hl0->getArchiveUrl( '!' ) ); + $this->assertEquals( '/testurl/archive/a/a2/%21', $this->file_hl2->getArchiveUrl( '!' ) ); + } + + function testGetThumbUrl() { + $this->assertEquals( '/testurl/thumb/Test%21', $this->file_hl0->getThumbUrl() ); + $this->assertEquals( '/testurl/thumb/a/a2/Test%21', $this->file_hl2->getThumbUrl() ); + $this->assertEquals( '/testurl/thumb/Test%21/x', $this->file_hl0->getThumbUrl( 'x' ) ); + $this->assertEquals( '/testurl/thumb/a/a2/Test%21/x', $this->file_hl2->getThumbUrl( 'x' ) ); + } + + function testGetArchiveVirtualUrl() { + $this->assertEquals( 'mwrepo://test/public/archive', $this->file_hl0->getArchiveVirtualUrl() ); + $this->assertEquals( 'mwrepo://test/public/archive/a/a2', $this->file_hl2->getArchiveVirtualUrl() ); + $this->assertEquals( 'mwrepo://test/public/archive/%21', $this->file_hl0->getArchiveVirtualUrl( '!' ) ); + $this->assertEquals( 'mwrepo://test/public/archive/a/a2/%21', $this->file_hl2->getArchiveVirtualUrl( '!' ) ); + } + + function testGetThumbVirtualUrl() { + $this->assertEquals( 'mwrepo://test/thumb/Test%21', $this->file_hl0->getThumbVirtualUrl() ); + $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21', $this->file_hl2->getThumbVirtualUrl() ); + $this->assertEquals( 'mwrepo://test/thumb/Test%21/%21', $this->file_hl0->getThumbVirtualUrl( '!' ) ); + $this->assertEquals( 'mwrepo://test/thumb/a/a2/Test%21/%21', $this->file_hl2->getThumbVirtualUrl( '!' ) ); + } + + function testGetUrl() { + $this->assertEquals( '/testurl/Test%21', $this->file_hl0->getUrl() ); + $this->assertEquals( '/testurl/a/a2/Test%21', $this->file_hl2->getUrl() ); + } + + function testWfLocalFile() { + $file = wfLocalFile( "File:Some_file_that_probably_doesn't exist.png" ); + $this->assertThat( $file, $this->isInstanceOf( 'LocalFile' ), 'wfLocalFile() returns LocalFile for valid Titles' ); + } +} + + diff --git a/maintenance/tests/phpunit/includes/MessageTest.php b/maintenance/tests/phpunit/includes/MessageTest.php new file mode 100644 index 0000000000..6c5580294e --- /dev/null +++ b/maintenance/tests/phpunit/includes/MessageTest.php @@ -0,0 +1,40 @@ +assertTrue( wfMessage( 'mainpage' )->exists() ); + $this->assertTrue( wfMessage( 'mainpage' )->params( array() )->exists() ); + $this->assertTrue( wfMessage( 'mainpage' )->rawParams( 'foo', 123 )->exists() ); + $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->exists() ); + $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->params( array() )->exists() ); + $this->assertFalse( wfMessage( 'i-dont-exist-evar' )->rawParams( 'foo', 123 )->exists() ); + } + + function testKey() { + $this->assertType( 'Message', wfMessage( 'mainpage' ) ); + $this->assertType( 'Message', wfMessage( 'i-dont-exist-evar' ) ); + $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->text() ); + $this->assertEquals( '<i-dont-exist-evar>', wfMessage( 'i-dont-exist-evar' )->text() ); + } + + function testInLanguage() { + $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( 'en' )->text() ); + $this->assertEquals( 'Заглавная страница', wfMessage( 'mainpage' )->inLanguage( 'ru' )->text() ); + $this->assertEquals( 'Main Page', wfMessage( 'mainpage' )->inLanguage( Language::factory( 'en' ) )->text() ); + $this->assertEquals( 'Заглавная страница', wfMessage( 'mainpage' )->inLanguage( Language::factory( 'ru' ) )->text() ); + } + + /** + * @expectedException MWException + */ + function testInLanguageThrows() { + wfMessage( 'foo' )->inLanguage( 123 ); + } +} diff --git a/maintenance/tests/phpunit/includes/ResourceLoaderFileModuleTest.php b/maintenance/tests/phpunit/includes/ResourceLoaderFileModuleTest.php new file mode 100644 index 0000000000..5ad7d9373d --- /dev/null +++ b/maintenance/tests/phpunit/includes/ResourceLoaderFileModuleTest.php @@ -0,0 +1,15 @@ + false, + 'wgCompressRevisions' => false, + 'wgInputEncoding' => 'utf-8', + 'wgOutputEncoding' => 'utf-8' ); + foreach ( $globalSet as $var => $data ) { + $this->saveGlobals[$var] = $GLOBALS[$var]; + $GLOBALS[$var] = $data; + } + } + + function tearDown() { + foreach ( $this->saveGlobals as $var => $data ) { + $GLOBALS[$var] = $data; + } + } + + function testGetRevisionText() { + $row = new stdClass; + $row->old_flags = ''; + $row->old_text = 'This is a bunch of revision text.'; + $this->assertEquals( + 'This is a bunch of revision text.', + Revision::getRevisionText( $row ) ); + } + + function testGetRevisionTextGzip() { + $row = new stdClass; + $row->old_flags = 'gzip'; + $row->old_text = gzdeflate( 'This is a bunch of revision text.' ); + $this->assertEquals( + 'This is a bunch of revision text.', + Revision::getRevisionText( $row ) ); + } + + function testGetRevisionTextUtf8Native() { + $row = new stdClass; + $row->old_flags = 'utf-8'; + $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; + $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; + $this->assertEquals( + "Wiki est l'\xc3\xa9cole superieur !", + Revision::getRevisionText( $row ) ); + } + + function testGetRevisionTextUtf8Legacy() { + $row = new stdClass; + $row->old_flags = ''; + $row->old_text = "Wiki est l'\xe9cole superieur !"; + $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; + $this->assertEquals( + "Wiki est l'\xc3\xa9cole superieur !", + Revision::getRevisionText( $row ) ); + } + + function testGetRevisionTextUtf8NativeGzip() { + $row = new stdClass; + $row->old_flags = 'gzip,utf-8'; + $row->old_text = gzdeflate( "Wiki est l'\xc3\xa9cole superieur !" ); + $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; + $this->assertEquals( + "Wiki est l'\xc3\xa9cole superieur !", + Revision::getRevisionText( $row ) ); + } + + function testGetRevisionTextUtf8LegacyGzip() { + $row = new stdClass; + $row->old_flags = 'gzip'; + $row->old_text = gzdeflate( "Wiki est l'\xe9cole superieur !" ); + $GLOBALS['wgLegacyEncoding'] = 'iso-8859-1'; + $this->assertEquals( + "Wiki est l'\xc3\xa9cole superieur !", + Revision::getRevisionText( $row ) ); + } + + function testCompressRevisionTextUtf8() { + $row = new stdClass; + $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; + $row->old_flags = Revision::compressRevisionText( $row->old_text ); + $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ), + "Flags should contain 'utf-8'" ); + $this->assertFalse( false !== strpos( $row->old_flags, 'gzip' ), + "Flags should not contain 'gzip'" ); + $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", + $row->old_text, "Direct check" ); + $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", + Revision::getRevisionText( $row ), "getRevisionText" ); + } + + function testCompressRevisionTextUtf8Gzip() { + $GLOBALS['wgCompressRevisions'] = true; + $row = new stdClass; + $row->old_text = "Wiki est l'\xc3\xa9cole superieur !"; + $row->old_flags = Revision::compressRevisionText( $row->old_text ); + $this->assertTrue( false !== strpos( $row->old_flags, 'utf-8' ), + "Flags should contain 'utf-8'" ); + $this->assertTrue( false !== strpos( $row->old_flags, 'gzip' ), + "Flags should contain 'gzip'" ); + $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", + gzinflate( $row->old_text ), "Direct check" ); + $this->assertEquals( "Wiki est l'\xc3\xa9cole superieur !", + Revision::getRevisionText( $row ), "getRevisionText" ); + } +} + + diff --git a/maintenance/tests/phpunit/includes/SanitizerTest.php b/maintenance/tests/phpunit/includes/SanitizerTest.php new file mode 100644 index 0000000000..a12f9013f0 --- /dev/null +++ b/maintenance/tests/phpunit/includes/SanitizerTest.php @@ -0,0 +1,72 @@ +assertEquals( + "\xc3\xa9cole", + Sanitizer::decodeCharReferences( 'école' ), + 'decode named entities' + ); + } + + function testDecodeNumericEntities() { + $this->assertEquals( + "\xc4\x88io bonas dans l'\xc3\xa9cole!", + Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), + 'decode numeric entities' + ); + } + + function testDecodeMixedEntities() { + $this->assertEquals( + "\xc4\x88io bonas dans l'\xc3\xa9cole!", + Sanitizer::decodeCharReferences( "Ĉio bonas dans l'école!" ), + 'decode mixed numeric/named entities' + ); + } + + function testDecodeMixedComplexEntities() { + $this->assertEquals( + "\xc4\x88io bonas dans l'\xc3\xa9cole! (mais pas Ĉio dans l'école)", + Sanitizer::decodeCharReferences( + "Ĉio bonas dans l'école! (mais pas &#x108;io dans l'&eacute;cole)" + ), + 'decode mixed complex entities' + ); + } + + function testInvalidAmpersand() { + $this->assertEquals( + 'a & b', + Sanitizer::decodeCharReferences( 'a & b' ), + 'Invalid ampersand' + ); + } + + function testInvalidEntities() { + $this->assertEquals( + '&foo;', + Sanitizer::decodeCharReferences( '&foo;' ), + 'Invalid named entity' + ); + } + + function testInvalidNumberedEntities() { + $this->assertEquals( UTF8_REPLACEMENT, Sanitizer::decodeCharReferences( "�" ), 'Invalid numbered entity' ); + } + + function testSelfClosingTag() { + $GLOBALS['wgUseTidy'] = false; + $this->assertEquals( + '
Hello world
', + Sanitizer::removeHTMLtags( '
Hello world
' ), + 'Self-closing closing div' + ); + } +} + diff --git a/maintenance/tests/phpunit/includes/SiteConfigurationTest.php b/maintenance/tests/phpunit/includes/SiteConfigurationTest.php new file mode 100644 index 0000000000..dec5d5fa02 --- /dev/null +++ b/maintenance/tests/phpunit/includes/SiteConfigurationTest.php @@ -0,0 +1,311 @@ +suffixes as $suffix ) { + if ( substr( $wiki, -strlen( $suffix ) ) == $suffix ) { + $site = $suffix; + $lang = substr( $wiki, 0, -strlen( $suffix ) ); + break; + } + } + return array( + 'suffix' => $site, + 'lang' => $lang, + 'params' => array( + 'lang' => $lang, + 'site' => $site, + 'wiki' => $wiki, + ), + 'tags' => array( 'tag' ), + ); +} + +class SiteConfigurationTest extends PHPUnit_Framework_TestCase { + var $mConf; + + function setUp() { + $this->mConf = new SiteConfiguration; + + $this->mConf->suffixes = array( 'wiki' ); + $this->mConf->wikis = array( 'enwiki', 'dewiki', 'frwiki' ); + $this->mConf->settings = array( + 'simple' => array( + 'wiki' => 'wiki', + 'tag' => 'tag', + 'enwiki' => 'enwiki', + 'dewiki' => 'dewiki', + 'frwiki' => 'frwiki', + ), + + 'fallback' => array( + 'default' => 'default', + 'wiki' => 'wiki', + 'tag' => 'tag', + ), + + 'params' => array( + 'default' => '$lang $site $wiki', + ), + + '+global' => array( + 'wiki' => array( + 'wiki' => 'wiki', + ), + 'tag' => array( + 'tag' => 'tag', + ), + 'enwiki' => array( + 'enwiki' => 'enwiki', + ), + 'dewiki' => array( + 'dewiki' => 'dewiki', + ), + 'frwiki' => array( + 'frwiki' => 'frwiki', + ), + ), + + 'merge' => array( + '+wiki' => array( + 'wiki' => 'wiki', + ), + '+tag' => array( + 'tag' => 'tag', + ), + 'default' => array( + 'default' => 'default', + ), + '+enwiki' => array( + 'enwiki' => 'enwiki', + ), + '+dewiki' => array( + 'dewiki' => 'dewiki', + ), + '+frwiki' => array( + 'frwiki' => 'frwiki', + ), + ), + ); + + $GLOBALS['global'] = array( 'global' => 'global' ); + } + + + function testSiteFromDB() { + $this->assertEquals( + array( 'wikipedia', 'en' ), + $this->mConf->siteFromDB( 'enwiki' ), + 'siteFromDB()' + ); + $this->assertEquals( + array( 'wikipedia', '' ), + $this->mConf->siteFromDB( 'wiki' ), + 'siteFromDB() on a suffix' + ); + $this->assertEquals( + array( null, null ), + $this->mConf->siteFromDB( 'wikien' ), + 'siteFromDB() on a non-existing wiki' + ); + + $this->mConf->suffixes = array( 'wiki', '' ); + $this->assertEquals( + array( '', 'wikien' ), + $this->mConf->siteFromDB( 'wikien' ), + 'siteFromDB() on a non-existing wiki (2)' + ); + } + + function testGetLocalDatabases() { + $this->assertEquals( + array( 'enwiki', 'dewiki', 'frwiki' ), + $this->mConf->getLocalDatabases(), + 'getLocalDatabases()' + ); + } + + function testGet() { + $this->assertEquals( + 'enwiki', + $this->mConf->get( 'simple', 'enwiki', 'wiki' ), + 'get(): simple setting on an existing wiki' + ); + $this->assertEquals( + 'dewiki', + $this->mConf->get( 'simple', 'dewiki', 'wiki' ), + 'get(): simple setting on an existing wiki (2)' + ); + $this->assertEquals( + 'frwiki', + $this->mConf->get( 'simple', 'frwiki', 'wiki' ), + 'get(): simple setting on an existing wiki (3)' + ); + $this->assertEquals( + 'wiki', + $this->mConf->get( 'simple', 'wiki', 'wiki' ), + 'get(): simple setting on an suffix' + ); + $this->assertEquals( + 'wiki', + $this->mConf->get( 'simple', 'eswiki', 'wiki' ), + 'get(): simple setting on an non-existing wiki' + ); + + $this->assertEquals( + 'wiki', + $this->mConf->get( 'fallback', 'enwiki', 'wiki' ), + 'get(): fallback setting on an existing wiki' + ); + $this->assertEquals( + 'tag', + $this->mConf->get( 'fallback', 'dewiki', 'wiki', array(), array( 'tag' ) ), + 'get(): fallback setting on an existing wiki (with wiki tag)' + ); + $this->assertEquals( + 'wiki', + $this->mConf->get( 'fallback', 'wiki', 'wiki' ), + 'get(): fallback setting on an suffix' + ); + $this->assertEquals( + 'wiki', + $this->mConf->get( 'fallback', 'wiki', 'wiki', array(), array( 'tag' ) ), + 'get(): fallback setting on an suffix (with wiki tag)' + ); + $this->assertEquals( + 'wiki', + $this->mConf->get( 'fallback', 'eswiki', 'wiki' ), + 'get(): fallback setting on an non-existing wiki' + ); + $this->assertEquals( + 'tag', + $this->mConf->get( 'fallback', 'eswiki', 'wiki', array(), array( 'tag' ) ), + 'get(): fallback setting on an non-existing wiki (with wiki tag)' + ); + + $common = array( 'wiki' => 'wiki', 'default' => 'default' ); + $commonTag = array( 'tag' => 'tag', 'wiki' => 'wiki', 'default' => 'default' ); + $this->assertEquals( + array( 'enwiki' => 'enwiki' ) + $common, + $this->mConf->get( 'merge', 'enwiki', 'wiki' ), + 'get(): merging setting on an existing wiki' + ); + $this->assertEquals( + array( 'enwiki' => 'enwiki' ) + $commonTag, + $this->mConf->get( 'merge', 'enwiki', 'wiki', array(), array( 'tag' ) ), + 'get(): merging setting on an existing wiki (with tag)' + ); + $this->assertEquals( + array( 'dewiki' => 'dewiki' ) + $common, + $this->mConf->get( 'merge', 'dewiki', 'wiki' ), + 'get(): merging setting on an existing wiki (2)' + ); + $this->assertEquals( + array( 'dewiki' => 'dewiki' ) + $commonTag, + $this->mConf->get( 'merge', 'dewiki', 'wiki', array(), array( 'tag' ) ), + 'get(): merging setting on an existing wiki (2) (with tag)' + ); + $this->assertEquals( + array( 'frwiki' => 'frwiki' ) + $common, + $this->mConf->get( 'merge', 'frwiki', 'wiki' ), + 'get(): merging setting on an existing wiki (3)' + ); + $this->assertEquals( + array( 'frwiki' => 'frwiki' ) + $commonTag, + $this->mConf->get( 'merge', 'frwiki', 'wiki', array(), array( 'tag' ) ), + 'get(): merging setting on an existing wiki (3) (with tag)' + ); + $this->assertEquals( + array( 'wiki' => 'wiki' ) + $common, + $this->mConf->get( 'merge', 'wiki', 'wiki' ), + 'get(): merging setting on an suffix' + ); + $this->assertEquals( + array( 'wiki' => 'wiki' ) + $commonTag, + $this->mConf->get( 'merge', 'wiki', 'wiki', array(), array( 'tag' ) ), + 'get(): merging setting on an suffix (with tag)' + ); + $this->assertEquals( + $common, + $this->mConf->get( 'merge', 'eswiki', 'wiki' ), + 'get(): merging setting on an non-existing wiki' + ); + $this->assertEquals( + $commonTag, + $this->mConf->get( 'merge', 'eswiki', 'wiki', array(), array( 'tag' ) ), + 'get(): merging setting on an non-existing wiki (with tag)' + ); + } + + function testSiteFromDBWithCallback() { + $this->mConf->siteParamsCallback = 'getSiteParams'; + + $this->assertEquals( + array( 'wiki', 'en' ), + $this->mConf->siteFromDB( 'enwiki' ), + 'siteFromDB() with callback' + ); + $this->assertEquals( + array( 'wiki', '' ), + $this->mConf->siteFromDB( 'wiki' ), + 'siteFromDB() with callback on a suffix' + ); + $this->assertEquals( + array( null, null ), + $this->mConf->siteFromDB( 'wikien' ), + 'siteFromDB() with callback on a non-existing wiki' + ); + } + + function testParamReplacement() { + $this->mConf->siteParamsCallback = 'getSiteParams'; + + $this->assertEquals( + 'en wiki enwiki', + $this->mConf->get( 'params', 'enwiki', 'wiki' ), + 'get(): parameter replacement on an existing wiki' + ); + $this->assertEquals( + 'de wiki dewiki', + $this->mConf->get( 'params', 'dewiki', 'wiki' ), + 'get(): parameter replacement on an existing wiki (2)' + ); + $this->assertEquals( + 'fr wiki frwiki', + $this->mConf->get( 'params', 'frwiki', 'wiki' ), + 'get(): parameter replacement on an existing wiki (3)' + ); + $this->assertEquals( + ' wiki wiki', + $this->mConf->get( 'params', 'wiki', 'wiki' ), + 'get(): parameter replacement on an suffix' + ); + $this->assertEquals( + 'es wiki eswiki', + $this->mConf->get( 'params', 'eswiki', 'wiki' ), + 'get(): parameter replacement on an non-existing wiki' + ); + } + + function testGetAll() { + $this->mConf->siteParamsCallback = 'getSiteParams'; + + $getall = array( + 'simple' => 'enwiki', + 'fallback' => 'tag', + 'params' => 'en wiki enwiki', + 'global' => array( 'enwiki' => 'enwiki' ) + $GLOBALS['global'], + 'merge' => array( 'enwiki' => 'enwiki', 'tag' => 'tag', 'wiki' => 'wiki', 'default' => 'default' ), + ); + $this->assertEquals( $getall, $this->mConf->getAll( 'enwiki' ), 'getAll()' ); + + $this->mConf->extractAllGlobals( 'enwiki', 'wiki' ); + + $this->assertEquals( $getall['simple'], $GLOBALS['simple'], 'extractAllGlobals(): simple setting' ); + $this->assertEquals( $getall['fallback'], $GLOBALS['fallback'], 'extractAllGlobals(): fallback setting' ); + $this->assertEquals( $getall['params'], $GLOBALS['params'], 'extractAllGlobals(): parameter replacement' ); + $this->assertEquals( $getall['global'], $GLOBALS['global'], 'extractAllGlobals(): merging with global' ); + $this->assertEquals( $getall['merge'], $GLOBALS['merge'], 'extractAllGlobals(): merging setting' ); + } +} diff --git a/maintenance/tests/phpunit/includes/TimeAdjustTest.php b/maintenance/tests/phpunit/includes/TimeAdjustTest.php new file mode 100644 index 0000000000..820e7130fd --- /dev/null +++ b/maintenance/tests/phpunit/includes/TimeAdjustTest.php @@ -0,0 +1,49 @@ +iniSet( 'precision', 15 ); + } + + public function tearDown() { + global $wgLocalTZoffset; + $wgLocalTZoffset = self::$offset; + } + + # Test offset usage for a given language::userAdjust + function testUserAdjust() { + global $wgLocalTZoffset, $wgContLang; + + $wgContLang = $en = Language::factory( 'en' ); + + #  Collection of parameters for Language_t_Offset. + # Format: date to be formatted, localTZoffset value, expected date + $userAdjust_tests = array( + array( 20061231235959, 0, 20061231235959 ), + array( 20061231235959, 5, 20070101000459 ), + array( 20061231235959, 15, 20070101001459 ), + array( 20061231235959, 60, 20070101005959 ), + array( 20061231235959, 90, 20070101012959 ), + array( 20061231235959, 120, 20070101015959 ), + array( 20061231235959, 540, 20070101085959 ), + array( 20061231235959, -5, 20061231235459 ), + array( 20061231235959, -30, 20061231232959 ), + array( 20061231235959, -60, 20061231225959 ), + ); + + foreach ( $userAdjust_tests as $data ) { + $wgLocalTZoffset = $data[1]; + + $this->assertEquals( + strval( $data[2] ), + strval( $en->userAdjust( $data[0], '' ) ), + "User adjust {$data[0]} by {$data[1]} minutes should give {$data[2]}" + ); + } + } +} diff --git a/maintenance/tests/phpunit/includes/TitlePermissionTest.php b/maintenance/tests/phpunit/includes/TitlePermissionTest.php new file mode 100644 index 0000000000..a3270fa35c --- /dev/null +++ b/maintenance/tests/phpunit/includes/TitlePermissionTest.php @@ -0,0 +1,651 @@ +getID() ) { + self::$userUser = User::createNew( self::$userName, array( + "email" => "test@example.com", + "real_name" => "Test User" ) ); + } + + self::$altUser = User::newFromName( self::$altUserName ); + if ( !self::$altUser->getID() ) { + self::$altUser = User::createNew( self::$altUserName, array( + "email" => "alttest@example.com", + "real_name" => "Test User Alt" ) ); + } + + self::$anonUser = User::newFromId( 0 ); + + self::$user = self::$userUser; + } + } + + function tearDown() { + global $wgMemc, $wgContLang, $wgLang; + $wgMemc = $wgContLang = $wgLang = null; + } + + function setUserPerm( $perm ) { + if ( is_array( $perm ) ) { + self::$user->mRights = $perm; + } else { + self::$user->mRights = array( $perm ); + } + } + + function setTitle( $ns, $title = "Main_Page" ) { + self::$title = Title::makeTitle( $ns, $title ); + } + + function setUser( $userName = null ) { + if ( $userName === 'anon' ) { + self::$user = self::$anonUser; + } else if ( $userName === null || $userName === self::$userName ) { + self::$user = self::$userUser; + } else { + self::$user = self::$altUser; + } + + global $wgUser; + $wgUser = self::$user; + } + + function testQuickPermissions() { + global $wgContLang; + $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); + + $this->setUser( 'anon' ); + $this->setTitle( NS_TALK ); + $this->setUserPerm( "createtalk" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array(), $res ); + + $this->setTitle( NS_TALK ); + $this->setUserPerm( "createpage" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array( array( "nocreatetext" ) ), $res ); + + $this->setTitle( NS_TALK ); + $this->setUserPerm( "" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array( array( 'nocreatetext' ) ), $res ); + + $this->setTitle( NS_MAIN ); + $this->setUserPerm( "createpage" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array( ), $res ); + + $this->setTitle( NS_MAIN ); + $this->setUserPerm( "createtalk" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array( array( 'nocreatetext' ) ), $res ); + + $this->setUser( self::$userName ); + $this->setTitle( NS_TALK ); + $this->setUserPerm( "createtalk" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array( ), $res ); + + $this->setTitle( NS_TALK ); + $this->setUserPerm( "createpage" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); + + $this->setTitle( NS_TALK ); + $this->setUserPerm( "" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); + + $this->setTitle( NS_MAIN ); + $this->setUserPerm( "createpage" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array( ), $res ); + + $this->setTitle( NS_MAIN ); + $this->setUserPerm( "createtalk" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); + + $this->setTitle( NS_MAIN ); + $this->setUserPerm( "" ); + $res = self::$title->getUserPermissionsErrors( 'create', self::$user ); + $this->assertEquals( array( array( 'nocreate-loggedin' ) ), $res ); + + $this->setUser( 'anon' ); + $this->setTitle( NS_USER, self::$userName . '' ); + $this->setUserPerm( "" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'cant-move-user-page' ), array( 'movenologintext' ) ), $res ); + + $this->setTitle( NS_USER, self::$userName . '/subpage' ); + $this->setUserPerm( "" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'movenologintext' ) ), $res ); + + $this->setTitle( NS_USER, self::$userName . '' ); + $this->setUserPerm( "move-rootuserpages" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'movenologintext' ) ), $res ); + + $this->setTitle( NS_USER, self::$userName . '/subpage' ); + $this->setUserPerm( "move-rootuserpages" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'movenologintext' ) ), $res ); + + $this->setTitle( NS_USER, self::$userName . '' ); + $this->setUserPerm( "" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'cant-move-user-page' ), array( 'movenologintext' ) ), $res ); + + $this->setTitle( NS_USER, self::$userName . '/subpage' ); + $this->setUserPerm( "" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'movenologintext' ) ), $res ); + + $this->setTitle( NS_USER, self::$userName . '' ); + $this->setUserPerm( "move-rootuserpages" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'movenologintext' ) ), $res ); + + $this->setTitle( NS_USER, self::$userName . '/subpage' ); + $this->setUserPerm( "move-rootuserpages" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'movenologintext' ) ), $res ); + + $this->setUser( self::$userName ); + $this->setTitle( NS_FILE, "img.png" ); + $this->setUserPerm( "" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ), $res ); + + $this->setTitle( NS_FILE, "img.png" ); + $this->setUserPerm( "movefile" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'movenotallowed' ) ), $res ); + + $this->setUser( 'anon' ); + $this->setTitle( NS_FILE, "img.png" ); + $this->setUserPerm( "" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ), $res ); + + $this->setTitle( NS_FILE, "img.png" ); + $this->setUserPerm( "movefile" ); + $res = self::$title->getUserPermissionsErrors( 'move', self::$user ); + $this->assertEquals( array( array( 'movenologintext' ) ), $res ); + + $this->setUser( self::$userName ); + $this->setUserPerm( "move" ); + $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ) ) ); + + $this->setUserPerm( "" ); + $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ) ); + + $this->setUser( 'anon' ); + $this->setUserPerm( "move" ); + $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ) ) ); + + $this->setUserPerm( "" ); + $this->runGroupPermissions( 'move', array( array( 'movenotallowedfile' ), array( 'movenotallowed' ) ), + array( array( 'movenotallowedfile' ), array( 'movenologintext' ) ) ); + + $this->setTitle( NS_MAIN ); + $this->setUser( 'anon' ); + $this->setUserPerm( "move" ); + $this->runGroupPermissions( 'move', array( ) ); + + $this->setUserPerm( "" ); + $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ), + array( array( 'movenologintext' ) ) ); + + $this->setUser( self::$userName ); + $this->setUserPerm( "" ); + $this->runGroupPermissions( 'move', array( array( 'movenotallowed' ) ) ); + + $this->setUserPerm( "move" ); + $this->runGroupPermissions( 'move', array( ) ); + + $this->setUser( 'anon' ); + $this->setUserPerm( 'move' ); + $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); + $this->assertEquals( array( ), $res ); + + $this->setUserPerm( '' ); + $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); + $this->assertEquals( array( array( 'movenotallowed' ) ), $res ); + + $this->setTitle( NS_USER ); + $this->setUser( self::$userName ); + $this->setUserPerm( array( "move", "move-rootuserpages" ) ); + $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); + $this->assertEquals( array( ), $res ); + + $this->setUserPerm( "move" ); + $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); + $this->assertEquals( array( array( 'cant-move-to-user-page' ) ), $res ); + + $this->setUser( 'anon' ); + $this->setUserPerm( array( "move", "move-rootuserpages" ) ); + $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); + $this->assertEquals( array( ), $res ); + + $this->setTitle( NS_USER, "User/subpage" ); + $this->setUserPerm( array( "move", "move-rootuserpages" ) ); + $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); + $this->assertEquals( array( ), $res ); + + $this->setUserPerm( "move" ); + $res = self::$title->getUserPermissionsErrors( 'move-target', self::$user ); + $this->assertEquals( array( ), $res ); + + $this->setUser( 'anon' ); + $check = array( 'edit' => array( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ) ), + array( array( 'badaccess-group0' ) ), + array( ), true ), + 'protect' => array( array( array( 'badaccess-groups', "[[$prefix:Administrators|Administrators]]", 1 ), array( 'protect-cantedit' ) ), + array( array( 'badaccess-group0' ), array( 'protect-cantedit' ) ), + array( array( 'protect-cantedit' ) ), false ), + '' => array( array( ), array( ), array( ), true ) ); + global $wgUser; + $wgUser = self::$user; + foreach ( array( "edit", "protect", "" ) as $action ) { + $this->setUserPerm( null ); + $this->assertEquals( $check[$action][0], + self::$title->getUserPermissionsErrors( $action, self::$user, true ) ); + + global $wgGroupPermissions; + $old = $wgGroupPermissions; + $wgGroupPermissions = array(); + + $this->assertEquals( $check[$action][1], + self::$title->getUserPermissionsErrors( $action, self::$user, true ) ); + $wgGroupPermissions = $old; + + $this->setUserPerm( $action ); + $this->assertEquals( $check[$action][2], + self::$title->getUserPermissionsErrors( $action, self::$user, true ) ); + + $this->setUserPerm( $action ); + $this->assertEquals( $check[$action][3], + self::$title->userCan( $action, true ) ); + $this->assertEquals( $check[$action][3], + self::$title->quickUserCan( $action, false ) ); + + # count( User::getGroupsWithPermissions( $action ) ) < 1 + } + } + + function runGroupPermissions( $action, $result, $result2 = null ) { + global $wgGroupPermissions; + + if ( $result2 === null ) $result2 = $result; + + $wgGroupPermissions['autoconfirmed']['move'] = false; + $wgGroupPermissions['user']['move'] = false; + $res = self::$title->getUserPermissionsErrors( $action, self::$user ); + $this->assertEquals( $result, $res ); + + $wgGroupPermissions['autoconfirmed']['move'] = true; + $wgGroupPermissions['user']['move'] = false; + $res = self::$title->getUserPermissionsErrors( $action, self::$user ); + $this->assertEquals( $result2, $res ); + + $wgGroupPermissions['autoconfirmed']['move'] = true; + $wgGroupPermissions['user']['move'] = true; + $res = self::$title->getUserPermissionsErrors( $action, self::$user ); + $this->assertEquals( $result2, $res ); + + $wgGroupPermissions['autoconfirmed']['move'] = false; + $wgGroupPermissions['user']['move'] = true; + $res = self::$title->getUserPermissionsErrors( $action, self::$user ); + $this->assertEquals( $result2, $res ); + } + + function testPermissionHooks() { } + function testSpecialsAndNSPermissions() { + $this->setUser( self::$userName ); + global $wgUser, $wgContLang; + $wgUser = self::$user; + $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); + + $this->setTitle( NS_SPECIAL ); + + $this->assertEquals( array( array( 'badaccess-group0' ), array( 'ns-specialprotected' ) ), + self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); + $this->assertEquals( array( array( 'badaccess-groups', "*, [[$prefix:Administrators|Administrators]]", 2 ) ), + self::$title->getUserPermissionsErrors( 'createaccount', self::$user ) ); + $this->assertEquals( array( array( 'badaccess-group0' ) ), + self::$title->getUserPermissionsErrors( 'execute', self::$user ) ); + + $this->setTitle( NS_MAIN ); + $this->setUserPerm( 'bogus' ); + $this->assertEquals( array( ), + self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); + + $this->setTitle( NS_MAIN ); + $this->setUserPerm( '' ); + $this->assertEquals( array( array( 'badaccess-group0' ) ), + self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); + + global $wgNamespaceProtection; + $wgNamespaceProtection[NS_USER] = array ( 'bogus' ); + $this->setTitle( NS_USER ); + $this->setUserPerm( '' ); + $this->assertEquals( array( array( 'badaccess-group0' ), array( 'namespaceprotected', 'User' ) ), + self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); + + $this->setTitle( NS_MEDIAWIKI ); + $this->setUserPerm( 'bogus' ); + $this->assertEquals( array( array( 'protectedinterface' ) ), + self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); + + $this->setTitle( NS_MEDIAWIKI ); + $this->setUserPerm( 'bogus' ); + $this->assertEquals( array( array( 'protectedinterface' ) ), + self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); + + $wgNamespaceProtection = null; + $this->setUserPerm( 'bogus' ); + $this->assertEquals( array( ), + self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); + $this->assertEquals( true, + self::$title->userCan( 'bogus' ) ); + + $this->setUserPerm( '' ); + $this->assertEquals( array( array( 'badaccess-group0' ) ), + self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); + $this->assertEquals( false, + self::$title->userCan( 'bogus' ) ); + } + + function testCSSandJSPermissions() { + $this->setUser( self::$userName ); + global $wgUser; + $wgUser = self::$user; + + $this->setTitle( NS_USER, self::$altUserName . '/test.js' ); + $this->runCSSandJSPermissions( + array( array( 'badaccess-group0' ), array( 'customcssjsprotected' ) ), + array( array( 'badaccess-group0' ), array( 'customcssjsprotected' ) ), + array( array( 'badaccess-group0' ) ) ); + + $this->setTitle( NS_USER, self::$altUserName . '/test.css' ); + $this->runCSSandJSPermissions( + array( array( 'badaccess-group0' ), array( 'customcssjsprotected' ) ), + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ), array( 'customcssjsprotected' ) ) ); + + $this->setTitle( NS_USER, self::$altUserName . '/tempo' ); + $this->runCSSandJSPermissions( + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ) ), + array( array( 'badaccess-group0' ) ) ); + } + + function runCSSandJSPermissions( $result0, $result1, $result2 ) { + $this->setUserPerm( '' ); + $this->assertEquals( $result0, + self::$title->getUserPermissionsErrors( 'bogus', + self::$user ) ); + + $this->setUserPerm( 'editusercss' ); + $this->assertEquals( $result1, + self::$title->getUserPermissionsErrors( 'bogus', + self::$user ) ); + + $this->setUserPerm( 'edituserjs' ); + $this->assertEquals( $result2, + self::$title->getUserPermissionsErrors( 'bogus', + self::$user ) ); + + $this->setUserPerm( 'editusercssjs' ); + $this->assertEquals( array( array( 'badaccess-group0' ) ), + self::$title->getUserPermissionsErrors( 'bogus', + self::$user ) ); + + $this->setUserPerm( array( 'edituserjs', 'editusercss' ) ); + $this->assertEquals( array( array( 'badaccess-group0' ) ), + self::$title->getUserPermissionsErrors( 'bogus', + self::$user ) ); + } + + function testPageRestrictions() { + global $wgUser, $wgContLang; + + $prefix = $wgContLang->getFormattedNsText( NS_PROJECT ); + + $wgUser = self::$user; + $this->setTitle( NS_MAIN ); + self::$title->mRestrictionsLoaded = true; + $this->setUserPerm( "edit" ); + self::$title->mRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) ); + + $this->assertEquals( array( ), + self::$title->getUserPermissionsErrors( 'edit', + self::$user ) ); + + $this->assertEquals( true, + self::$title->quickUserCan( 'edit', false ) ); + self::$title->mRestrictions = array( "edit" => array( 'bogus', "sysop", "protect", "" ), + "bogus" => array( 'bogus', "sysop", "protect", "" ) ); + + $this->assertEquals( array( array( 'badaccess-group0' ), + array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'protect' ) ), + self::$title->getUserPermissionsErrors( 'bogus', + self::$user ) ); + $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'protect' ) ), + self::$title->getUserPermissionsErrors( 'edit', + self::$user ) ); + $this->setUserPerm( "" ); + $this->assertEquals( array( array( 'badaccess-group0' ), + array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'protect' ) ), + self::$title->getUserPermissionsErrors( 'bogus', + self::$user ) ); + $this->assertEquals( array( array( 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ), + array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'protect' ) ), + self::$title->getUserPermissionsErrors( 'edit', + self::$user ) ); + $this->setUserPerm( array( "edit", "editprotected" ) ); + $this->assertEquals( array( array( 'badaccess-group0' ), + array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'protect' ) ), + self::$title->getUserPermissionsErrors( 'bogus', + self::$user ) ); + $this->assertEquals( array( ), + self::$title->getUserPermissionsErrors( 'edit', + self::$user ) ); + self::$title->mCascadeRestriction = true; + $this->assertEquals( false, + self::$title->quickUserCan( 'bogus', false ) ); + $this->assertEquals( false, + self::$title->quickUserCan( 'edit', false ) ); + $this->assertEquals( array( array( 'badaccess-group0' ), + array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'protect' ) ), + self::$title->getUserPermissionsErrors( 'bogus', + self::$user ) ); + $this->assertEquals( array( array( 'protectedpagetext', 'bogus' ), + array( 'protectedpagetext', 'protect' ), + array( 'protectedpagetext', 'protect' ) ), + self::$title->getUserPermissionsErrors( 'edit', + self::$user ) ); + } + + function testCascadingSourcesRestrictions() { + global $wgUser; + $wgUser = self::$user; + $this->setTitle( NS_MAIN, "test page" ); + $this->setUserPerm( array( "edit", "bogus" ) ); + + self::$title->mCascadeSources = array( Title::makeTitle( NS_MAIN, "Bogus" ), Title::makeTitle( NS_MAIN, "UnBogus" ) ); + self::$title->mCascadingRestrictions = array( "bogus" => array( 'bogus', "sysop", "protect", "" ) ); + + $this->assertEquals( false, + self::$title->userCan( 'bogus' ) ); + $this->assertEquals( array( array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ), + array( "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n" ) ), + self::$title->getUserPermissionsErrors( 'bogus', self::$user ) ); + + $this->assertEquals( true, + self::$title->userCan( 'edit' ) ); + $this->assertEquals( array( ), + self::$title->getUserPermissionsErrors( 'edit', self::$user ) ); + + } + + function testActionPermissions() { + global $wgUser; + $wgUser = self::$user; + + $this->setUserPerm( array( "createpage" ) ); + $this->setTitle( NS_MAIN, "test page" ); + self::$title->mTitleProtection['pt_create_perm'] = ''; + self::$title->mTitleProtection['pt_user'] = self::$user->getID(); + self::$title->mTitleProtection['pt_expiry'] = Block::infinity(); + self::$title->mTitleProtection['pt_reason'] = 'test'; + self::$title->mCascadeRestriction = false; + + $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), + self::$title->getUserPermissionsErrors( 'create', self::$user ) ); + $this->assertEquals( false, + self::$title->userCan( 'create' ) ); + + self::$title->mTitleProtection['pt_create_perm'] = 'sysop'; + $this->setUserPerm( array( 'createpage', 'protect' ) ); + $this->assertEquals( array( ), + self::$title->getUserPermissionsErrors( 'create', self::$user ) ); + $this->assertEquals( true, + self::$title->userCan( 'create' ) ); + + + $this->setUserPerm( array( 'createpage' ) ); + $this->assertEquals( array( array( 'titleprotected', 'Useruser', 'test' ) ), + self::$title->getUserPermissionsErrors( 'create', self::$user ) ); + $this->assertEquals( false, + self::$title->userCan( 'create' ) ); + + $this->setTitle( NS_MEDIA, "test page" ); + $this->setUserPerm( array( "move" ) ); + $this->assertEquals( false, + self::$title->userCan( 'move' ) ); + $this->assertEquals( array( array( 'immobile-source-namespace', 'Media' ) ), + self::$title->getUserPermissionsErrors( 'move', self::$user ) ); + + $this->setTitle( NS_MAIN, "test page" ); + $this->assertEquals( array( ), + self::$title->getUserPermissionsErrors( 'move', self::$user ) ); + $this->assertEquals( true, + self::$title->userCan( 'move' ) ); + + self::$title->mInterwiki = "no"; + $this->assertEquals( array( array( 'immobile-page' ) ), + self::$title->getUserPermissionsErrors( 'move', self::$user ) ); + $this->assertEquals( false, + self::$title->userCan( 'move' ) ); + + $this->setTitle( NS_MEDIA, "test page" ); + $this->assertEquals( false, + self::$title->userCan( 'move-target' ) ); + $this->assertEquals( array( array( 'immobile-target-namespace', 'Media' ) ), + self::$title->getUserPermissionsErrors( 'move-target', self::$user ) ); + + $this->setTitle( NS_MAIN, "test page" ); + $this->assertEquals( array( ), + self::$title->getUserPermissionsErrors( 'move-target', self::$user ) ); + $this->assertEquals( true, + self::$title->userCan( 'move-target' ) ); + + self::$title->mInterwiki = "no"; + $this->assertEquals( array( array( 'immobile-target-page' ) ), + self::$title->getUserPermissionsErrors( 'move-target', self::$user ) ); + $this->assertEquals( false, + self::$title->userCan( 'move-target' ) ); + + } + + function testUserBlock() { + global $wgUser, $wgEmailConfirmToEdit, $wgEmailAuthentication; + $wgEmailConfirmToEdit = true; + $wgEmailAuthentication = true; + $wgUser = self::$user; + + $this->setUserPerm( array( "createpage", "move" ) ); + $this->setTitle( NS_MAIN, "test page" ); + + # $short + $this->assertEquals( array( array( 'confirmedittext' ) ), + self::$title->getUserPermissionsErrors( 'move-target', self::$user ) ); + $this->assertEquals( true, self::$title->userCan( 'move-target' ) ); + + $wgEmailConfirmToEdit = false; + # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount' + $this->assertEquals( array( ), + self::$title->getUserPermissionsErrors( 'move-target', + self::$user ) ); + + global $wgLang; + $prev = time(); + $now = time() + 120; + self::$user->mBlockedby = self::$user->getId(); + self::$user->mBlock = new Block( '127.0.8.1', self::$user->getId(), self::$user->getId(), + 'no reason given', $prev + 3600, 1, 0 ); + self::$user->mBlock->mTimestamp = 0; + $this->assertEquals( array( array( 'autoblockedtext', + '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', + 'Useruser', 0, 'infinite', '127.0.8.1', + $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ) ), + self::$title->getUserPermissionsErrors( 'move-target', + self::$user ) ); + + $this->assertEquals( true, + self::$title->userCan( 'move-target', self::$user ) ); + + global $wgLocalTZoffset; + $wgLocalTZoffset = -60; + self::$user->mBlockedby = self::$user->getName(); + self::$user->mBlock = new Block( '127.0.8.1', 2, 1, 'no reason given', $now, 0, 10 ); + $this->assertEquals( array( array( 'blockedtext', + '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', + 'Useruser', 0, '23:00, 31 December 1969', '127.0.8.1', + $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ) ), + self::$title->getUserPermissionsErrors( 'move-target', self::$user ) ); + + # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this ) + # $user->blockedFor() == '' + # $user->mBlock->mExpiry == 'infinity' + } +} diff --git a/maintenance/tests/phpunit/includes/TitleTest.php b/maintenance/tests/phpunit/includes/TitleTest.php new file mode 100644 index 0000000000..5b42c1c575 --- /dev/null +++ b/maintenance/tests/phpunit/includes/TitleTest.php @@ -0,0 +1,17 @@ +|", $chr ) !== false || preg_match( "/[\\x00-\\x1f\\x7f]/", $chr ) ) { + $this->assertFalse( (bool)preg_match( "/[$titlechars]/", $chr ), "chr($num) = $chr is not a valid titlechar" ); + } else { + $this->assertTrue( (bool)preg_match( "/[$titlechars]/", $chr ), "chr($num) = $chr is a valid titlechar" ); + } + } + } +} diff --git a/maintenance/tests/phpunit/includes/UploadFromUrlTest.php b/maintenance/tests/phpunit/includes/UploadFromUrlTest.php new file mode 100644 index 0000000000..c2c244630b --- /dev/null +++ b/maintenance/tests/phpunit/includes/UploadFromUrlTest.php @@ -0,0 +1,349 @@ +exists() ) { + $this->deleteFile( 'UploadFromUrlTest.png' ); + } + } + + protected function doApiRequest( $params ) { + $sessionId = session_id(); + session_write_close(); + + $req = new FauxRequest( $params, true, $_SESSION ); + $module = new ApiMain( $req, true ); + $module->execute(); + + wfSetupSession( $sessionId ); + return array( $module->getResultData(), $req ); + } + + /** + * Ensure that the job queue is empty before continuing + */ + public function testClearQueue() { + while ( $job = Job::pop() ) { } + $this->assertFalse( $job ); + } + + /** + * @todo Document why we test login, since the $wgUser hack used doesn't + * require login + */ + public function testLogin() { + $data = $this->doApiRequest( array( + 'action' => 'login', + 'lgname' => self::$userName, + 'lgpassword' => self::$passWord ) ); + $this->assertArrayHasKey( "login", $data[0] ); + $this->assertArrayHasKey( "result", $data[0]['login'] ); + $this->assertEquals( "NeedToken", $data[0]['login']['result'] ); + $token = $data[0]['login']['token']; + + $data = $this->doApiRequest( array( + 'action' => 'login', + "lgtoken" => $token, + "lgname" => self::$userName, + "lgpassword" => self::$passWord ) ); + + $this->assertArrayHasKey( "login", $data[0] ); + $this->assertArrayHasKey( "result", $data[0]['login'] ); + $this->assertEquals( "Success", $data[0]['login']['result'] ); + $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] ); + + return $data; + } + + /** + * @depends testLogin + * @depends testClearQueue + */ + public function testSetupUrlDownload( $data ) { + $token = self::$user->editToken(); + $exception = false; + + try { + $this->doApiRequest( array( + 'action' => 'upload', + ) ); + } catch ( UsageException $e ) { + $exception = true; + $this->assertEquals( "The token parameter must be set", $e->getMessage() ); + } + $this->assertTrue( $exception, "Got exception" ); + + $exception = false; + try { + $this->doApiRequest( array( + 'action' => 'upload', + 'token' => $token, + ), $data ); + } catch ( UsageException $e ) { + $exception = true; + $this->assertEquals( "One of the parameters sessionkey, file, url, statuskey is required", + $e->getMessage() ); + } + $this->assertTrue( $exception, "Got exception" ); + + $exception = false; + try { + $this->doApiRequest( array( + 'action' => 'upload', + 'url' => 'http://www.example.com/test.png', + 'token' => $token, + ), $data ); + } catch ( UsageException $e ) { + $exception = true; + $this->assertEquals( "The filename parameter must be set", $e->getMessage() ); + } + $this->assertTrue( $exception, "Got exception" ); + + self::$user->removeGroup( 'sysop' ); + $exception = false; + try { + $this->doApiRequest( array( + 'action' => 'upload', + 'url' => 'http://www.example.com/test.png', + 'filename' => 'UploadFromUrlTest.png', + 'token' => $token, + ), $data ); + } catch ( UsageException $e ) { + $exception = true; + $this->assertEquals( "Permission denied", $e->getMessage() ); + } + $this->assertTrue( $exception, "Got exception" ); + + self::$user->addGroup( '*' ); + self::$user->addGroup( 'sysop' ); + $exception = false; + $data = $this->doApiRequest( array( + 'action' => 'upload', + 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', + 'asyncdownload' => 1, + 'filename' => 'UploadFromUrlTest.png', + 'token' => $token, + ), $data ); + + $this->assertEquals( $data[0]['upload']['result'], 'Queued', 'Queued upload' ); + + $job = Job::pop(); + $this->assertThat( $job, $this->isInstanceOf( 'UploadFromUrlJob' ), 'Queued upload inserted' ); + } + + /** + * @depends testLogin + * @depends testClearQueue + */ + public function testAsyncUpload( $data ) { + $token = self::$user->editToken(); + + self::$user->addGroup( 'users' ); + + $data = $this->doAsyncUpload( $token, true ); + $this->assertEquals( $data[0]['upload']['result'], 'Success' ); + $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' ); + $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() ); + + $this->deleteFile( 'UploadFromUrlTest.png' ); + + return $data; + } + + /** + * @depends testLogin + * @depends testClearQueue + */ + public function testAsyncUploadWarning( $data ) { + $token = self::$user->editToken(); + + self::$user->addGroup( 'users' ); + + + $data = $this->doAsyncUpload( $token ); + + $this->assertEquals( $data[0]['upload']['result'], 'Warning' ); + $this->assertTrue( isset( $data[0]['upload']['sessionkey'] ) ); + + $data = $this->doApiRequest( array( + 'action' => 'upload', + 'sessionkey' => $data[0]['upload']['sessionkey'], + 'filename' => 'UploadFromUrlTest.png', + 'ignorewarnings' => 1, + 'token' => $token, + ) ); + $this->assertEquals( $data[0]['upload']['result'], 'Success' ); + $this->assertEquals( $data[0]['upload']['filename'], 'UploadFromUrlTest.png' ); + $this->assertTrue( wfLocalFile( $data[0]['upload']['filename'] )->exists() ); + + $this->deleteFile( 'UploadFromUrlTest.png' ); + + return $data; + } + + /** + * @depends testLogin + * @depends testClearQueue + */ + public function testSyncDownload( $data ) { + $token = self::$user->editToken(); + + $job = Job::pop(); + $this->assertFalse( $job, 'Starting with an empty jobqueue' ); + + self::$user->addGroup( 'users' ); + $data = $this->doApiRequest( array( + 'action' => 'upload', + 'filename' => 'UploadFromUrlTest.png', + 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', + 'ignorewarnings' => true, + 'token' => $token, + ), $data ); + + $job = Job::pop(); + $this->assertFalse( $job ); + + $this->assertEquals( 'Success', $data[0]['upload']['result'] ); + $this->deleteFile( 'UploadFromUrlTest.png' ); + + return $data; + } + + public function testLeaveMessage() { + $token = self::$user->editToken(); + + $talk = self::$user->getTalkPage(); + if ( $talk->exists() ) { + $a = new Article( $talk ); + $a->doDeleteArticle( '' ); + } + + $this->assertFalse( (bool)$talk->getArticleId( GAID_FOR_UPDATE ), 'User talk does not exist' ); + + $data = $this->doApiRequest( array( + 'action' => 'upload', + 'filename' => 'UploadFromUrlTest.png', + 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', + 'asyncdownload' => 1, + 'token' => $token, + 'leavemessage' => 1, + 'ignorewarnings' => 1, + ) ); + + $job = Job::pop(); + $job->run(); + + $this->assertTrue( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ); + $this->assertTrue( (bool)$talk->getArticleId( GAID_FOR_UPDATE ), 'User talk exists' ); + + $this->deleteFile( 'UploadFromUrlTest.png' ); + + $talkRev = Revision::newFromTitle( $talk ); + $talkSize = $talkRev->getSize(); + + $exception = false; + try { + $data = $this->doApiRequest( array( + 'action' => 'upload', + 'filename' => 'UploadFromUrlTest.png', + 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', + 'asyncdownload' => 1, + 'token' => $token, + 'leavemessage' => 1, + ) ); + } catch ( UsageException $e ) { + $exception = true; + $this->assertEquals( 'Using leavemessage without ignorewarnings is not supported', $e->getMessage() ); + } + $this->assertTrue( $exception ); + + $job = Job::pop(); + $this->assertFalse( $job ); + + return; + + // Broken until using leavemessage with ignorewarnings is supported + $job->run(); + + $this->assertFalse( wfLocalFile( 'UploadFromUrlTest.png' )->exists() ); + + $talkRev = Revision::newFromTitle( $talk ); + $this->assertTrue( $talkRev->getSize() > $talkSize, 'New message left' ); + + + } + + /** + * Helper function to perform an async upload, execute the job and fetch + * the status + * + * @return array The result of action=upload&statuskey=key + */ + private function doAsyncUpload( $token, $ignoreWarnings = false, $leaveMessage = false ) { + $params = array( + 'action' => 'upload', + 'filename' => 'UploadFromUrlTest.png', + 'url' => 'http://bits.wikimedia.org/skins-1.5/common/images/poweredby_mediawiki_88x31.png', + 'asyncdownload' => 1, + 'token' => $token, + ); + if ( $ignoreWarnings ) { + $params['ignorewarnings'] = 1; + } + if ( $leaveMessage ) { + $params['leavemessage'] = 1; + } + + $data = $this->doApiRequest( $params ); + $this->assertEquals( $data[0]['upload']['result'], 'Queued' ); + $this->assertTrue( isset( $data[0]['upload']['statuskey'] ) ); + $statusKey = $data[0]['upload']['statuskey']; + + $job = Job::pop(); + $this->assertEquals( 'UploadFromUrlJob', get_class( $job ) ); + + $status = $job->run(); + $this->assertTrue( $status ); + + $data = $this->doApiRequest( array( + 'action' => 'upload', + 'statuskey' => $statusKey, + 'token' => $token, + ) ); + + return $data; + } + + + /** + * + */ + protected function deleteFile( $name ) { + $t = Title::newFromText( $name, NS_FILE ); + $this->assertTrue($t->exists(), "File '$name' exists"); + + if ( $t->exists() ) { + $file = wfFindFile( $name, array( 'ignoreRedirect' => true ) ); + $empty = ""; + FileDeleteForm::doDelete( $t, $file, $empty, "none", true ); + $a = new Article ( $t ); + $a->doDeleteArticle( "testing" ); + } + $t = Title::newFromText( $name, NS_FILE ); + + $this->assertFalse($t->exists(), "File '$name' was deleted"); + } + } diff --git a/maintenance/tests/phpunit/includes/UploadTest.php b/maintenance/tests/phpunit/includes/UploadTest.php new file mode 100644 index 0000000000..41c9d80d56 --- /dev/null +++ b/maintenance/tests/phpunit/includes/UploadTest.php @@ -0,0 +1,90 @@ +upload = new UploadTestHandler; + } + + /** + * Test various forms of valid and invalid titles that can be supplied. + */ + public function testTitleValidation() { + + + /* Test a valid title */ + $this->assertUploadTitleAndCode( 'ValidTitle.jpg', + 'ValidTitle.jpg', UploadTestHandler::OK, + 'upload valid title' ); + + /* A title with a slash */ + $this->assertUploadTitleAndCode( 'A/B.jpg', + 'B.jpg', UploadTestHandler::OK, + 'upload title with slash' ); + + /* A title with illegal char */ + $this->assertUploadTitleAndCode( 'A:B.jpg', + 'A-B.jpg', UploadTestHandler::OK, + 'upload title with colon' ); + + /* A title without extension */ + $this->assertUploadTitleAndCode( 'A', + null, UploadTestHandler::FILETYPE_MISSING, + 'upload title without extension' ); + + /* A title with no basename */ + $this->assertUploadTitleAndCode( '.jpg', + null, UploadTestHandler::MIN_LENGTH_PARTNAME, + 'upload title without basename' ); + + } + /** + * Helper function for testTitleValidation. First checks the return code + * of UploadBase::getTitle() and then the actual returned titl + */ + private function assertUploadTitleAndCode( $srcFilename, $dstFilename, $code, $msg ) { + /* Check the result code */ + $this->assertEquals( $code, + $this->upload->testTitleValidation( $srcFilename ), + "$msg code" ); + + /* If we expect a valid title, check the title itself. */ + if ( $code == UploadTestHandler::OK ) { + $this->assertEquals( $dstFilename, + $this->upload->getTitle()->getText(), + "$msg text" ); + } + } + + /** + * Test the upload verification functions + */ + public function testVerifyUpload() { + /* Setup with zero file size */ + $this->upload->initializePathInfo( '', '', 0 ); + $result = $this->upload->verifyUpload(); + $this->assertEquals( UploadTestHandler::EMPTY_FILE, + $result['status'], + 'upload empty file' ); + } + +} + +class UploadTestHandler extends UploadBase { + public function initializeFromRequest( &$request ) { } + public function testTitleValidation( $name ) { + $this->mTitle = false; + $this->mDesiredDestName = $name; + $this->getTitle(); + return $this->mTitleError; + } + + +} diff --git a/maintenance/tests/phpunit/includes/XmlTest.php b/maintenance/tests/phpunit/includes/XmlTest.php new file mode 100644 index 0000000000..330e60c677 --- /dev/null +++ b/maintenance/tests/phpunit/includes/XmlTest.php @@ -0,0 +1,115 @@ +assertEquals( + '', + Xml::element( 'element', null, null ), + 'Opening element with no attributes' + ); + } + + function testElementEmpty() { + $this->assertEquals( + '', + Xml::element( 'element', null, '' ), + 'Terminated empty element' + ); + } + + function testElementEscaping() { + $this->assertEquals( + 'hello <there> you & you', + Xml::element( 'element', null, 'hello you & you' ), + 'Element with no attributes and content that needs escaping' + ); + } + + function testElementAttributes() { + $this->assertEquals( + '="<>">', + Xml::element( 'element', array( 'key' => 'value', '<>' => '<>' ), null ), + 'Element attributes, keys are not escaped' + ); + } + + function testOpenElement() { + $this->assertEquals( + '', + Xml::openElement( 'element', array( 'k' => 'v' ) ), + 'openElement() shortcut' + ); + } + + function testCloseElement() { + $this->assertEquals( '', Xml::closeElement( 'element' ), 'closeElement() shortcut' ); + } + + # + # textarea + # + function testTextareaNoContent() { + $this->assertEquals( + '', + Xml::textarea( 'name', '' ), + 'textarea() with not content' + ); + } + + function testTextareaAttribs() { + $this->assertEquals( + '', + Xml::textarea( 'name', '', 20, 10 ), + 'textarea() with custom attribs' + ); + } + + # + # JS + # + function testEscapeJsStringSpecialChars() { + $this->assertEquals( + '\\\\\r\n', + Xml::escapeJsString( "\\\r\n" ), + 'escapeJsString() with special characters' + ); + } + + function testEncodeJsVarBoolean() { + $this->assertEquals( + 'true', + Xml::encodeJsVar( true ), + 'encodeJsVar() with boolean' + ); + } + + function testEncodeJsVarNull() { + $this->assertEquals( + 'null', + Xml::encodeJsVar( null ), + 'encodeJsVar() with null' + ); + } + + function testEncodeJsVarArray() { + $this->assertEquals( + '["a", 1]', + Xml::encodeJsVar( array( 'a', 1 ) ), + 'encodeJsVar() with array' + ); + $this->assertEquals( + '{"a": "a", "b": 1}', + Xml::encodeJsVar( array( 'a' => 'a', 'b' => 1 ) ), + 'encodeJsVar() with associative array' + ); + } + + function testEncodeJsVarObject() { + $this->assertEquals( + '{"a": "a", "b": 1}', + Xml::encodeJsVar( (object)array( 'a' => 'a', 'b' => 1 ) ), + 'encodeJsVar() with object' + ); + } +} diff --git a/maintenance/tests/phpunit/includes/api/ApiSetup.php b/maintenance/tests/phpunit/includes/api/ApiSetup.php new file mode 100644 index 0000000000..51d2ff67b5 --- /dev/null +++ b/maintenance/tests/phpunit/includes/api/ApiSetup.php @@ -0,0 +1,39 @@ +getID() ) { + self::$user = User::createNew( self::$userName, array( + "email" => "test@example.com", + "real_name" => "Test User" ) ); + } + self::$user->setPassword( self::$passWord ); + self::$user->saveSettings(); + } + + $GLOBALS['wgUser'] = self::$user; + } +} diff --git a/maintenance/tests/phpunit/includes/api/ApiTest.php b/maintenance/tests/phpunit/includes/api/ApiTest.php new file mode 100644 index 0000000000..02d480c1bd --- /dev/null +++ b/maintenance/tests/phpunit/includes/api/ApiTest.php @@ -0,0 +1,222 @@ + null, + 'enablechunks' => false, + 'sessionkey' => null, + ); + } +} + +class ApiTest extends ApiTestSetup { + + function setup() { + parent::setup(); + } + + function testRequireOnlyOneParameterDefault() { + $mock = new MockApi(); + + $this->assertEquals( + null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", + "enablechunks" => false ), "filename", "enablechunks" ) ); + } + + /** + * @expectedException UsageException + */ + function testRequireOnlyOneParameterZero() { + $mock = new MockApi(); + + $this->assertEquals( + null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", + "enablechunks" => 0 ), "filename", "enablechunks" ) ); + } + + /** + * @expectedException UsageException + */ + function testRequireOnlyOneParameterTrue() { + $mock = new MockApi(); + + $this->assertEquals( + null, $mock->requireOnlyOneParameter( array( "filename" => "foo.txt", + "enablechunks" => true ), "filename", "enablechunks" ) ); + } + + function testApi() { + global $wgServerName, $wgServer; + + if ( !isset( $wgServerName ) || !isset( $wgServer ) ) { + $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . + 'be set in LocalSettings.php' ); + } + /* Haven't thought about test ordering yet -- but this depends on HttpTest.php */ + $resp = Http::get( self::$apiUrl . "?format=xml" ); + + libxml_use_internal_errors( true ); + $sxe = simplexml_load_string( $resp ); + $this->assertNotType( "bool", $sxe ); + $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); + } + + function testApiLoginNoName() { + global $wgServerName, $wgServer; + + if ( !isset( $wgServerName ) || !isset( $wgServer ) ) { + $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . + 'be set in LocalSettings.php' ); + } + $resp = Http::post( self::$apiUrl . "?action=login&format=xml", + array( "postData" => array( + "lgname" => "", + "lgpassword" => self::$passWord ) ) ); + libxml_use_internal_errors( true ); + $sxe = simplexml_load_string( $resp ); + $this->assertNotType( "bool", $sxe ); + $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); + $a = $sxe->login[0]->attributes()->result; + $this->assertEquals( ' result="NoName"', $a->asXML() ); + } + + function testApiLoginBadPass() { + global $wgServerName, $wgServer; + + if ( !isset( $wgServerName ) || !isset( $wgServer ) ) { + $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . + 'be set in LocalSettings.php' ); + } + $resp = Http::post( self::$apiUrl . "?action=login&format=xml", + array( "postData" => array( + "lgname" => self::$userName, + "lgpassword" => "bad" ) ) ); + libxml_use_internal_errors( true ); + $sxe = simplexml_load_string( $resp ); + $this->assertNotType( "bool", $sxe ); + $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); + $a = $sxe->login[0]->attributes()->result[0]; + $this->assertEquals( ' result="NeedToken"', $a->asXML() ); + + $token = (string)$sxe->login[0]->attributes()->token; + + $resp = Http::post( self::$apiUrl . "?action=login&format=xml", + array( "postData" => array( + "lgtoken" => $token, + "lgname" => self::$userName, + "lgpassword" => "bad" ) ) ); + + + $sxe = simplexml_load_string( $resp ); + $this->assertNotType( "bool", $sxe ); + $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); + $a = $sxe->login[0]->attributes()->result[0]; + + $this->assertEquals( ' result="NeedToken"', $a->asXML() ); + } + + function testApiLoginGoodPass() { + global $wgServerName, $wgServer; + + if ( !isset( $wgServerName ) || !isset( $wgServer ) ) { + $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . + 'be set in LocalSettings.php' ); + } + $req = HttpRequest::factory( self::$apiUrl . "?action=login&format=xml", + array( "method" => "POST", + "postData" => array( + "lgname" => self::$userName, + "lgpassword" => self::$passWord ) ) ); + $req->execute(); + + libxml_use_internal_errors( true ); + $sxe = simplexml_load_string( $req->getContent() ); + $this->assertNotType( "bool", $sxe ); + $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); + + $a = $sxe->login[0]->attributes()->result[0]; + $this->assertEquals( ' result="NeedToken"', $a->asXML() ); + $token = (string)$sxe->login[0]->attributes()->token; + + $req->setData( array( + "lgtoken" => $token, + "lgname" => self::$userName, + "lgpassword" => self::$passWord ) ); + $req->execute(); + + $sxe = simplexml_load_string( $req->getContent() ); + + $this->assertNotType( "bool", $sxe ); + $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); + $a = $sxe->login[0]->attributes()->result[0]; + + $this->assertEquals( ' result="Success"', $a->asXML() ); + } + + function testApiGotCookie() { + global $wgServerName, $wgServer, $wgScriptPath; + + if ( !isset( $wgServerName ) || !isset( $wgServer ) ) { + $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . + 'be set in LocalSettings.php' ); + } + $req = HttpRequest::factory( self::$apiUrl . "?action=login&format=xml", + array( "method" => "POST", + "postData" => array( + "lgname" => self::$userName, + "lgpassword" => self::$passWord ) ) ); + $req->execute(); + + libxml_use_internal_errors( true ); + $sxe = simplexml_load_string( $req->getContent() ); + $this->assertNotType( "bool", $sxe ); + $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); + + $a = $sxe->login[0]->attributes()->result[0]; + $this->assertEquals( ' result="NeedToken"', $a->asXML() ); + $token = (string)$sxe->login[0]->attributes()->token; + + $req->setData( array( + "lgtoken" => $token, + "lgname" => self::$userName, + "lgpassword" => self::$passWord ) ); + $req->execute(); + + $cj = $req->getCookieJar(); + $this->assertRegexp( '/_session=[^;]*; .*UserID=[0-9]*; .*UserName=' . self::$userName . '; .*Token=/', + $cj->serializeToHttpRequest( $wgScriptPath, $wgServerName ) ); + + + return $cj; + } + + /** + * @depends testApiGotCookie + */ + function testApiListPages( CookieJar $cj ) { + $this->markTestIncomplete( "Not done with this yet" ); + global $wgServerName, $wgServer; + + if ( $wgServerName == "localhost" || $wgServer == "http://localhost" ) { + $this->markTestIncomplete( 'This test needs $wgServerName and $wgServer to ' . + 'be set in LocalSettings.php' ); + } + $req = HttpRequest::factory( self::$apiUrl . "?action=query&format=xml&prop=revisions&" . + "titles=Main%20Page&rvprop=timestamp|user|comment|content" ); + $req->setCookieJar( $cj ); + $req->execute(); + libxml_use_internal_errors( true ); + $sxe = simplexml_load_string( $req->getContent() ); + $this->assertNotType( "bool", $sxe ); + $this->assertThat( $sxe, $this->isInstanceOf( "SimpleXMLElement" ) ); + $a = $sxe->query[0]->pages[0]->page[0]->attributes(); + } +} diff --git a/maintenance/tests/phpunit/includes/api/ApiWatchTest.php b/maintenance/tests/phpunit/includes/api/ApiWatchTest.php new file mode 100644 index 0000000000..e12e46d597 --- /dev/null +++ b/maintenance/tests/phpunit/includes/api/ApiWatchTest.php @@ -0,0 +1,211 @@ +execute(); + + $data[0] = $module->getResultData(); + $data[1] = $req; + $data[2] = $_SESSION; + + return $data; + } + + function testLogin() { + $data = $this->doApiRequest( array( + 'action' => 'login', + 'lgname' => 'WikiSysop', + 'lgpassword' => 'none' ), $data ); + + $this->assertArrayHasKey( "login", $data[0] ); + $this->assertArrayHasKey( "result", $data[0]['login'] ); + $this->assertEquals( "NeedToken", $data[0]['login']['result'] ); + $token = $data[0]['login']['token']; + + $data = $this->doApiRequest( array( + 'action' => 'login', + "lgtoken" => $token, + "lgname" => 'WikiSysop', + "lgpassword" => 'none' ), $data ); + + $this->assertArrayHasKey( "login", $data[0] ); + $this->assertArrayHasKey( "result", $data[0]['login'] ); + $this->assertEquals( "Success", $data[0]['login']['result'] ); + $this->assertArrayHasKey( 'lgtoken', $data[0]['login'] ); + + return $data; + } + + function testGetToken() { + + $data = $this->doApiRequest( array( + 'action' => 'query', + 'titles' => 'Main Page', + 'intoken' => 'edit|delete|protect|move|block|unblock', + 'prop' => 'info' ), $data ); + + $this->assertArrayHasKey( 'query', $data[0] ); + $this->assertArrayHasKey( 'pages', $data[0]['query'] ); + $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); + + $this->assertArrayHasKey( $key, $data[0]['query']['pages'] ); + $this->assertArrayHasKey( 'edittoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'movetoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'deletetoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'blocktoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'unblocktoken', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'protecttoken', $data[0]['query']['pages'][$key] ); + + return $data; + } + + /** + * @depends testGetToken + */ + function testWatchEdit( $data ) { + $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); + $pageinfo = $data[0]['query']['pages'][$key]; + + $data = $this->doApiRequest( array( + 'action' => 'edit', + 'title' => 'Main Page', + 'text' => 'new text', + 'token' => $pageinfo['edittoken'], + 'watchlist' => 'watch' ), $data ); + $this->assertArrayHasKey( 'edit', $data[0] ); + $this->assertArrayHasKey( 'result', $data[0]['edit'] ); + $this->assertEquals( 'Success', $data[0]['edit']['result'] ); + + return $data; + } + + + /** + * @depends testWatchEdit + */ + function testWatchClear( $data ) { + $data = $this->doApiRequest( array( + 'action' => 'query', + 'list' => 'watchlist' ), $data ); + + if ( isset( $data[0]['query']['watchlist'] ) ) { + $wl = $data[0]['query']['watchlist']; + + foreach ( $wl as $page ) { + $data = $this->doApiRequest( array( + 'action' => 'watch', + 'title' => $page['title'], + 'unwatch' => true ), $data ); + } + } + $data = $this->doApiRequest( array( + 'action' => 'query', + 'list' => 'watchlist' ), $data ); + $this->assertArrayHasKey( 'query', $data[0] ); + $this->assertArrayHasKey( 'watchlist', $data[0]['query'] ); + $this->assertEquals( 0, count( $data[0]['query']['watchlist'] ) ); + + return $data; + } + + /** + * @depends testGetToken + */ + function testWatchProtect( $data ) { + $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); + $pageinfo = $data[0]['query']['pages'][$key]; + + $data = $this->doApiRequest( array( + 'action' => 'protect', + 'token' => $pageinfo['protecttoken'], + 'title' => 'Main Page', + 'protections' => 'edit=sysop', + 'watchlist' => 'unwatch' ), $data ); + + $this->assertArrayHasKey( 'protect', $data[0] ); + $this->assertArrayHasKey( 'protections', $data[0]['protect'] ); + $this->assertEquals( 1, count( $data[0]['protect']['protections'] ) ); + $this->assertArrayHasKey( 'edit', $data[0]['protect']['protections'][0] ); + } + + /** + * @depends testGetToken + */ + function testGetRollbackToken( $data ) { + $data = $this->doApiRequest( array( + 'action' => 'query', + 'prop' => 'revisions', + 'titles' => 'Main Page', + 'rvtoken' => 'rollback' ), $data ); + + $this->assertArrayHasKey( 'query', $data[0] ); + $this->assertArrayHasKey( 'pages', $data[0]['query'] ); + $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); + + $this->assertArrayHasKey( 'pageid', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 'revisions', $data[0]['query']['pages'][$key] ); + $this->assertArrayHasKey( 0, $data[0]['query']['pages'][$key]['revisions'] ); + $this->assertArrayHasKey( 'rollbacktoken', $data[0]['query']['pages'][$key]['revisions'][0] ); + + return $data; + } + + /** + * @depends testGetRollbackToken + */ + function testWatchRollback( $data ) { + $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); + $pageinfo = $data[0]['query']['pages'][$key]['revisions'][0]; + + $data = $this->doApiRequest( array( + 'action' => 'rollback', + 'title' => 'Main Page', + 'user' => 'WikiSysop', + 'token' => $pageinfo['rollbacktoken'], + 'watchlist' => 'watch' ), $data ); + + $this->assertArrayHasKey( 'rollback', $data[0] ); + $this->assertArrayHasKey( 'title', $data[0]['rollback'] ); + } + + /** + * @depends testGetToken + */ + function testWatchDelete( $data ) { + $key = array_pop( array_keys( $data[0]['query']['pages'] ) ); + $pageinfo = $data[0]['query']['pages'][$key]; + + $data = $this->doApiRequest( array( + 'action' => 'delete', + 'token' => $pageinfo['deletetoken'], + 'title' => 'Main Page' ), $data ); + $this->assertArrayHasKey( 'delete', $data[0] ); + $this->assertArrayHasKey( 'title', $data[0]['delete'] ); + + $data = $this->doApiRequest( array( + 'action' => 'query', + 'list' => 'watchlist' ), $data ); + } + +} diff --git a/maintenance/tests/phpunit/includes/db/DatabaseSqliteTest.php b/maintenance/tests/phpunit/includes/db/DatabaseSqliteTest.php new file mode 100644 index 0000000000..29ce6383be --- /dev/null +++ b/maintenance/tests/phpunit/includes/db/DatabaseSqliteTest.php @@ -0,0 +1,70 @@ +lastQuery = $sql; + return true; + } + + function replaceVars( $s ) { + return parent::replaceVars( $s ); + } +} + +class DatabaseSqliteTest extends PHPUnit_Framework_TestCase { + var $db; + + function setup() { + if ( !Sqlite::isPresent() ) { + $this->markTestIncomplete( 'No SQLite support detected' ); + } + $this->db = new MockDatabaseSqlite(); + } + + function replaceVars( $sql ) { + // normalize spacing to hide implementation details + return preg_replace( '/\s+/', ' ', $this->db->replaceVars( $sql ) ); + } + + function testReplaceVars() { + $this->assertEquals( 'foo', $this->replaceVars( 'foo' ), "Don't break anything accidentally" ); + + $this->assertEquals( "CREATE TABLE /**/foo (foo_key INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " + . "foo_bar TEXT, foo_name TEXT NOT NULL DEFAULT '', foo_int INTEGER, foo_int2 INTEGER );", + $this->replaceVars( "CREATE TABLE /**/foo (foo_key int unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT, + foo_bar char(13), foo_name varchar(255) binary NOT NULL DEFAULT '', foo_int tinyint ( 8 ), foo_int2 int(16) ) ENGINE=MyISAM;" ) + ); + + $this->assertEquals( "CREATE TABLE foo ( foo_binary1 BLOB, foo_binary2 BLOB );", + $this->replaceVars( "CREATE TABLE foo ( foo_binary1 binary(16), foo_binary2 varbinary(32) );" ) + ); + + $this->assertEquals( "CREATE TABLE text ( text_foo TEXT );", + $this->replaceVars( "CREATE TABLE text ( text_foo tinytext );" ), + 'Table name changed' + ); + + $this->assertEquals( "CREATE TABLE enums( enum1 TEXT, myenum TEXT)", + $this->replaceVars( "CREATE TABLE enums( enum1 ENUM('A', 'B'), myenum ENUM ('X', 'Y'))" ) + ); + + $this->assertEquals( "ALTER TABLE foo ADD COLUMN foo_bar INTEGER DEFAULT 42", + $this->replaceVars( "ALTER TABLE foo\nADD COLUMN foo_bar int(10) unsigned DEFAULT 42" ) + ); + } + + function testEntireSchema() { + global $IP; + + $result = Sqlite::checkSqlSyntax( "$IP/maintenance/tables.sql" ); + if ( $result !== true ) { + $this->fail( $result ); + } + } +} \ No newline at end of file diff --git a/maintenance/tests/phpunit/includes/db/DatabaseTest.php b/maintenance/tests/phpunit/includes/db/DatabaseTest.php new file mode 100644 index 0000000000..96a1c1af22 --- /dev/null +++ b/maintenance/tests/phpunit/includes/db/DatabaseTest.php @@ -0,0 +1,92 @@ +db = wfGetDB( DB_SLAVE ); + } + + function testAddQuotesNull() { + $check = "NULL"; + if ( $this->db->getType() === 'sqlite' ) { + $check = "''"; + } + $this->assertEquals( $check, $this->db->addQuotes( null ) ); + } + + function testAddQuotesInt() { + # returning just "1234" should be ok too, though... + # maybe + $this->assertEquals( + "'1234'", + $this->db->addQuotes( 1234 ) ); + } + + function testAddQuotesFloat() { + # returning just "1234.5678" would be ok too, though + $this->assertEquals( + "'1234.5678'", + $this->db->addQuotes( 1234.5678 ) ); + } + + function testAddQuotesString() { + $this->assertEquals( + "'string'", + $this->db->addQuotes( 'string' ) ); + } + + function testAddQuotesStringQuote() { + $check = "'string''s cause trouble'"; + if ( $this->db->getType() === 'mysql' ) { + $check = "'string\'s cause trouble'"; + } + $this->assertEquals( + $check, + $this->db->addQuotes( "string's cause trouble" ) ); + } + + function testFillPreparedEmpty() { + $sql = $this->db->fillPrepared( + 'SELECT * FROM interwiki', array() ); + $this->assertEquals( + "SELECT * FROM interwiki", + $sql ); + } + + function testFillPreparedQuestion() { + $sql = $this->db->fillPrepared( + 'SELECT * FROM cur WHERE cur_namespace=? AND cur_title=?', + array( 4, "Snicker's_paradox" ) ); + + $check = "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker''s_paradox'"; + if ( $this->db->getType() === 'mysql' ) { + $check = "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker\'s_paradox'"; + } + $this->assertEquals( $check, $sql ); + } + + function testFillPreparedBang() { + $sql = $this->db->fillPrepared( + 'SELECT user_id FROM ! WHERE user_name=?', + array( '"user"', "Slash's Dot" ) ); + + $check = "SELECT user_id FROM \"user\" WHERE user_name='Slash''s Dot'"; + if ( $this->db->getType() === 'mysql' ) { + $check = "SELECT user_id FROM \"user\" WHERE user_name='Slash\'s Dot'"; + } + $this->assertEquals( $check, $sql ); + } + + function testFillPreparedRaw() { + $sql = $this->db->fillPrepared( + "SELECT * FROM cur WHERE cur_title='This_\\&_that,_WTF\\?\\!'", + array( '"user"', "Slash's Dot" ) ); + $this->assertEquals( + "SELECT * FROM cur WHERE cur_title='This_&_that,_WTF?!'", + $sql ); + } + +} + + diff --git a/maintenance/tests/phpunit/includes/parser/MediaWikiParserTest.php b/maintenance/tests/phpunit/includes/parser/MediaWikiParserTest.php new file mode 100644 index 0000000000..404ccf2e27 --- /dev/null +++ b/maintenance/tests/phpunit/includes/parser/MediaWikiParserTest.php @@ -0,0 +1,57 @@ +backend = new ParserTestSuiteBackend; + parent::__construct(); + $this->setName( 'Parser tests' ); + } + + public function run( PHPUnit_Framework_TestResult $result = null, $filter = false, + array $groups = array(), array $excludeGroups = array(), $processIsolation = false + ) { + global $IP, $wgContLang, $wgMemc; + $wgContLang = Language::factory( 'en' ); + $wgMemc = new FakeMemCachedClient; + $this->backend->setupDatabase(); + + $iter = new TestFileIterator( "$IP/maintenance/parserTests.txt" ); + $iter->setParser( $this->backend ); + $this->count = 0; + + foreach ( $iter as $test ) { + $this->addTest( new ParserUnitTest( $this, $test ) ); + $this->count++; + } + + parent::run( $result, $filter, $groups, $excludeGroups, $processIsolation ); + + $this->backend->teardownDatabase(); + } + + public function count() { + return $this->count; + } + + public function toString() { + return "MediaWiki Parser Tests"; + } + + public function getBackend() { + return $this->backend; + } + + public function getIterator() { + return $this->iterator; + } +} + diff --git a/maintenance/tests/phpunit/includes/parser/ParserHelpers.php b/maintenance/tests/phpunit/includes/parser/ParserHelpers.php new file mode 100644 index 0000000000..893bf8b420 --- /dev/null +++ b/maintenance/tests/phpunit/includes/parser/ParserHelpers.php @@ -0,0 +1,88 @@ +suite = $suite; + $this->test = $test; + } + + function count() { return 1; } + + public function run( PHPUnit_Framework_TestResult $result = null ) { + PHPUnit_Framework_Assert::resetCount(); + if ( $result === NULL ) { + $result = new PHPUnit_Framework_TestResult; + } + + $backend = $this->suite->getBackend(); + $result->startTest( $this ); + PHPUnit_Util_Timer::start(); + + $r = false; + try { + # Run the test. + # On failure, the subclassed backend will throw an exception with + # the details. + $r = $backend->runTest( + $this->test['test'], + $this->test['input'], + $this->test['result'], + $this->test['options'], + $this->test['config'] + ); + } + catch ( PHPUnit_Framework_AssertionFailedError $e ) { + $result->addFailure( $this, $e, PHPUnit_Util_Timer::stop() ); + } + catch ( Exception $e ) { + $result->addError( $this, $e, PHPUnit_Util_Timer::stop() ); + } + + $result->endTest( $this, PHPUnit_Util_Timer::stop() ); + + $backend->recorder->record( $this->test['test'], $r ); + $this->addToAssertionCount( PHPUnit_Framework_Assert::getCount() ); + + return $result; + } + + public function toString() { + return $this->test['test']; + } + +} + +class ParserTestSuiteBackend extends ParserTest { + function showTesting( $desc ) { + } + + function showRunFile( $path ) { + } + + function showSuccess( $desc ) { + PHPUnit_Framework_Assert::assertTrue( true, $desc ); + return true; + } + + function showFailure( $desc, $expected, $got ) { + PHPUnit_Framework_Assert::assertEquals( $expected, $got, $desc ); + } + + public function setupRecorder( $options ) { + $this->recorder = new PHPUnitTestRecorder( $this ); + } +} + +class PHPUnitTestRecorder extends TestRecorder { + function record( $test, $result ) { + $this->total++; + $this->success += $result; + + } + + function reportPercentage( $success, $total ) { } +} + diff --git a/maintenance/tests/phpunit/includes/search/SearchDbTest.php b/maintenance/tests/phpunit/includes/search/SearchDbTest.php new file mode 100644 index 0000000000..2f36c6b00e --- /dev/null +++ b/maintenance/tests/phpunit/includes/search/SearchDbTest.php @@ -0,0 +1,34 @@ +db = wfGetDB( DB_MASTER ); + if ( !$this->db ) { + $this->markTestIncomplete( "Can't find a database to test with." ); + } + + $GLOBALS['wgContLang'] = new Language; + $this->insertSearchData(); + + $this->insertSearchData(); + $searchType = preg_replace( "/Database/", "Search", + get_class( $this->db ) ); + $this->search = new $searchType( $this->db ); + } + + function tearDown() { + $this->removeSearchData(); + if ( !is_null( $this->db ) ) { + wfGetLB()->closeConnecton( $this->db ); + } + unset( $this->db ); + unset( $this->search ); + $GLOBALS['wgContLang'] = null; + } +} + + diff --git a/maintenance/tests/phpunit/includes/search/SearchEngineTest.php b/maintenance/tests/phpunit/includes/search/SearchEngineTest.php new file mode 100644 index 0000000000..b34ad7df7e --- /dev/null +++ b/maintenance/tests/phpunit/includes/search/SearchEngineTest.php @@ -0,0 +1,176 @@ +pageExists( 'Not_Main_Page' ) ) { + return; + } + $this->insertPage( "Not_Main_Page", "This is not a main page", 0 ); + $this->insertPage( 'Talk:Not_Main_Page', 'This is not a talk page to the main page, see [[smithee]]', 1 ); + $this->insertPage( 'Smithee', 'A smithee is one who smiths. See also [[Alan Smithee]]', 0 ); + $this->insertPage( 'Talk:Smithee', 'This article sucks.', 1 ); + $this->insertPage( 'Unrelated_page', 'Nothing in this page is about the S word.', 0 ); + $this->insertPage( 'Another_page', 'This page also is unrelated.', 0 ); + $this->insertPage( 'Help:Help', 'Help me!', 4 ); + $this->insertPage( 'Thppt', 'Blah blah', 0 ); + $this->insertPage( 'Alan_Smithee', 'yum', 0 ); + $this->insertPage( 'Pages', 'are\'food', 0 ); + $this->insertPage( 'HalfOneUp', 'AZ', 0 ); + $this->insertPage( 'FullOneUp', 'AZ', 0 ); + $this->insertPage( 'HalfTwoLow', 'az', 0 ); + $this->insertPage( 'FullTwoLow', 'az', 0 ); + $this->insertPage( 'HalfNumbers', '1234567890', 0 ); + $this->insertPage( 'FullNumbers', '1234567890', 0 ); + $this->insertPage( 'DomainName', 'example.com', 0 ); + } + + function removeSearchData() { + return; + /*while ( count( $this->pageList ) ) { + list( $title, $id ) = array_pop( $this->pageList ); + $article = new Article( $title, $id ); + $article->doDeleteArticle( "Search Test" ); + }*/ + } + + function fetchIds( $results ) { + $this->assertTrue( is_object( $results ) ); + + if ( $this->db->getType() !== 'mysql' && $this->db->getType() !== 'sqlite' ) { + $this->markTestSkipped( "MySQL or SQLite only" ); + } + $matches = array(); + while ( $row = $results->next() ) { + $matches[] = $row->getTitle()->getPrefixedText(); + } + $results->free(); + # Search is not guaranteed to return results in a certain order; + # sort them numerically so we will compare simply that we received + # the expected matches. + sort( $matches ); + return $matches; + } + + // Modified version of WikiRevision::importOldRevision() + function insertPage( $pageName, $text, $ns ) { + $dbw = $this->db; + $title = Title::newFromText( $pageName ); + + $userId = 0; + $userText = 'WikiSysop'; + $comment = 'Search Test'; + + // avoid memory leak...? + $linkCache = LinkCache::singleton(); + $linkCache->clear(); + + $article = new Article( $title ); + $pageId = $article->getId(); + $created = false; + if ( $pageId == 0 ) { + # must create the page... + $pageId = $article->insertOn( $dbw ); + $created = true; + } + + # FIXME: Use original rev_id optionally (better for backups) + # Insert the row + $revision = new Revision( array( + 'page' => $pageId, + 'text' => $text, + 'comment' => $comment, + 'user' => $userId, + 'user_text' => $userText, + 'timestamp' => 0, + 'minor_edit' => false, + ) ); + $revId = $revision->insertOn( $dbw ); + $changed = $article->updateIfNewerOn( $dbw, $revision ); + + $GLOBALS['wgTitle'] = $title; + if ( $created ) { + Article::onArticleCreate( $title ); + $article->createUpdates( $revision ); + } elseif ( $changed ) { + Article::onArticleEdit( $title ); + $article->editUpdates( + $text, $comment, false, 0, $revId ); + } + + $su = new SearchUpdate( $article->getId(), $pageName, $text ); + $su->doUpdate(); + + $this->pageList[] = array( $title, $article->getId() ); + + return true; + } + + function testFullWidth() { + $this->assertEquals( + array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), + $this->fetchIds( $this->search->searchText( 'AZ' ) ), + "Search for normalized from Half-width Upper" ); + $this->assertEquals( + array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), + $this->fetchIds( $this->search->searchText( 'az' ) ), + "Search for normalized from Half-width Lower" ); + $this->assertEquals( + array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), + $this->fetchIds( $this->search->searchText( 'AZ' ) ), + "Search for normalized from Full-width Upper" ); + $this->assertEquals( + array( 'FullOneUp', 'FullTwoLow', 'HalfOneUp', 'HalfTwoLow' ), + $this->fetchIds( $this->search->searchText( 'az' ) ), + "Search for normalized from Full-width Lower" ); + } + + function testTextSearch() { + $this->assertEquals( + array( 'Smithee' ), + $this->fetchIds( $this->search->searchText( 'smithee' ) ), + "Plain search failed" ); + } + + function testTextPowerSearch() { + $this->search->setNamespaces( array( 0, 1, 4 ) ); + $this->assertEquals( + array( + 'Smithee', + 'Talk:Not Main Page', + ), + $this->fetchIds( $this->search->searchText( 'smithee' ) ), + "Power search failed" ); + } + + function testTitleSearch() { + $this->assertEquals( + array( + 'Alan Smithee', + 'Smithee', + ), + $this->fetchIds( $this->search->searchTitle( 'smithee' ) ), + "Title search failed" ); + } + + function testTextTitlePowerSearch() { + $this->search->setNamespaces( array( 0, 1, 4 ) ); + $this->assertEquals( + array( + 'Alan Smithee', + 'Smithee', + 'Talk:Smithee', + ), + $this->fetchIds( $this->search->searchTitle( 'smithee' ) ), + "Title power search failed" ); + } + +} diff --git a/maintenance/tests/phpunit/includes/search/SearchUpdateTest.php b/maintenance/tests/phpunit/includes/search/SearchUpdateTest.php new file mode 100644 index 0000000000..fd7230d327 --- /dev/null +++ b/maintenance/tests/phpunit/includes/search/SearchUpdateTest.php @@ -0,0 +1,123 @@ +mConn = true; + $this->mOpened = true; + } + + function open( $server, $user, $password, $dbName ) { return true; } + function doQuery( $sql ) { } + function fetchObject( $res ) { } + function fetchRow( $res ) { } + function numRows( $res ) { } + function numFields( $res ) { } + function fieldName( $res, $n ) { } + function insertId() { } + function dataSeek( $res, $row ) { } + function lastErrno() { return 0; } + function lastError() { return ''; } + function affectedRows() { } + function fieldInfo( $table, $field ) { } + function strencode( $s ) { } + static function getSoftwareLink() { } + function getServerVersion() { } + function getType() { } + function getSearchEngine() { } +} + +class MockSearch extends SearchEngine { + public static $id; + public static $title; + public static $text; + + public function __construct( $db ) { + } + + public function update( $id, $title, $text ) { + self::$id = $id; + self::$title = $title; + self::$text = $text; + } +} + +class SearchUpdateTest extends PHPUnit_Framework_TestCase { + static $searchType; + static $dbtype; + static $factoryconf; + static $dbservers; + + function update( $text, $title = 'Test', $id = 1 ) { + $u = new SearchUpdate( $id, $title, $text ); + $u->doUpdate(); + return array( MockSearch::$title, MockSearch::$text ); + } + + function updateText( $text ) { + list( $title, $resultText ) = $this->update( $text ); + $resultText = trim( $resultText ); // abstract from some implementation details + return $resultText; + } + + function setUp() { + global $wgSearchType, $wgDBtype, $wgLBFactoryConf, $wgDBservers, $wgContLang; + + self::$searchType = $wgSearchType; + self::$dbtype = $wgDBtype; + self::$factoryconf = $wgLBFactoryConf; + self::$dbservers = $wgDBservers; + + $wgSearchType = 'MockSearch'; + $wgDBtype = 'mock'; + $wgLBFactoryConf['class'] = 'LBFactory_Simple'; + $wgDBservers = null; + $wgContLang = Language::factory( 'en' ); + LBFactory::destroyInstance(); + } + + function tearDown() { + global $wgSearchType, $wgDBtype, $wgLBFactoryConf, $wgDBservers, $wgContLang; + + LBFactory::destroyInstance(); + + $wgSearchType = self::$searchType; + $wgDBtype = self::$dbtype; + $wgLBFactoryConf = self::$factoryconf; + $wgDBservers = self::$dbservers; + $wgContLang = null; + } + + function testUpdateText() { + $this->assertEquals( + 'test', + $this->updateText( '
TeSt
' ), + 'HTML stripped, text lowercased' + ); + + $this->assertEquals( + 'foo bar boz quux', + $this->updateText( << +
foo
bar + bozquux + +EOT + ), 'Stripping HTML tables' ); + + $this->assertEquals( + 'a b', + $this->updateText( 'a > b' ), + 'Handle unclosed tags' + ); + + $text = str_pad( "foo assertNotEquals( + '', + $this->updateText( $text ), + 'Bug 18609' + ); + } +} diff --git a/maintenance/tests/phpunit/suite.xml b/maintenance/tests/phpunit/suite.xml new file mode 100644 index 0000000000..d92f2564d3 --- /dev/null +++ b/maintenance/tests/phpunit/suite.xml @@ -0,0 +1,33 @@ + + + + + + ./includes + + + ./includes + + + ./languages + + + ./skins + + + ./suites/UploadFromUrlTestSuite.php + + + + + Broken + Stub + + + \ No newline at end of file diff --git a/maintenance/tests/phpunit/suites/ExtensionsTestSuite.php b/maintenance/tests/phpunit/suites/ExtensionsTestSuite.php new file mode 100644 index 0000000000..bdaea10f59 --- /dev/null +++ b/maintenance/tests/phpunit/suites/ExtensionsTestSuite.php @@ -0,0 +1,4 @@ + 'LocalRepo', + 'name' => 'local', + 'directory' => wfTempDir() . '/test-repo', + 'url' => 'http://example.com/images', + 'deletedDir' => wfTempDir() . '/test-repo/delete', + 'hashLevels' => 2, + 'transformVia404' => false, + ); + $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; + $wgNamespaceAliases['Image'] = NS_FILE; + $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; + + + $wgEnableParserCache = false; + $wgDeferredUpdateList = array(); + $wgMemc =& wfGetMainCache(); + $messageMemc =& wfGetMessageCacheStorage(); + $parserMemc =& wfGetParserCacheStorage(); + + // $wgContLang = new StubContLang; + $wgUser = new User; + $wgLang = new StubUserLang; + $wgOut = new StubObject( 'wgOut', 'OutputPage' ); + $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) ); + $wgRequest = new WebRequest; + + $wgMessageCache = new StubObject( 'wgMessageCache', 'MessageCache', + array( $messageMemc, $wgUseDatabaseMessages, + $wgMsgCacheExpiry ) ); + if ( $wgStyleDirectory === false ) { + $wgStyleDirectory = "$IP/skins"; + } + + } + + public function tearDown() { + $this->teardownUploadDir( $this->uploadDir ); + } + + private $uploadDir; + private $keepUploads; + + /** + * Remove the dummy uploads directory + */ + private function teardownUploadDir( $dir ) { + if ( $this->keepUploads ) { + return; + } + + // delete the files first, then the dirs. + self::deleteFiles( + array ( + "$dir/3/3a/Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/200px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/640px-Foobar.jpg", + "$dir/thumb/3/3a/Foobar.jpg/120px-Foobar.jpg", + + "$dir/0/09/Bad.jpg", + ) + ); + + self::deleteDirs( + array ( + "$dir/3/3a", + "$dir/3", + "$dir/thumb/6/65", + "$dir/thumb/6", + "$dir/thumb/3/3a/Foobar.jpg", + "$dir/thumb/3/3a", + "$dir/thumb/3", + + "$dir/0/09/", + "$dir/0/", + + "$dir/thumb", + "$dir", + ) + ); + } + + /** + * Delete the specified files, if they exist. + * + * @param $files Array: full paths to files to delete. + */ + private static function deleteFiles( $files ) { + foreach ( $files as $file ) { + if ( file_exists( $file ) ) { + unlink( $file ); + } + } + } + + /** + * Delete the specified directories, if they exist. Must be empty. + * + * @param $dirs Array: full paths to directories to delete. + */ + private static function deleteDirs( $dirs ) { + foreach ( $dirs as $dir ) { + if ( is_dir( $dir ) ) { + rmdir( $dir ); + } + } + } + + /** + * Create a dummy uploads directory which will contain a couple + * of files in order to pass existence tests. + * + * @return String: the directory + */ + private function setupUploadDir() { + global $IP; + + if ( $this->keepUploads ) { + $dir = wfTempDir() . '/mwParser-images'; + + if ( is_dir( $dir ) ) { + return $dir; + } + } else { + $dir = wfTempDir() . "/mwParser-" . mt_rand() . "-images"; + } + + wfDebug( "Creating upload directory $dir\n" ); + + if ( file_exists( $dir ) ) { + wfDebug( "Already exists!\n" ); + return $dir; + } + + wfMkdirParents( $dir . '/3/3a' ); + copy( "$IP/skins/monobook/headbg.jpg", "$dir/3/3a/Foobar.jpg" ); + + wfMkdirParents( $dir . '/0/09' ); + copy( "$IP/skins/monobook/headbg.jpg", "$dir/0/09/Bad.jpg" ); + + return $dir; + } + + public static function suite() { + // Hack to invoke the autoloader required to get phpunit to recognize + // the UploadFromUrlTest class + class_exists( 'UploadFromUrlTest' ); + $suite = new UploadFromUrlTestSuite( 'UploadFromUrlTest' ); + return $suite; + } +} diff --git a/maintenance/tests/test-prefetch-current.xml b/maintenance/tests/test-prefetch-current.xml deleted file mode 100644 index a4c8bda30b..0000000000 --- a/maintenance/tests/test-prefetch-current.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - DemoWiki - http://example.com/wiki/Main_Page - MediaWiki 1.5.0 - first-letter - - Media - Special - - Talk - User - User talk - DemoWiki - DemoWIki talk - Image - Image talk - MediaWiki - MediaWiki talk - Template - Template talk - Help - Help talk - Category - Category talk - - - - First page - 1 - - 1 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 1, rev 1 - page 1, rev 1 - - - 2 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 1, rev 2 - page 1, rev 2 - - - 4 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 1, rev 4 - page 1, rev 4 - - - - Second page - 2 - - 3 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 2, rev 3 - page 2, rev 3 - - - - Third page - 3 - - 5 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 3, rev 5 - page 3, rev 5 - - - diff --git a/maintenance/tests/test-prefetch-previous.xml b/maintenance/tests/test-prefetch-previous.xml deleted file mode 100644 index 95eb82dd4f..0000000000 --- a/maintenance/tests/test-prefetch-previous.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - DemoWiki - http://example.com/wiki/Main_Page - MediaWiki 1.5.0 - first-letter - - Media - Special - - Talk - User - User talk - DemoWiki - DemoWIki talk - Image - Image talk - MediaWiki - MediaWiki talk - Template - Template talk - Help - Help talk - Category - Category talk - - - - First page - 1 - - 1 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 1, rev 1 - page 1, rev 1 - - - 2 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 1, rev 2 - page 1, rev 2 - - - - Second page - 2 - - 3 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 2, rev 3 - page 2, rev 3 - - - diff --git a/maintenance/tests/test-prefetch-stub.xml b/maintenance/tests/test-prefetch-stub.xml deleted file mode 100644 index 59d43d2f35..0000000000 --- a/maintenance/tests/test-prefetch-stub.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - DemoWiki - http://example.com/wiki/Main_Page - MediaWiki 1.5.0 - first-letter - - Media - Special - - Talk - User - User talk - DemoWiki - DemoWIki talk - Image - Image talk - MediaWiki - MediaWiki talk - Template - Template talk - Help - Help talk - Category - Category talk - - - - First page - 1 - - 1 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 1, rev 1 - - - - 2 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 1, rev 2 - - - - 4 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 1, rev 4 - - - - - Second page - 2 - - 3 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 2, rev 3 - - - - - Third page - 3 - - 5 - 2001-01-15T12:00:00Z - 10.0.0.1 - page 3, rev 5 - - - -