createNoOpMock( Router::class, [ 'getRoutePath', 'getRouteUrl' ] ); $router->method( 'getRoutePath' ) ->willReturnCallback( static function ( string $route, array $pathParams = [], array $queryParams = [] ) use ( $rootPath ) { foreach ( $pathParams as $param => $value ) { // NOTE: we use rawurlencode here, since execute() uses rawurldecode(). // Spaces in path params must be encoded to %20 (not +). // Slashes must be encoded as %2F. $route = str_replace( '{' . $param . '}', rawurlencode( (string)$value ), $route ); } $url = $rootPath . $route; return wfAppendQuery( $url, $queryParams ); } ); $router->method( 'getRouteUrl' ) ->willReturnCallback( static function ( string $route, array $pathParams = [], array $queryParams = [] ) use ( $baseUrl, $router ) { return $baseUrl . $router->getRoutePath( $route, $pathParams, $queryParams ); } ); return $router; } /** * @param Parsoid|MockObject $mockParsoid */ public function resetServicesWithMockedParsoid( $mockParsoid ): void { $services = $this->getServiceContainer(); $parsoidParser = new ParsoidParser( $mockParsoid, $services->getParsoidPageConfigFactory(), $services->getLanguageConverterFactory(), $services->getParserFactory(), $services->getGlobalIdGenerator() ); // Create a mock Parsoid factory that returns the ParsoidParser object // with the mocked Parsoid object. $mockParsoidParserFactory = $this->createNoOpMock( ParsoidParserFactory::class, [ 'create' ] ); $mockParsoidParserFactory->method( 'create' )->willReturn( $parsoidParser ); $this->setService( 'ParsoidParserFactory', $mockParsoidParserFactory ); } /** * @return PageHTMLHandler */ public function newPageHtmlHandler( ?RequestInterface $request = null ) { $services = $this->getServiceContainer(); $config = [ MainConfigNames::RightsUrl => 'https://example.com/rights', MainConfigNames::RightsText => 'some rights', MainConfigNames::ParsoidCacheConfig => MainConfigSchema::getDefaultValue( MainConfigNames::ParsoidCacheConfig ) ]; $helperFactory = $this->createNoOpMock( PageRestHelperFactory::class, [ 'newPageContentHelper', 'newHtmlOutputRendererHelper', 'newHtmlMessageOutputHelper', 'newPageRedirectHelper' ] ); $helperFactory->method( 'newPageContentHelper' ) ->willReturn( new PageContentHelper( new ServiceOptions( PageContentHelper::CONSTRUCTOR_OPTIONS, $config ), $services->getRevisionLookup(), $services->getTitleFormatter(), $services->getPageStore() ) ); $parsoidOutputStash = $this->getParsoidOutputStash(); $helperFactory->method( 'newHtmlOutputRendererHelper' ) ->willReturnCallback( static function ( $page, $parameters, $authority, $revision, $lenientRevHandling ) use ( $services, $parsoidOutputStash ) { return new HtmlOutputRendererHelper( $parsoidOutputStash, $services->getStatsdDataFactory(), $services->getParserOutputAccess(), $services->getPageStore(), $services->getRevisionLookup(), $services->getRevisionRenderer(), $services->getParsoidSiteConfig(), $services->getHtmlTransformFactory(), $services->getContentHandlerFactory(), $services->getLanguageFactory(), $page, $parameters, $authority, $revision, $lenientRevHandling ); } ); $helperFactory->method( 'newHtmlMessageOutputHelper' ) ->willReturnCallback( static function ( $page ) { return new HtmlMessageOutputHelper( $page ); } ); $request ??= new RequestData( [] ); $responseFactory = new ResponseFactory( [] ); $helperFactory->method( 'newPageRedirectHelper' ) ->willReturn( new PageRedirectHelper( $services->getRedirectStore(), $services->getTitleFormatter(), $responseFactory, $this->newRouterForPageHandler( 'https://example.test/api' ), '/test/{title}', $request, $services->getLanguageConverterFactory() ) ); return new PageHTMLHandler( $helperFactory ); } /** * @return PageSourceHandler */ public function newPageSourceHandler() { $services = $this->getServiceContainer(); return new PageSourceHandler( $services->getTitleFormatter(), $services->getPageRestHelperFactory() ); } public function newPageHistoryHandler() { $services = $this->getServiceContainer(); return new PageHistoryHandler( $services->getRevisionStore(), $services->getNameTableStoreFactory(), $services->getGroupPermissionsLookup(), $services->getConnectionProvider(), $services->getPageStore(), $services->getTitleFormatter(), $services->getPageRestHelperFactory() ); } public function newPageHistoryCountHandler() { $services = $this->getServiceContainer(); return new PageHistoryCountHandler( $services->getRevisionStore(), $services->getNameTableStoreFactory(), $services->getGroupPermissionsLookup(), $services->getConnectionProvider(), new WANObjectCache( [ 'cache' => $this->parserCacheBagOStuff, ] ), $services->getPageStore(), $services->getPageRestHelperFactory(), $services->getTempUserConfig() ); } public function newLanguageLinksHandler() { $services = $this->getServiceContainer(); return new LanguageLinksHandler( $services->getConnectionProvider(), $services->getLanguageNameUtils(), $services->getTitleFormatter(), $services->getTitleParser(), $services->getPageStore(), $services->getPageRestHelperFactory() ); } private function installMockFileRepo( string $fileName, ?string $redirectedFrom = null ): void { $repo = $this->createNoOpMock( FileRepo::class, [] ); $file = $this->createNoOpMock( File::class, [ 'isLocal', 'exists', 'getRepo', 'getRedirected', 'getName', ] ); $file->method( 'isLocal' )->willReturn( false ); $file->method( 'exists' )->willReturn( true ); $file->method( 'getRepo' )->willReturn( $repo ); $file->method( 'getRedirected' )->willReturn( $redirectedFrom ); $file->method( 'getName' )->willReturn( $fileName ); $repoGroup = $this->createNoOpMock( RepoGroup::class, [ 'findFile' ] ); $repoGroup->expects( $this->atLeastOnce() )->method( 'findFile' ) ->willReturn( $file ); $this->setService( 'RepoGroup', $repoGroup ); } }