*/
public function testRegisterInvalidName() {
$resourceLoader = new EmptyResourceLoader();
- $this->setExpectedException( 'MWException', "name 'test!invalid' is invalid" );
+ $this->setExpectedException( MWException::class, "name 'test!invalid' is invalid" );
$resourceLoader->register( 'test!invalid', new ResourceLoaderTestModule() );
}
*/
public function testRegisterInvalidType() {
$resourceLoader = new EmptyResourceLoader();
- $this->setExpectedException( 'MWException', 'ResourceLoader module info type error' );
+ $this->setExpectedException( MWException::class, 'ResourceLoader module info type error' );
$resourceLoader->register( 'test', new stdClass() );
}
*/
public function testAddSourceDupe() {
$rl = new ResourceLoader;
- $this->setExpectedException( 'MWException', 'ResourceLoader duplicate source addition error' );
+ $this->setExpectedException(
+ MWException::class, 'ResourceLoader duplicate source addition error'
+ );
$rl->addSource( 'foo', 'https://example.org/w/load.php' );
$rl->addSource( 'foo', 'https://example.com/w/load.php' );
}
*/
public function testAddSourceInvalid() {
$rl = new ResourceLoader;
- $this->setExpectedException( 'MWException', 'with no "loadScript" key' );
+ $this->setExpectedException( MWException::class, 'with no "loadScript" key' );
$rl->addSource( 'foo', [ 'x' => 'https://example.org/w/load.php' ] );
}
ResourceLoader::clearCache();
$this->setMwGlobals( 'wgResourceLoaderDebug', true );
- $rl = TestingAccessWrapper::newFromClass( 'ResourceLoader' );
+ $rl = TestingAccessWrapper::newFromClass( ResourceLoader::class );
$this->assertEquals(
$case['expected'],
$rl->makeLoaderImplementScript(
* @covers ResourceLoader::makeLoaderImplementScript
*/
public function testMakeLoaderImplementScriptInvalid() {
- $this->setExpectedException( 'MWException', 'Invalid scripts error' );
- $rl = TestingAccessWrapper::newFromClass( 'ResourceLoader' );
+ $this->setExpectedException( MWException::class, 'Invalid scripts error' );
+ $rl = TestingAccessWrapper::newFromClass( ResourceLoader::class );
$rl->makeLoaderImplementScript(
'test', // name
123, // scripts
* @covers ResourceLoader::getCombinedVersion
*/
public function testGetCombinedVersion() {
- $rl = new EmptyResourceLoader();
+ $rl = $this->getMockBuilder( EmptyResourceLoader::class )
+ // Disable log from outputErrorAndLog
+ ->setMethods( [ 'outputErrorAndLog' ] )->getMock();
$rl->register( [
'foo' => self::getSimpleModuleMock(),
'ferry' => self::getFailFerryMock(),
$rl
);
+ // Disable log from makeModuleResponse via outputErrorAndLog
+ $this->setLogger( 'exception', new Psr\Log\NullLogger() );
+
$response = $rl->makeModuleResponse( $context, $modules );
$errors = $rl->getErrors();
'foo' => self::getSimpleModuleMock( 'foo();' ),
'ferry' => self::getFailFerryMock(),
'bar' => self::getSimpleModuleMock( 'bar();' ),
- 'startup' => [ 'class' => 'ResourceLoaderStartUpModule' ],
+ 'startup' => [ 'class' => ResourceLoaderStartUpModule::class ],
] );
$context = $this->getResourceLoaderContext(
[
'getModuleNames'
);
+ // Disable log from makeModuleResponse via outputErrorAndLog
+ $this->setLogger( 'exception', new Psr\Log\NullLogger() );
+
$modules = [ 'startup' => $rl->getModule( 'startup' ) ];
$response = $rl->makeModuleResponse( $context, $modules );
$errors = $rl->getErrors();
'startup response sets state to error'
);
}
+
+ /**
+ * Integration test for modules sending extra HTTP response headers.
+ *
+ * @covers ResourceLoaderModule::getHeaders
+ * @covers ResourceLoaderModule::buildContent
+ * @covers ResourceLoader::makeModuleResponse
+ */
+ public function testMakeModuleResponseExtraHeaders() {
+ $module = $this->getMockBuilder( ResourceLoaderTestModule::class )
+ ->setMethods( [ 'getPreloadLinks' ] )->getMock();
+ $module->method( 'getPreloadLinks' )->willReturn( [
+ 'https://example.org/script.js' => [ 'as' => 'script' ],
+ ] );
+
+ $rl = new EmptyResourceLoader();
+ $rl->register( [
+ 'foo' => $module,
+ ] );
+ $context = $this->getResourceLoaderContext(
+ [ 'modules' => 'foo', 'only' => 'scripts' ],
+ $rl
+ );
+
+ $modules = [ 'foo' => $rl->getModule( 'foo' ) ];
+ $response = $rl->makeModuleResponse( $context, $modules );
+ $extraHeaders = TestingAccessWrapper::newFromObject( $rl )->extraHeaders;
+
+ $this->assertEquals(
+ [
+ 'Link: <https://example.org/script.js>;rel=preload;as=script'
+ ],
+ $extraHeaders,
+ 'Extra headers'
+ );
+ }
+
+ /**
+ * @covers ResourceLoaderModule::getHeaders
+ * @covers ResourceLoaderModule::buildContent
+ * @covers ResourceLoader::makeModuleResponse
+ */
+ public function testMakeModuleResponseExtraHeadersMulti() {
+ $foo = $this->getMockBuilder( ResourceLoaderTestModule::class )
+ ->setMethods( [ 'getPreloadLinks' ] )->getMock();
+ $foo->method( 'getPreloadLinks' )->willReturn( [
+ 'https://example.org/script.js' => [ 'as' => 'script' ],
+ ] );
+
+ $bar = $this->getMockBuilder( ResourceLoaderTestModule::class )
+ ->setMethods( [ 'getPreloadLinks' ] )->getMock();
+ $bar->method( 'getPreloadLinks' )->willReturn( [
+ '/example.png' => [ 'as' => 'image' ],
+ '/example.jpg' => [ 'as' => 'image' ],
+ ] );
+
+ $rl = new EmptyResourceLoader();
+ $rl->register( [ 'foo' => $foo, 'bar' => $bar ] );
+ $context = $this->getResourceLoaderContext(
+ [ 'modules' => 'foo|bar', 'only' => 'scripts' ],
+ $rl
+ );
+
+ $modules = [ 'foo' => $rl->getModule( 'foo' ), 'bar' => $rl->getModule( 'bar' ) ];
+ $response = $rl->makeModuleResponse( $context, $modules );
+ $extraHeaders = TestingAccessWrapper::newFromObject( $rl )->extraHeaders;
+ $this->assertEquals(
+ [
+ 'Link: <https://example.org/script.js>;rel=preload;as=script',
+ 'Link: </example.png>;rel=preload;as=image,</example.jpg>;rel=preload;as=image'
+ ],
+ $extraHeaders,
+ 'Extra headers'
+ );
+ }
+
+ /**
+ * @covers ResourceLoader::respond
+ */
+ public function testRespond() {
+ $rl = $this->getMockBuilder( EmptyResourceLoader::class )
+ ->setMethods( [
+ 'tryRespondNotModified',
+ 'sendResponseHeaders',
+ 'measureResponseTime',
+ ] )
+ ->getMock();
+ $context = $this->getResourceLoaderContext( [ 'modules' => '' ], $rl );
+
+ $rl->expects( $this->once() )->method( 'measureResponseTime' );
+ $this->expectOutputRegex( '/no modules were requested/' );
+
+ $rl->respond( $context );
+ }
+
+ /**
+ * @covers ResourceLoader::measureResponseTime
+ */
+ public function testMeasureResponseTime() {
+ $stats = $this->getMockBuilder( NullStatsdDataFactory::class )
+ ->setMethods( [ 'timing' ] )->getMock();
+ $this->setService( 'StatsdDataFactory', $stats );
+
+ $stats->expects( $this->once() )->method( 'timing' )
+ ->with( 'resourceloader.responseTime', $this->anything() );
+
+ $timing = new Timing();
+ $timing->mark( 'requestShutdown' );
+ $rl = TestingAccessWrapper::newFromObject( new EmptyResourceLoader );
+ $rl->measureResponseTime( $timing );
+ DeferredUpdates::doUpdates();
+ }
}