4 * Abstract base class for shared logic when testing ChangesListSpecialPage
9 abstract class AbstractChangesListSpecialPageTestCase
extends MediaWikiTestCase
{
10 // Must be initialized by subclass
12 * @var ChangesListSpecialPage
14 protected $changesListSpecialPage;
16 protected $oldPatrollersGroup;
18 protected function setUp() {
19 global $wgGroupPermissions;
22 $this->setMwGlobals( [
23 'wgRCWatchCategoryMembership' => true,
24 'wgUseRCPatrol' => true,
27 if ( isset( $wgGroupPermissions['patrollers'] ) ) {
28 $this->oldPatrollersGroup
= $wgGroupPermissions['patrollers'];
31 $wgGroupPermissions['patrollers'] = [
36 $this->setTemporaryHook(
37 'ChangesListSpecialPageFilters',
41 # setup the ChangesListSpecialPage (or subclass) object
42 $this->changesListSpecialPage
= $this->getPage();
43 $context = $this->changesListSpecialPage
->getContext();
44 $context = new DerivativeContext( $context );
45 $context->setUser( $this->getTestUser( [ 'patrollers' ] )->getUser() );
46 $this->changesListSpecialPage
->setContext( $context );
47 $this->changesListSpecialPage
->registerFilters();
50 abstract protected function getPage();
52 protected function tearDown() {
53 global $wgGroupPermissions;
57 if ( $this->oldPatrollersGroup
!== null ) {
58 $wgGroupPermissions['patrollers'] = $this->oldPatrollersGroup
;
62 abstract public function provideParseParameters();
65 * @dataProvider provideParseParameters
67 public function testParseParameters( $params, $expected ) {
68 $opts = new FormOptions();
69 foreach ( $expected as $key => $value ) {
70 // Register it as null so sets aren't rejected.
74 FormOptions
::guessType( $expected )
78 $this->changesListSpecialPage
->parseParameters(
83 $this->assertArrayEquals(
85 $opts->getAllValues(),
86 /** ordered= */ false,
92 * @dataProvider validateOptionsProvider
94 public function testValidateOptions( $optionsToSet, $expectedRedirect, $expectedRedirectOptions ) {
97 $output = $this->getMockBuilder( OutputPage
::class )
98 ->disableProxyingToOriginalMethods()
99 ->disableOriginalConstructor()
101 $output->method( 'redirect' )->willReturnCallback(
102 function ( $url ) use ( &$redirectQuery, &$redirected ) {
103 $urlParts = wfParseUrl( $url );
104 $query = $urlParts[ 'query' ] ??
'';
105 parse_str( $query, $redirectQuery );
109 $ctx = new RequestContext();
111 // Give users patrol permissions so we can test that.
112 $user = $this->getTestSysop()->getUser();
113 $ctx->setUser( $user );
115 // Disable this hook or it could break changeType
116 // depending on which other extensions are running.
117 $this->setTemporaryHook(
118 'ChangesListSpecialPageStructuredFilters',
122 $ctx->setOutput( $output );
123 $clsp = $this->changesListSpecialPage
;
124 $clsp->setContext( $ctx );
125 $opts = $clsp->getDefaultOptions();
127 foreach ( $optionsToSet as $option => $value ) {
128 $opts->setValue( $option, $value );
131 $clsp->validateOptions( $opts );
133 $this->assertEquals( $expectedRedirect, $redirected, 'redirection' );
135 if ( $expectedRedirect ) {
136 if ( count( $expectedRedirectOptions ) > 0 ) {
137 $expectedRedirectOptions +
= [
138 'title' => $clsp->getPageTitle()->getPrefixedText(),
142 $this->assertArrayEquals(
143 $expectedRedirectOptions,
145 /* $ordered= */ false,