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