aboutsummaryrefslogtreecommitdiffstats
path: root/tests/phpunit/unit
diff options
context:
space:
mode:
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>2020-03-26 03:15:58 +0000
committerGerrit Code Review <gerrit@wikimedia.org>2020-03-26 03:15:58 +0000
commitfde16090b698268747e04d32789471d78c35b072 (patch)
tree2c902e1510de0aa712ff990843482bc05c0a4934 /tests/phpunit/unit
parent0d2c52919c41e144b08c43885307deb0f1a6c5ca (diff)
parent22561b64a7c2b0c4402a1601824fd2705b847ca5 (diff)
downloadmediawikicore-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.php96
-rw-r--r--tests/phpunit/unit/includes/Rest/Handler/MediaTestTrait.php129
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;
+ }
+
+}