diff options
Diffstat (limited to 'www/wiki/tests/phpunit/includes/exception')
8 files changed, 475 insertions, 0 deletions
diff --git a/www/wiki/tests/phpunit/includes/exception/BadTitleErrorTest.php b/www/wiki/tests/phpunit/includes/exception/BadTitleErrorTest.php new file mode 100644 index 00000000..b706face --- /dev/null +++ b/www/wiki/tests/phpunit/includes/exception/BadTitleErrorTest.php @@ -0,0 +1,30 @@ +<?php +/** + * @covers BadTitleError + * @author Addshore + */ +class BadTitleErrorTest extends MediaWikiTestCase { + + public function testExceptionSetsStatusCode() { + $this->setMwGlobals( 'wgOut', $this->getMockWgOut() ); + try { + throw new BadTitleError(); + } catch ( BadTitleError $e ) { + ob_start(); + $e->report(); + $text = ob_get_clean(); + $this->assertContains( $e->getText(), $text ); + } + } + + private function getMockWgOut() { + $mock = $this->getMockBuilder( OutputPage::class ) + ->disableOriginalConstructor() + ->getMock(); + $mock->expects( $this->once() ) + ->method( 'setStatusCode' ) + ->with( 400 ); + return $mock; + } + +} diff --git a/www/wiki/tests/phpunit/includes/exception/ErrorPageErrorTest.php b/www/wiki/tests/phpunit/includes/exception/ErrorPageErrorTest.php new file mode 100644 index 00000000..49d454e8 --- /dev/null +++ b/www/wiki/tests/phpunit/includes/exception/ErrorPageErrorTest.php @@ -0,0 +1,52 @@ +<?php + +/** + * @covers ErrorPageError + * @author Addshore + */ +class ErrorPageErrorTest extends MediaWikiTestCase { + + private function getMockMessage() { + $mockMessage = $this->getMockBuilder( Message::class ) + ->disableOriginalConstructor() + ->getMock(); + $mockMessage->expects( $this->once() ) + ->method( 'inLanguage' ) + ->will( $this->returnValue( $mockMessage ) ); + $mockMessage->expects( $this->once() ) + ->method( 'useDatabase' ) + ->will( $this->returnValue( $mockMessage ) ); + return $mockMessage; + } + + public function testConstruction() { + $mockMessage = $this->getMockMessage(); + $title = 'Foo'; + $params = [ 'Baz' ]; + $e = new ErrorPageError( $title, $mockMessage, $params ); + $this->assertEquals( $title, $e->title ); + $this->assertEquals( $mockMessage, $e->msg ); + $this->assertEquals( $params, $e->params ); + } + + public function testReport() { + $mockMessage = $this->getMockMessage(); + $title = 'Foo'; + $params = [ 'Baz' ]; + + $mock = $this->getMockBuilder( OutputPage::class ) + ->disableOriginalConstructor() + ->getMock(); + $mock->expects( $this->once() ) + ->method( 'showErrorPage' ) + ->with( $title, $mockMessage, $params ); + $mock->expects( $this->once() ) + ->method( 'output' ); + $this->setMwGlobals( 'wgOut', $mock ); + $this->setMwGlobals( 'wgCommandLineMode', false ); + + $e = new ErrorPageError( $title, $mockMessage, $params ); + $e->report(); + } + +} diff --git a/www/wiki/tests/phpunit/includes/exception/HttpErrorTest.php b/www/wiki/tests/phpunit/includes/exception/HttpErrorTest.php new file mode 100644 index 00000000..90ccd1e5 --- /dev/null +++ b/www/wiki/tests/phpunit/includes/exception/HttpErrorTest.php @@ -0,0 +1,63 @@ +<?php + +/** + * @todo tests for HttpError::report + * + * @covers HttpError + */ +class HttpErrorTest extends MediaWikiTestCase { + + public function testIsLoggable() { + $httpError = new HttpError( 500, 'server error!' ); + $this->assertFalse( $httpError->isLoggable(), 'http error is not loggable' ); + } + + public function testGetStatusCode() { + $httpError = new HttpError( 500, 'server error!' ); + $this->assertEquals( 500, $httpError->getStatusCode() ); + } + + /** + * @dataProvider getHtmlProvider + */ + public function testGetHtml( array $expected, $content, $header ) { + $httpError = new HttpError( 500, $content, $header ); + $errorHtml = $httpError->getHTML(); + + foreach ( $expected as $key => $html ) { + $this->assertContains( $html, $errorHtml, $key ); + } + } + + public function getHtmlProvider() { + return [ + [ + [ + 'head html' => '<head><title>Server Error 123</title></head>', + 'body html' => '<body><h1>Server Error 123</h1>' + . '<p>a server error!</p></body>' + ], + 'a server error!', + 'Server Error 123' + ], + [ + [ + 'head html' => '<head><title>loginerror</title></head>', + 'body html' => '<body><h1>loginerror</h1>' + . '<p>suspicious-userlogout</p></body>' + ], + new RawMessage( 'suspicious-userlogout' ), + new RawMessage( 'loginerror' ) + ], + [ + [ + 'head html' => '<html><head><title>Internal Server Error</title></head>', + 'body html' => '<body><h1>Internal Server Error</h1>' + . '<p>a server error!</p></body></html>' + ], + 'a server error!', + null + ] + ]; + } +} diff --git a/www/wiki/tests/phpunit/includes/exception/MWExceptionHandlerTest.php b/www/wiki/tests/phpunit/includes/exception/MWExceptionHandlerTest.php new file mode 100644 index 00000000..66060656 --- /dev/null +++ b/www/wiki/tests/phpunit/includes/exception/MWExceptionHandlerTest.php @@ -0,0 +1,74 @@ +<?php +/** + * @author Antoine Musso + * @copyright Copyright © 2013, Antoine Musso + * @copyright Copyright © 2013, Wikimedia Foundation Inc. + * @file + */ + +class MWExceptionHandlerTest extends MediaWikiTestCase { + + /** + * @covers MWExceptionHandler::getRedactedTrace + */ + public function testGetRedactedTrace() { + $refvar = 'value'; + try { + $array = [ 'a', 'b' ]; + $object = new stdClass(); + self::helperThrowAnException( $array, $object, $refvar ); + } catch ( Exception $e ) { + } + + # Make sure our stack trace contains an array and an object passed to + # some function in the stacktrace. Else, we can not assert the trace + # redaction achieved its job. + $trace = $e->getTrace(); + $hasObject = false; + $hasArray = false; + foreach ( $trace as $frame ) { + if ( !isset( $frame['args'] ) ) { + continue; + } + foreach ( $frame['args'] as $arg ) { + $hasObject = $hasObject || is_object( $arg ); + $hasArray = $hasArray || is_array( $arg ); + } + + if ( $hasObject && $hasArray ) { + break; + } + } + $this->assertTrue( $hasObject, + "The stacktrace must have a function having an object has parameter" ); + $this->assertTrue( $hasArray, + "The stacktrace must have a function having an array has parameter" ); + + # Now we redact the trace.. and make sure no function arguments are + # arrays or objects. + $redacted = MWExceptionHandler::getRedactedTrace( $e ); + + foreach ( $redacted as $frame ) { + if ( !isset( $frame['args'] ) ) { + continue; + } + foreach ( $frame['args'] as $arg ) { + $this->assertNotInternalType( 'array', $arg ); + $this->assertNotInternalType( 'object', $arg ); + } + } + + $this->assertEquals( 'value', $refvar, 'Ensuring reference variable wasn\'t changed' ); + } + + /** + * Helper function for testExpandArgumentsInCall + * + * Pass it an object and an array, and something by reference :-) + * + * @throws Exception + */ + protected static function helperThrowAnException( $a, $b, &$c ) { + throw new Exception(); + } +} diff --git a/www/wiki/tests/phpunit/includes/exception/MWExceptionTest.php b/www/wiki/tests/phpunit/includes/exception/MWExceptionTest.php new file mode 100644 index 00000000..b1605549 --- /dev/null +++ b/www/wiki/tests/phpunit/includes/exception/MWExceptionTest.php @@ -0,0 +1,193 @@ +<?php +/** + * @author Antoine Musso + * @copyright Copyright © 2013, Antoine Musso + * @copyright Copyright © 2013, Wikimedia Foundation Inc. + * @file + */ + +class MWExceptionTest extends MediaWikiTestCase { + + /** + * @expectedException MWException + * @covers MWException + */ + public function testMwexceptionThrowing() { + throw new MWException(); + } + + /** + * @dataProvider provideTextUseOutputPage + * @covers MWException::useOutputPage + */ + public function testUseOutputPage( $expected, $langObj, $wgFullyInitialised, $wgOut ) { + $this->setMwGlobals( [ + 'wgLang' => $langObj, + 'wgFullyInitialised' => $wgFullyInitialised, + 'wgOut' => $wgOut, + ] ); + + $e = new MWException(); + $this->assertEquals( $expected, $e->useOutputPage() ); + } + + public function provideTextUseOutputPage() { + return [ + // expected, langObj, wgFullyInitialised, wgOut + [ false, null, null, null ], + [ false, $this->getMockLanguage(), null, null ], + [ false, $this->getMockLanguage(), true, null ], + [ false, null, true, null ], + [ false, null, null, true ], + [ true, $this->getMockLanguage(), true, true ], + ]; + } + + private function getMockLanguage() { + return $this->getMockBuilder( Language::class ) + ->disableOriginalConstructor() + ->getMock(); + } + + /** + * @dataProvider provideUseMessageCache + * @covers MWException::useMessageCache + */ + public function testUseMessageCache( $expected, $langObj ) { + $this->setMwGlobals( [ + 'wgLang' => $langObj, + ] ); + $e = new MWException(); + $this->assertEquals( $expected, $e->useMessageCache() ); + } + + public function provideUseMessageCache() { + return [ + [ false, null ], + [ true, $this->getMockLanguage() ], + ]; + } + + /** + * @covers MWException::isLoggable + */ + public function testIsLogable() { + $e = new MWException(); + $this->assertTrue( $e->isLoggable() ); + } + + /** + * @dataProvider provideIsCommandLine + * @covers MWException::isCommandLine + */ + public function testisCommandLine( $expected, $wgCommandLineMode ) { + $this->setMwGlobals( [ + 'wgCommandLineMode' => $wgCommandLineMode, + ] ); + $e = new MWException(); + $this->assertEquals( $expected, $e->isCommandLine() ); + } + + public static function provideIsCommandLine() { + return [ + [ false, null ], + [ true, true ], + ]; + } + + /** + * Verify the exception classes are JSON serializabe. + * + * @covers MWExceptionHandler::jsonSerializeException + * @dataProvider provideExceptionClasses + */ + public function testJsonSerializeExceptions( $exception_class ) { + $json = MWExceptionHandler::jsonSerializeException( + new $exception_class() + ); + $this->assertNotEquals( false, $json, + "The $exception_class exception should be JSON serializable, got false." ); + } + + public static function provideExceptionClasses() { + return [ + [ Exception::class ], + [ MWException::class ], + ]; + } + + /** + * Lame JSON schema validation. + * + * @covers MWExceptionHandler::jsonSerializeException + * + * @param string $expectedKeyType Type expected as returned by gettype() + * @param string $exClass An exception class (ie: Exception, MWException) + * @param string $key Name of the key to validate in the serialized JSON + * @dataProvider provideJsonSerializedKeys + */ + public function testJsonserializeexceptionKeys( $expectedKeyType, $exClass, $key ) { + # Make sure we log a backtrace: + $this->setMwGlobals( [ 'wgLogExceptionBacktrace' => true ] ); + + $json = json_decode( + MWExceptionHandler::jsonSerializeException( new $exClass() ) + ); + $this->assertObjectHasAttribute( $key, $json, + "JSON serialized exception is missing key '$key'" + ); + $this->assertInternalType( $expectedKeyType, $json->$key, + "JSON serialized key '$key' has type " . gettype( $json->$key ) + . " (expected: $expectedKeyType)." + ); + } + + /** + * Returns test cases: exception class, key name, gettype() + */ + public static function provideJsonSerializedKeys() { + $testCases = []; + foreach ( [ Exception::class, MWException::class ] as $exClass ) { + $exTests = [ + [ 'string', $exClass, 'id' ], + [ 'string', $exClass, 'file' ], + [ 'integer', $exClass, 'line' ], + [ 'string', $exClass, 'message' ], + [ 'null', $exClass, 'url' ], + # Backtrace only enabled with wgLogExceptionBacktrace = true + [ 'array', $exClass, 'backtrace' ], + ]; + $testCases = array_merge( $testCases, $exTests ); + } + return $testCases; + } + + /** + * Given wgLogExceptionBacktrace is true + * then serialized exception SHOULD have a backtrace + * + * @covers MWExceptionHandler::jsonSerializeException + */ + public function testJsonserializeexceptionBacktracingEnabled() { + $this->setMwGlobals( [ 'wgLogExceptionBacktrace' => true ] ); + $json = json_decode( + MWExceptionHandler::jsonSerializeException( new Exception() ) + ); + $this->assertObjectHasAttribute( 'backtrace', $json ); + } + + /** + * Given wgLogExceptionBacktrace is false + * then serialized exception SHOULD NOT have a backtrace + * + * @covers MWExceptionHandler::jsonSerializeException + */ + public function testJsonserializeexceptionBacktracingDisabled() { + $this->setMwGlobals( [ 'wgLogExceptionBacktrace' => false ] ); + $json = json_decode( + MWExceptionHandler::jsonSerializeException( new Exception() ) + ); + $this->assertObjectNotHasAttribute( 'backtrace', $json ); + } + +} diff --git a/www/wiki/tests/phpunit/includes/exception/ReadOnlyErrorTest.php b/www/wiki/tests/phpunit/includes/exception/ReadOnlyErrorTest.php new file mode 100644 index 00000000..ee5becff --- /dev/null +++ b/www/wiki/tests/phpunit/includes/exception/ReadOnlyErrorTest.php @@ -0,0 +1,16 @@ +<?php + +/** + * @covers ReadOnlyError + * @author Addshore + */ +class ReadOnlyErrorTest extends MediaWikiTestCase { + + public function testConstruction() { + $e = new ReadOnlyError(); + $this->assertEquals( 'readonly', $e->title ); + $this->assertEquals( 'readonlytext', $e->msg ); + $this->assertEquals( wfReadOnlyReason() ?: [], $e->params ); + } + +} diff --git a/www/wiki/tests/phpunit/includes/exception/ThrottledErrorTest.php b/www/wiki/tests/phpunit/includes/exception/ThrottledErrorTest.php new file mode 100644 index 00000000..5214b6d4 --- /dev/null +++ b/www/wiki/tests/phpunit/includes/exception/ThrottledErrorTest.php @@ -0,0 +1,31 @@ +<?php + +/** + * @covers ThrottledError + * @author Addshore + */ +class ThrottledErrorTest extends MediaWikiTestCase { + + public function testExceptionSetsStatusCode() { + $this->setMwGlobals( 'wgOut', $this->getMockWgOut() ); + try { + throw new ThrottledError(); + } catch ( ThrottledError $e ) { + ob_start(); + $e->report(); + $text = ob_get_clean(); + $this->assertContains( $e->getText(), $text ); + } + } + + private function getMockWgOut() { + $mock = $this->getMockBuilder( OutputPage::class ) + ->disableOriginalConstructor() + ->getMock(); + $mock->expects( $this->once() ) + ->method( 'setStatusCode' ) + ->with( 429 ); + return $mock; + } + +} diff --git a/www/wiki/tests/phpunit/includes/exception/UserNotLoggedInTest.php b/www/wiki/tests/phpunit/includes/exception/UserNotLoggedInTest.php new file mode 100644 index 00000000..55ec45a0 --- /dev/null +++ b/www/wiki/tests/phpunit/includes/exception/UserNotLoggedInTest.php @@ -0,0 +1,16 @@ +<?php + +/** + * @covers UserNotLoggedIn + * @author Addshore + */ +class UserNotLoggedInTest extends MediaWikiTestCase { + + public function testConstruction() { + $e = new UserNotLoggedIn(); + $this->assertEquals( 'exception-nologin', $e->title ); + $this->assertEquals( 'exception-nologin-text', $e->msg ); + $this->assertEquals( [], $e->params ); + } + +} |