Fix use of GenderCache in ApiPageSet::processTitlesArray
[lhc/web/wiklou.git] / tests / phpunit / includes / block / CompositeBlockTest.php
1 <?php
2
3 use MediaWiki\Block\BlockRestrictionStore;
4 use MediaWiki\Block\CompositeBlock;
5 use MediaWiki\Block\DatabaseBlock;
6 use MediaWiki\Block\Restriction\PageRestriction;
7 use MediaWiki\Block\Restriction\NamespaceRestriction;
8 use MediaWiki\Block\SystemBlock;
9 use MediaWiki\MediaWikiServices;
10
11 /**
12 * @group Database
13 * @group Blocking
14 * @coversDefaultClass \MediaWiki\Block\CompositeBlock
15 */
16 class CompositeBlockTest extends MediaWikiLangTestCase {
17 private function getPartialBlocks() {
18 $sysopId = $this->getTestSysop()->getUser()->getId();
19
20 $userBlock = new DatabaseBlock( [
21 'address' => $this->getTestUser()->getUser(),
22 'by' => $sysopId,
23 'sitewide' => false,
24 ] );
25 $ipBlock = new DatabaseBlock( [
26 'address' => '127.0.0.1',
27 'by' => $sysopId,
28 'sitewide' => false,
29 ] );
30
31 $userBlock->insert();
32 $ipBlock->insert();
33
34 return [
35 'user' => $userBlock,
36 'ip' => $ipBlock,
37 ];
38 }
39
40 private function deleteBlocks( $blocks ) {
41 foreach ( $blocks as $block ) {
42 $block->delete();
43 }
44 }
45
46 /**
47 * @covers ::__construct
48 * @dataProvider provideTestStrictestParametersApplied
49 */
50 public function testStrictestParametersApplied( $blocks, $expected ) {
51 $this->setMwGlobals( [
52 'wgBlockDisablesLogin' => false,
53 'wgBlockAllowsUTEdit' => true,
54 ] );
55
56 $block = new CompositeBlock( [
57 'originalBlocks' => $blocks,
58 ] );
59
60 $this->assertSame( $expected[ 'hideName' ], $block->getHideName() );
61 $this->assertSame( $expected[ 'sitewide' ], $block->isSitewide() );
62 $this->assertSame( $expected[ 'blockEmail' ], $block->isEmailBlocked() );
63 $this->assertSame( $expected[ 'allowUsertalk' ], $block->isUsertalkEditAllowed() );
64 }
65
66 public static function provideTestStrictestParametersApplied() {
67 return [
68 'Sitewide block and partial block' => [
69 [
70 new DatabaseBlock( [
71 'sitewide' => false,
72 'blockEmail' => true,
73 'allowUsertalk' => true,
74 ] ),
75 new DatabaseBlock( [
76 'sitewide' => true,
77 'blockEmail' => false,
78 'allowUsertalk' => false,
79 ] ),
80 ],
81 [
82 'hideName' => false,
83 'sitewide' => true,
84 'blockEmail' => true,
85 'allowUsertalk' => false,
86 ],
87 ],
88 'Partial block and system block' => [
89 [
90 new DatabaseBlock( [
91 'sitewide' => false,
92 'blockEmail' => true,
93 'allowUsertalk' => false,
94 ] ),
95 new SystemBlock( [
96 'systemBlock' => 'proxy',
97 ] ),
98 ],
99 [
100 'hideName' => false,
101 'sitewide' => true,
102 'blockEmail' => true,
103 'allowUsertalk' => false,
104 ],
105 ],
106 'System block and user name hiding block' => [
107 [
108 new DatabaseBlock( [
109 'hideName' => true,
110 'sitewide' => true,
111 'blockEmail' => true,
112 'allowUsertalk' => false,
113 ] ),
114 new SystemBlock( [
115 'systemBlock' => 'proxy',
116 ] ),
117 ],
118 [
119 'hideName' => true,
120 'sitewide' => true,
121 'blockEmail' => true,
122 'allowUsertalk' => false,
123 ],
124 ],
125 'Two lenient partial blocks' => [
126 [
127 new DatabaseBlock( [
128 'sitewide' => false,
129 'blockEmail' => false,
130 'allowUsertalk' => true,
131 ] ),
132 new DatabaseBlock( [
133 'sitewide' => false,
134 'blockEmail' => false,
135 'allowUsertalk' => true,
136 ] ),
137 ],
138 [
139 'hideName' => false,
140 'sitewide' => false,
141 'blockEmail' => false,
142 'allowUsertalk' => true,
143 ],
144 ],
145 ];
146 }
147
148 /**
149 * @covers ::appliesToTitle
150 */
151 public function testBlockAppliesToTitle() {
152 $this->setMwGlobals( [
153 'wgBlockDisablesLogin' => false,
154 ] );
155
156 $blocks = $this->getPartialBlocks();
157
158 $block = new CompositeBlock( [
159 'originalBlocks' => $blocks,
160 ] );
161
162 $pageFoo = $this->getExistingTestPage( 'Foo' );
163 $pageBar = $this->getExistingTestPage( 'User:Bar' );
164
165 $this->getBlockRestrictionStore()->insert( [
166 new PageRestriction( $blocks[ 'user' ]->getId(), $pageFoo->getId() ),
167 new NamespaceRestriction( $blocks[ 'ip' ]->getId(), NS_USER ),
168 ] );
169
170 $this->assertTrue( $block->appliesToTitle( $pageFoo->getTitle() ) );
171 $this->assertTrue( $block->appliesToTitle( $pageBar->getTitle() ) );
172
173 $this->deleteBlocks( $blocks );
174 }
175
176 /**
177 * @covers ::appliesToUsertalk
178 * @covers ::appliesToPage
179 * @covers ::appliesToNamespace
180 */
181 public function testBlockAppliesToUsertalk() {
182 $this->setMwGlobals( [
183 'wgBlockAllowsUTEdit' => true,
184 'wgBlockDisablesLogin' => false,
185 ] );
186
187 $blocks = $this->getPartialBlocks();
188
189 $block = new CompositeBlock( [
190 'originalBlocks' => $blocks,
191 ] );
192
193 $title = $blocks[ 'user' ]->getTarget()->getTalkPage();
194 $page = $this->getExistingTestPage( 'User talk:' . $title->getText() );
195
196 $this->getBlockRestrictionStore()->insert( [
197 new PageRestriction( $blocks[ 'user' ]->getId(), $page->getId() ),
198 new NamespaceRestriction( $blocks[ 'ip' ]->getId(), NS_USER ),
199 ] );
200
201 $this->assertTrue( $block->appliesToUsertalk( $blocks[ 'user' ]->getTarget()->getTalkPage() ) );
202
203 $this->deleteBlocks( $blocks );
204 }
205
206 /**
207 * @covers ::appliesToRight
208 * @dataProvider provideTestBlockAppliesToRight
209 */
210 public function testBlockAppliesToRight( $blocks, $right, $expected ) {
211 $this->setMwGlobals( [
212 'wgBlockDisablesLogin' => false,
213 ] );
214
215 $block = new CompositeBlock( [
216 'originalBlocks' => $blocks,
217 ] );
218
219 $this->assertSame( $block->appliesToRight( $right ), $expected );
220 }
221
222 public static function provideTestBlockAppliesToRight() {
223 return [
224 'Read is not blocked' => [
225 [
226 new DatabaseBlock(),
227 new DatabaseBlock(),
228 ],
229 'read',
230 false,
231 ],
232 'Email is blocked if blocked by any blocks' => [
233 [
234 new DatabaseBlock( [
235 'blockEmail' => true,
236 ] ),
237 new DatabaseBlock( [
238 'blockEmail' => false,
239 ] ),
240 ],
241 'sendemail',
242 true,
243 ],
244 ];
245 }
246
247 /**
248 * @covers ::getPermissionsError
249 * @dataProvider provideGetPermissionsError
250 */
251 public function testGetPermissionsError( $ids, $expectedIdsMsg ) {
252 // Some block options
253 $timestamp = time();
254 $target = '1.2.3.4';
255 $byText = 'MediaWiki default';
256 $formattedByText = "\u{202A}{$byText}\u{202C}";
257 $reason = '';
258 $expiry = 'infinite';
259
260 $block = $this->getMockBuilder( CompositeBlock::class )
261 ->setMethods( [ 'getIds', 'getBlockErrorParams' ] )
262 ->getMock();
263 $block->method( 'getIds' )
264 ->willReturn( $ids );
265 $block->method( 'getBlockErrorParams' )
266 ->willReturn( [
267 $formattedByText,
268 $reason,
269 $target,
270 $formattedByText,
271 null,
272 $timestamp,
273 $target,
274 $expiry,
275 ] );
276
277 $this->assertSame( [
278 'blockedtext-composite',
279 $formattedByText,
280 $reason,
281 $target,
282 $formattedByText,
283 $expectedIdsMsg,
284 $timestamp,
285 $target,
286 $expiry,
287 ], $block->getPermissionsError( RequestContext::getMain() ) );
288 }
289
290 public static function provideGetPermissionsError() {
291 return [
292 'All original blocks are system blocks' => [
293 [],
294 'Your IP address appears in multiple blacklists',
295 ],
296 'One original block is a database block' => [
297 [ 100 ],
298 'Relevant block IDs: #100 (your IP address may also be blacklisted)',
299 ],
300 'Several original blocks are database blocks' => [
301 [ 100, 101, 102 ],
302 'Relevant block IDs: #100, #101, #102 (your IP address may also be blacklisted)',
303 ],
304 ];
305 }
306
307 /**
308 * Get an instance of BlockRestrictionStore
309 *
310 * @return BlockRestrictionStore
311 */
312 protected function getBlockRestrictionStore() : BlockRestrictionStore {
313 return MediaWikiServices::getInstance()->getBlockRestrictionStore();
314 }
315 }