static::getTestSysop(), 'uploader' => static::getTestUser(), ]; $this->setRequest( new FauxRequest( [] ) ); $this->apiContext = new ApiTestContext(); } protected function tearDown(): void { // Avoid leaking session over tests MediaWiki\Session\SessionManager::getGlobalSession()->clear(); parent::tearDown(); } /** * Does the API request and returns the result. * * @param array $params * @param array|null $session * @param bool $appendModule * @param Authority|null $performer * @param string|null $tokenType Set to a string like 'csrf' to send an * appropriate token * @return array List of: * - the result data (array) * - the request (WebRequest) * - the session data of the request (array) * - if $appendModule is true, the Api module $module * @throws ApiUsageException */ protected function doApiRequest( array $params, array $session = null, $appendModule = false, Authority $performer = null, $tokenType = null ) { global $wgRequest; if ( $session === null ) { // re-use existing global session by default $session = $wgRequest->getSessionArray(); } $sessionObj = SessionManager::singleton()->getEmptySession(); if ( $session !== null ) { foreach ( $session as $key => $value ) { $sessionObj->set( $key, $value ); } } // set up global environment if ( $performer ) { $legacyUser = $this->getServiceContainer()->getUserFactory()->newFromAuthority( $performer ); $contextUser = $legacyUser; } else { $contextUser = self::$users['sysop']->getUser(); $performer = $contextUser; } $sessionObj->setUser( $contextUser ); if ( $tokenType !== null ) { if ( $tokenType === 'auto' ) { $tokenType = ( new ApiMain() )->getModuleManager() ->getModule( $params['action'], 'action' )->needsToken(); } if ( $tokenType !== false ) { $params['token'] = ApiQueryTokens::getToken( $contextUser, $sessionObj, ApiQueryTokens::getTokenTypeSalts()[$tokenType] )->toString(); } } $wgRequest = $this->buildFauxRequest( $params, $sessionObj ); RequestContext::getMain()->setRequest( $wgRequest ); RequestContext::getMain()->setAuthority( $performer ); // set up local environment $context = $this->apiContext->newTestContext( $wgRequest, $performer ); $module = new ApiMain( $context, true ); // run it! $module->execute(); // construct result $results = [ $module->getResult()->getResultData( null, [ 'Strip' => 'all' ] ), $context->getRequest(), $context->getRequest()->getSessionArray() ]; if ( $appendModule ) { $results[] = $module; } return $results; } /** * @since 1.37 * @param array $params * @param MediaWiki\Session\Session|array|null $session * @return FauxRequest */ protected function buildFauxRequest( $params, $session ) { return new FauxRequest( $params, true, $session ); } /** * Convenience function to access the token parameter of doApiRequest() * more succinctly. * * @param array $params Key-value API params * @param array|null $session Session array * @param Authority|null $performer A User object for the context * @param string $tokenType Which token type to pass * @return array Result of the API call */ protected function doApiRequestWithToken( array $params, array $session = null, Authority $performer = null, $tokenType = 'auto' ) { return $this->doApiRequest( $params, $session, false, $performer, $tokenType ); } protected static function getErrorFormatter() { if ( self::$errorFormatter === null ) { self::$errorFormatter = new ApiErrorFormatter( new ApiResult( false ), MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( 'en' ), 'none' ); } return self::$errorFormatter; } public static function apiExceptionHasCode( ApiUsageException $ex, $code ) { return (bool)array_filter( self::getErrorFormatter()->arrayFromStatus( $ex->getStatusValue() ), static function ( $e ) use ( $code ) { return is_array( $e ) && $e['code'] === $code; } ); } /** * @coversNothing */ public function testApiTestGroup() { $groups = Test::getGroups( static::class ); $constraint = Assert::logicalOr( $this->contains( 'medium' ), $this->contains( 'large' ) ); $this->assertThat( $groups, $constraint, 'ApiTestCase::setUp can be slow, tests must be "medium" or "large"' ); } /** * Expect an ApiUsageException to be thrown with the given parameters, which are the same as * ApiUsageException::newWithMessage()'s parameters. This allows checking for an exception * whose text is given by a message key instead of text, so as not to hard-code the message's * text into test code. * @param string|array|Message $msg * @param string|null $code * @param array|null $data * @param int $httpCode */ protected function setExpectedApiException( $msg, $code = null, array $data = null, $httpCode = 0 ) { $expected = ApiUsageException::newWithMessage( null, $msg, $code, $data, $httpCode ); $this->expectException( ApiUsageException::class ); $this->expectExceptionMessage( $expected->getMessage() ); } }