diff options
author | jenkins-bot <jenkins-bot@gerrit.wikimedia.org> | 2020-03-26 03:15:58 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@wikimedia.org> | 2020-03-26 03:15:58 +0000 |
commit | fde16090b698268747e04d32789471d78c35b072 (patch) | |
tree | 2c902e1510de0aa712ff990843482bc05c0a4934 /tests/phpunit/unit | |
parent | 0d2c52919c41e144b08c43885307deb0f1a6c5ca (diff) | |
parent | 22561b64a7c2b0c4402a1601824fd2705b847ca5 (diff) | |
download | mediawikicore-fde16090b698268747e04d32789471d78c35b072.tar.gz mediawikicore-fde16090b698268747e04d32789471d78c35b072.zip |
Merge "REST endpoints: Add etag and last-modified headers"
Diffstat (limited to 'tests/phpunit/unit')
-rw-r--r-- | tests/phpunit/unit/includes/Rest/Handler/HandlerTestTrait.php | 96 | ||||
-rw-r--r-- | tests/phpunit/unit/includes/Rest/Handler/MediaTestTrait.php | 129 |
2 files changed, 218 insertions, 7 deletions
diff --git a/tests/phpunit/unit/includes/Rest/Handler/HandlerTestTrait.php b/tests/phpunit/unit/includes/Rest/Handler/HandlerTestTrait.php index 1f6a876e8fc1..16ad9411cd82 100644 --- a/tests/phpunit/unit/includes/Rest/Handler/HandlerTestTrait.php +++ b/tests/phpunit/unit/includes/Rest/Handler/HandlerTestTrait.php @@ -2,19 +2,27 @@ namespace MediaWiki\Tests\Rest\Handler; +use GenderCache; +use Language; +use MediaWiki\Interwiki\InterwikiLookup; +use MediaWiki\Linker\LinkTarget; use MediaWiki\Permissions\PermissionManager; use MediaWiki\Rest\Handler; use MediaWiki\Rest\HttpException; use MediaWiki\Rest\RequestInterface; use MediaWiki\Rest\Response; use MediaWiki\Rest\ResponseFactory; +use MediaWiki\Rest\ResponseInterface; use MediaWiki\Rest\Router; use MediaWiki\Rest\Validator\Validator; use MediaWiki\User\UserIdentityValue; use MediaWikiTestCaseTrait; +use MediaWikiTitleCodec; +use NamespaceInfo; use PHPUnit\Framework\Assert; use PHPUnit\Framework\MockObject\MockObject; use Title; +use User; use Wikimedia\Message\ITextFormatter; use Wikimedia\Message\MessageValue; use Wikimedia\ObjectFactory; @@ -50,7 +58,7 @@ trait HandlerTestTrait { * @param RequestInterface $request * @param array $config * - * @return Response + * @return ResponseInterface */ private function executeHandler( Handler $handler, RequestInterface $request, $config = [] ) { $formatter = $this->createMock( ITextFormatter::class ); @@ -83,11 +91,21 @@ trait HandlerTestTrait { $handler->init( $router, $request, $config, $responseFactory ); $handler->validate( $validator ); + + // Check conditional request headers + $earlyResponse = $handler->checkPreconditions(); + if ( $earlyResponse ) { + return $earlyResponse; + } + $ret = $handler->execute(); $response = $ret instanceof Response ? $ret : $responseFactory->createFromReturnValue( $ret ); + // Set Last-Modified and ETag headers in the response if available + $handler->applyConditionalResponseHeaders( $response ); + return $response; } @@ -141,22 +159,86 @@ trait HandlerTestTrait { } /** - * @return Title + * @param string $text + * @param array $props Additional properties to set. Supported keys: + * - id: int + * - namespace: int + * + * @return Title|MockObject */ - private function makeMockTitle( $text, $id = null, $model = 'UNKNOWN' ) { - $id = $id ?? ++$this->pageIdCounter; + private function makeMockTitle( $text, array $props = [] ) { + $id = $props['id'] ?? ++$this->pageIdCounter; + $ns = $props['namespace'] ?? 0; + $nsName = $ns ? "ns$ns:" : ''; + + $preText = $text; + $text = preg_replace( '/^[\w ]*?:/', '', $text ); + + // If no namespace prefix was given, add one if needed. + if ( $preText == $text && $ns ) { + $preText = $nsName . $text; + } /** @var Title|MockObject $title */ $title = $this->createMock( Title::class ); + $title->method( 'getText' )->willReturn( str_replace( '_', ' ', $text ) ); $title->method( 'getDBkey' )->willReturn( str_replace( ' ', '_', $text ) ); - $title->method( 'getPrefixedText' )->willReturn( str_replace( '_', ' ', $text ) ); - $title->method( 'getPrefixedDBkey' )->willReturn( str_replace( ' ', '_', $text ) ); + + $title->method( 'getPrefixedText' )->willReturn( str_replace( '_', ' ', $preText ) ); + $title->method( 'getPrefixedDBkey' )->willReturn( str_replace( ' ', '_', $preText ) ); + $title->method( 'getArticleID' )->willReturn( $id ); + $title->method( 'getNamespace' )->willReturn( $props['namespace'] ?? 0 ); $title->method( 'exists' )->willReturn( $id > 0 ); - $title->method( 'getContentModel' )->willReturn( $model ); + $title->method( 'getTouched' )->willReturn( $id ? '20200101223344' : false ); return $title; } + /** + * @return PermissionManager|MockObject + */ + private function makeMockPermissionManager() { + /** @var PermissionManager|MockObject $permissionManager */ + $permissionManager = $this->createNoOpMock( + PermissionManager::class, [ 'userCan' ] + ); + $permissionManager->method( 'userCan' ) + ->willReturnCallback( function ( $action, User $user, LinkTarget $page ) { + return !preg_match( '/Forbidden/', $page->getText() ); + } ); + + return $permissionManager; + } + + /** + * @return MediaWikiTitleCodec + */ + private function makeMockTitleCodec() { + /** @var Language|MockObject $language */ + $language = $this->createNoOpMock( Language::class, [ 'ucfirst' ] ); + $language->method( 'ucfirst' )->willReturnCallback( 'ucfirst' ); + + /** @var GenderCache|MockObject $genderCache */ + $genderCache = $this->createNoOpMock( GenderCache::class ); + + /** @var InterwikiLookup|MockObject $interwikiLookup */ + $interwikiLookup = $this->createNoOpMock( InterwikiLookup::class ); + + /** @var NamespaceInfo|MockObject $namespaceInfo */ + $namespaceInfo = $this->createNoOpMock( NamespaceInfo::class, [ 'isCapitalized' ] ); + $namespaceInfo->method( 'isCapitalized' )->willReturn( true ); + + $titleCodec = new MediaWikiTitleCodec( + $language, + $genderCache, + [ 'en' ], + $interwikiLookup, + $namespaceInfo + ); + + return $titleCodec; + } + } diff --git a/tests/phpunit/unit/includes/Rest/Handler/MediaTestTrait.php b/tests/phpunit/unit/includes/Rest/Handler/MediaTestTrait.php new file mode 100644 index 000000000000..bf7fe196f4cb --- /dev/null +++ b/tests/phpunit/unit/includes/Rest/Handler/MediaTestTrait.php @@ -0,0 +1,129 @@ +<?php + +namespace MediaWiki\Tests\Rest\Handler; + +use File; +use PHPUnit\Framework\MockObject\MockObject; +use RepoGroup; +use ThumbnailImage; +use Title; + +/** + * A trait providing utility functions for mocking media-related objects. + * + * @package MediaWiki\Tests\Rest\Handler + */ +trait MediaTestTrait { + + use HandlerTestTrait; + + /** + * @param Title|string $title + * + * @return File|MockObject + */ + private function makeMissingMockFile( $title ) { + $title = $title instanceof Title + ? $title + : $this->makeMockTitle( 'File:' . $title, [ 'namespace' => NS_FILE ] ); + + /** @var MockObject|File $file */ + $file = $this->createNoOpMock( + File::class, + [ 'getTitle', 'exists', 'getDescriptionUrl' ] + ); + $file->method( 'getTitle' )->willReturn( $title ); + $file->method( 'exists' )->willReturn( false ); + $file->method( 'getDescriptionUrl' )->willReturn( + 'https://example.com/wiki/' . $title->getPrefixedDBkey() + ); + + return $file; + } + + /** + * @param Title|string $title + * + * @return File|MockObject + */ + private function makeMockFile( $title ) { + $title = $title instanceof Title + ? $title + : $this->makeMockTitle( 'File:' . $title, [ 'namespace' => NS_FILE ] ); + + /** @var MockObject|File $file */ + $file = $this->createNoOpMock( + File::class, + [ 'getTitle', 'getDescriptionUrl', 'exists', 'userCan', 'getUser', 'getTimestamp', + 'getMediaType', 'getSize', 'getHeight', 'getWidth', 'getDisplayWidthHeight', + 'getLength', 'getUrl', 'allowInlineDisplay', 'transform', 'getSha1' ] + ); + $file->method( 'getTitle' )->willReturn( $title ); + $file->method( 'exists' )->willReturn( true ); + $file->method( 'userCan' )->willReturn( true ); + $file->method( 'getUser' )->willReturnCallback( function ( $type ) { + return $type === 'id' ? 7 : 'Alice'; + } ); + $file->method( 'getTimestamp' )->willReturn( '20200102030405' ); + $file->method( 'getMediaType' )->willReturn( 'test' ); + $file->method( 'getSize' )->willReturn( 12345 ); + $file->method( 'getHeight' )->willReturn( 400 ); + $file->method( 'getWidth' )->willReturn( 600 ); + $file->method( 'getDisplayWidthHeight' )->willReturn( [ 600, 400 ] ); + $file->method( 'getLength' )->willReturn( 678 ); + $file->method( 'getSha1' )->willReturn( 'DEADBEEF' ); + $file->method( 'allowInlineDisplay' )->willReturn( true ); + $file->method( 'getUrl' )->willReturn( + 'https://media.example.com/static/' . $title->getDBkey() + ); + $file->method( 'getDescriptionUrl' )->willReturn( + 'https://example.com/wiki/' . $title->getPrefixedDBkey() + ); + + $thumbnail = new ThumbnailImage( + $file, + 'https://media.example.com/static/thumb/' . $title->getDBkey(), + false, + [ 'width' => 64, 'height' => 64, ] + ); + $file->method( 'transform' )->willReturn( $thumbnail ); + + return $file; + } + + /** + * @return MockObject|RepoGroup + */ + private function makeMockRepoGroup() { + $findFile = function ( $title ) { + $title = $title instanceof Title + ? $title + : $this->makeMockTitle( 'File:' . $title, [ 'namespace' => NS_FILE ] ); + + if ( preg_match( '/missing/i', $title->getText() ) + || $title->getNamespace() !== NS_FILE + ) { + return $this->makeMissingMockFile( $title ); + } else { + return $this->makeMockFile( $title ); + } + }; + + $findFiles = function ( array $inputItems ) use ( $findFile ) { + $files = []; + foreach ( $inputItems as $item ) { + $files[] = ( $findFile )( $item['title'] ); + } + + return $files; + }; + + /** @var RepoGroup|MockObject $repoGroup */ + $repoGroup = $this->createNoOpMock( RepoGroup::class, [ 'findFiles', 'findFile' ] ); + $repoGroup->method( 'findFile' )->willReturnCallback( $findFile ); + $repoGroup->method( 'findFiles' )->willReturnCallback( $findFiles ); + + return $repoGroup; + } + +} |