Most accesses to this value (other than technically incorrect use via WebRequest::getVal), such as in various extensions, call Action::getActionName($ctx) rather than MediaWiki::getAction or the new RequestContext::getActionName. Related changes recently: * Introduced in3fdfef96e4(I1e259b54dca4). * Primary caller optimised ind7beb0e4ec(I72ffc9f36613bf9). * Warning for misuse added in Ib9fc34ca64b7c0e89. This fixes a bug in DerivativeContext, which got exposed by the ActionTest test cases, which happen to use DerivativeContext and inheriting from the global RequestContext. That's not ideal for the test to do, but did luckily help find this bug. The issue is that when changing the title or wikipage, the action cache be cleared and re-computed the next time it is accessed. The RequestContext class (which is also a mutable context) does the same and that is already covered by tests. Bug: T314008 Depends-On: I8434442a61449c16981b19935f2dbdf18e4b4e50 Change-Id: I7d40e7ca4878d43fd7d7614d9c8cf8d29a8c7c4b
135 lines
4.4 KiB
PHP
135 lines
4.4 KiB
PHP
<?php
|
|
|
|
use MediaWiki\Actions\ActionFactory;
|
|
use MediaWiki\Permissions\Authority;
|
|
|
|
/**
|
|
* @covers DerivativeContext
|
|
*/
|
|
class DerivativeContextTest extends MediaWikiIntegrationTestCase {
|
|
|
|
public function provideGetterSetter() {
|
|
$initialContext = new RequestContext();
|
|
yield 'get/set Context' => [
|
|
'initialContext' => $initialContext,
|
|
'initialValue' => $initialContext,
|
|
'newValue' => new RequestContext(),
|
|
'getter' => 'getContext',
|
|
'setter' => 'setContext'
|
|
];
|
|
yield 'get/set Config' => [
|
|
'initialContext' => $initialContext,
|
|
'initialValue' => new HashConfig(),
|
|
'newValue' => new HashConfig(),
|
|
'getter' => 'getConfig',
|
|
'setter' => 'setConfig'
|
|
];
|
|
yield 'get/set OutputPage' => [
|
|
'initialContext' => $initialContext,
|
|
'initialValue' => $this->createNoOpMock( OutputPage::class ),
|
|
'newValue' => $this->createNoOpMock( OutputPage::class ),
|
|
'getter' => 'getOutput',
|
|
'setter' => 'setOutput'
|
|
];
|
|
yield 'get/set User' => [
|
|
'initialContext' => $initialContext,
|
|
'initialValue' => $this->createNoOpMock( User::class ),
|
|
'newValue' => $this->createNoOpMock( User::class ),
|
|
'getter' => 'getUser',
|
|
'setter' => 'setUser'
|
|
];
|
|
yield 'get/set Authority' => [
|
|
'initialContext' => $initialContext,
|
|
'initialValue' => $this->createNoOpMock( Authority::class ),
|
|
'newValue' => $this->createNoOpMock( Authority::class ),
|
|
'getter' => 'getAuthority',
|
|
'setter' => 'setAuthority'
|
|
];
|
|
yield 'get/set Language' => [
|
|
'initialContext' => $initialContext,
|
|
'initialValue' => $this->createNoOpMock( Language::class ),
|
|
'newValue' => $this->createNoOpMock( Language::class ),
|
|
'getter' => 'getLanguage',
|
|
'setter' => 'setLanguage'
|
|
];
|
|
yield 'get/set WebRequest' => [
|
|
'initialContext' => $initialContext,
|
|
'initialValue' => new FauxRequest(),
|
|
'newValue' => new FauxRequest(),
|
|
'getter' => 'getRequest',
|
|
'setter' => 'setRequest'
|
|
];
|
|
$initialTitle = $this->createMock( Title::class );
|
|
$initialTitle->expects( $this->any() )->method( 'equals' );
|
|
yield 'get/set Title' => [
|
|
'initialContext' => $initialContext,
|
|
'initialValue' => $initialTitle,
|
|
'newValue' => $this->createNoOpMock( Title::class ),
|
|
'getter' => 'getTitle',
|
|
'setter' => 'setTitle',
|
|
];
|
|
$initialWikiPage = $this->createMock( WikiPage::class );
|
|
$initialWikiPage->expects( $this->any() )->method( 'getTitle' )->willReturn( $initialTitle );
|
|
$newWikiPage = $this->createMock( WikiPage::class );
|
|
$newWikiPage->expects( $this->any() )->method( 'getTitle' );
|
|
yield 'get/set WikiPage' => [
|
|
'initialContext' => $initialContext,
|
|
'initialValue' => $initialWikiPage,
|
|
'newValue' => $newWikiPage,
|
|
'getter' => 'getWikiPage',
|
|
'setter' => 'setWikiPage',
|
|
];
|
|
yield 'get/set ActionName' => [
|
|
'initialContext' => $initialContext,
|
|
'initialValue' => 'initActionName',
|
|
'newValue' => 'newActionName',
|
|
'getter' => 'getActionName',
|
|
'setter' => 'setActionName',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideGetterSetter
|
|
*/
|
|
public function testGetterSetter(
|
|
IContextSource $initialContext,
|
|
$initialValue,
|
|
$newValue,
|
|
string $getter,
|
|
string $setter
|
|
) {
|
|
if ( $setter !== 'setContext' ) {
|
|
$initialContext->$setter( $initialValue );
|
|
}
|
|
|
|
$derivativeContext = new DerivativeContext( $initialContext );
|
|
$this->assertSame( $initialValue, $derivativeContext->$getter(), 'Get inital value' );
|
|
$derivativeContext->$setter( $newValue );
|
|
$this->assertSame( $newValue, $derivativeContext->$getter(), 'Get new value' );
|
|
}
|
|
|
|
public function testOverideActionName() {
|
|
$parent = new RequestContext();
|
|
$parent->setActionName( 'view' );
|
|
|
|
$factory = $this->createMock( ActionFactory::class );
|
|
$factory
|
|
->method( 'getActionName' )
|
|
->willReturnOnConsecutiveCalls( 'foo', 'bar', 'baz' );
|
|
$this->setService( 'ActionFactory', $factory );
|
|
|
|
$derivative = new DerivativeContext( $parent );
|
|
$this->assertSame( 'view', $derivative->getActionName(), 'default to parent cache' );
|
|
|
|
$derivative->setTitle( $this->createMock( Title::class ) );
|
|
$this->assertSame( 'foo', $derivative->getActionName(), 'recompute after change' );
|
|
$this->assertSame( 'foo', $derivative->getActionName(), 'local cache' );
|
|
|
|
$derivative->setWikiPage( $this->createMock( WikiPage::class ) );
|
|
$this->assertSame( 'bar', $derivative->getActionName(), 'recompute after change' );
|
|
$this->assertSame( 'bar', $derivative->getActionName(), 'local cache' );
|
|
|
|
$derivative->setActionName( 'custom' );
|
|
$this->assertSame( 'custom', $derivative->getActionName(), 'override' );
|
|
}
|
|
}
|