|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Automattic\Jetpack; |
|
4
|
|
|
|
|
5
|
|
|
use Automattic\Jetpack\Capabilities; |
|
6
|
|
|
use phpmock\Mock; |
|
7
|
|
|
use phpmock\MockBuilder; |
|
8
|
|
|
|
|
9
|
|
|
class Test_Jetpack_Capabilities_Base extends \WP_UnitTestCase { |
|
10
|
|
|
var $builder; |
|
11
|
|
|
var $current_product_slug; |
|
12
|
|
|
var $current_supports_slug; |
|
13
|
|
|
|
|
14
|
|
|
public function setUp() { |
|
15
|
|
|
\Automattic\Jetpack\Capabilities::clear(); |
|
16
|
|
|
$this->builder = new Capabilities\Builder(); |
|
17
|
|
|
$this->setUserRole( 'editor' ); |
|
18
|
|
|
} |
|
19
|
|
|
|
|
20
|
|
|
public function tearDown() { |
|
21
|
|
|
Mock::disableAll(); |
|
22
|
|
|
\Mockery::close(); |
|
23
|
|
|
} |
|
24
|
|
|
|
|
25
|
|
|
/** |
|
26
|
|
|
* Utility functions |
|
27
|
|
|
*/ |
|
28
|
|
|
protected function setUserRole( $role ) { |
|
29
|
|
|
$user = wp_get_current_user(); |
|
30
|
|
|
$user->set_role( $role ); |
|
31
|
|
|
} |
|
32
|
|
|
|
|
33
|
|
|
protected function addUserCapability( $cap ) { |
|
34
|
|
|
$user = wp_get_current_user(); |
|
35
|
|
|
$user->add_cap( $cap ); |
|
36
|
|
|
} |
|
37
|
|
|
} |
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* Test registering and getting capabilities |
|
41
|
|
|
*/ |
|
42
|
|
|
class Test_Jetpack_Capabilities_Global extends Test_Jetpack_Capabilities_Base { |
|
43
|
|
|
public function test_register_rule() { |
|
44
|
|
|
$rule = new Capabilities\AllRule(); |
|
45
|
|
|
\Automattic\Jetpack\Capabilities::register( $rule, 'foo' ); |
|
46
|
|
|
|
|
47
|
|
|
$this->assertSame( $rule, \Automattic\Jetpack\Capabilities::get( 'foo' ) ); |
|
48
|
|
|
} |
|
49
|
|
|
|
|
50
|
|
|
public function test_map_meta_cap_wraps_jetpack_capabilities() { |
|
51
|
|
|
// let's create a capability we don't comply with... yet |
|
52
|
|
|
$capability = $this->builder |
|
53
|
|
|
->create() |
|
54
|
|
|
->require_wp_role( 'administrator' ) |
|
55
|
|
|
->register( 'jetpack.backup.restore' )->get(); |
|
56
|
|
|
|
|
57
|
|
|
// quick assertion to make sure it's false |
|
58
|
|
|
$this->assertFalse( $capability->check()->granted() ); |
|
59
|
|
|
|
|
60
|
|
|
// oh look! it's part of WP's caps now |
|
61
|
|
|
$this->assertFalse( current_user_can( 'jetpack.backup.restore' ) ); |
|
62
|
|
|
|
|
63
|
|
|
// now let's comply |
|
64
|
|
|
$this->setUserRole( 'administrator' ); |
|
65
|
|
|
|
|
66
|
|
|
// has admin privilege |
|
67
|
|
|
$this->assertTrue( current_user_can( 'jetpack.backup.restore' ) ); |
|
68
|
|
|
} |
|
69
|
|
|
|
|
70
|
|
|
public function test_build_capability_automatically_registers_it() { |
|
71
|
|
|
$cap = Capabilities::build( 'foo' )->require_wp_role( 'administrator' )->get(); |
|
72
|
|
|
|
|
73
|
|
|
$this->assertSame( $cap, \Automattic\Jetpack\Capabilities::get( 'foo' ) ); |
|
74
|
|
|
|
|
75
|
|
|
// quick assertion to make sure it's false |
|
76
|
|
|
$this->assertFalse( \Automattic\Jetpack\Capabilities::granted( 'foo' ) ); |
|
77
|
|
|
|
|
78
|
|
|
// oh look! it's part of WP's caps now |
|
79
|
|
|
$this->assertFalse( current_user_can( 'foo' ) ); |
|
80
|
|
|
|
|
81
|
|
|
// now let's comply |
|
82
|
|
|
$this->setUserRole( 'administrator' ); |
|
83
|
|
|
|
|
84
|
|
|
// has admin privilege |
|
85
|
|
|
$this->assertTrue( current_user_can( 'foo' ) ); |
|
86
|
|
|
} |
|
87
|
|
|
} |
|
88
|
|
|
|
|
89
|
|
View Code Duplication |
class Test_Jetpack_Capabilities_Jetpack_Plan extends Test_Jetpack_Capabilities_Base { |
|
|
|
|
|
|
90
|
|
|
public function test_jetpack_plan_rule() { |
|
91
|
|
|
$capability = $this->builder |
|
92
|
|
|
->create( 'jetpack.backup.restore' ) |
|
|
|
|
|
|
93
|
|
|
->require_minimum_jetpack_plan( 'a_nice_plan' ) |
|
94
|
|
|
->get(); |
|
95
|
|
|
|
|
96
|
|
|
// expected plan |
|
97
|
|
|
$this->mockJetpackPlan( 'a_nice_plan' ); |
|
98
|
|
|
|
|
99
|
|
|
$this->assertTrue( $capability->check()->granted() ); |
|
100
|
|
|
|
|
101
|
|
|
// unexpected plan |
|
102
|
|
|
$this->mockJetpackPlan( 'some_other_plan' ); |
|
103
|
|
|
|
|
104
|
|
|
$this->assertFalse( $capability->check()->granted() ); |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
private function mockJetpackPlan( $product_slug ) { |
|
108
|
|
|
$this->current_product_slug = $product_slug; |
|
109
|
|
|
|
|
110
|
|
|
$mockPlan = \Mockery::mock('alias:Jetpack_Plan'); |
|
111
|
|
|
|
|
112
|
|
|
// mock the static method Jetpack_Plan::get and return the instance prop |
|
113
|
|
|
$mockPlan |
|
114
|
|
|
->shouldReceive('get') |
|
115
|
|
|
->andReturnUsing( function() { |
|
116
|
|
|
return [ 'product_slug' => $this->current_product_slug ]; |
|
117
|
|
|
} ); |
|
118
|
|
|
} |
|
119
|
|
|
} |
|
120
|
|
|
|
|
121
|
|
View Code Duplication |
class Test_Jetpack_Capabilities_Jetpack_Plan_Supports extends Test_Jetpack_Capabilities_Base { |
|
|
|
|
|
|
122
|
|
|
public function test_jetpack_plan_supports_rule() { |
|
123
|
|
|
$capability = $this->builder |
|
124
|
|
|
->create( 'memberships' ) |
|
|
|
|
|
|
125
|
|
|
->require_jetpack_plan_supports( 'recurring-payments' ) |
|
126
|
|
|
->get(); |
|
127
|
|
|
|
|
128
|
|
|
// expected supports |
|
129
|
|
|
$this->mockJetpackPlanSupports( 'recurring-payments' ); |
|
130
|
|
|
|
|
131
|
|
|
$this->assertTrue( $capability->check()->granted() ); |
|
132
|
|
|
|
|
133
|
|
|
// unexpected supports (clears previous value) |
|
134
|
|
|
$this->mockJetpackPlanSupports( 'not-recurring-payments' ); |
|
135
|
|
|
|
|
136
|
|
|
$this->assertFalse( $capability->check()->granted() ); |
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
private function mockJetpackPlanSupports( $supports_slug ) { |
|
140
|
|
|
$this->current_supports_slug = $supports_slug; |
|
141
|
|
|
|
|
142
|
|
|
$mockPlan = \Mockery::mock('alias:Jetpack_Plan'); |
|
143
|
|
|
|
|
144
|
|
|
// mock the static method Jetpack_Plan::supports and return the instance prop |
|
145
|
|
|
$mockPlan |
|
146
|
|
|
->shouldReceive('supports') |
|
147
|
|
|
->andReturnUsing( function( $slug ) { |
|
148
|
|
|
return $slug === $this->current_supports_slug; |
|
149
|
|
|
} ); |
|
150
|
|
|
} |
|
151
|
|
|
} |
|
152
|
|
|
|
|
153
|
|
View Code Duplication |
class Test_Jetpack_Capabilities_WP_Role extends Test_Jetpack_Capabilities_Base { |
|
|
|
|
|
|
154
|
|
|
public function test_check_role() { |
|
155
|
|
|
$capability = $this->builder |
|
156
|
|
|
->create( 'jetpack.backup.restore' ) |
|
|
|
|
|
|
157
|
|
|
->require_wp_role( 'administrator' ) |
|
158
|
|
|
->get(); |
|
159
|
|
|
|
|
160
|
|
|
// no admin privilege |
|
161
|
|
|
$this->assertFalse( $capability->check()->granted() ); |
|
162
|
|
|
|
|
163
|
|
|
$this->setUserRole( 'administrator' ); |
|
164
|
|
|
|
|
165
|
|
|
// has admin privilege |
|
166
|
|
|
$this->assertTrue( $capability->check()->granted() ); |
|
167
|
|
|
} |
|
168
|
|
|
} |
|
169
|
|
|
|
|
170
|
|
View Code Duplication |
class Test_Jetpack_Capabilities_WP_Capability extends Test_Jetpack_Capabilities_Base { |
|
|
|
|
|
|
171
|
|
|
public function test_check_capability() { |
|
172
|
|
|
$capability = $this->builder |
|
173
|
|
|
->create( 'jetpack.backup.restore' ) |
|
|
|
|
|
|
174
|
|
|
->require_wp_capability( 'do_a_thing' ) |
|
175
|
|
|
->get(); |
|
176
|
|
|
|
|
177
|
|
|
// no admin privilege |
|
178
|
|
|
$this->assertFalse( $capability->check()->granted() ); |
|
179
|
|
|
|
|
180
|
|
|
$this->addUserCapability( 'do_a_thing' ); |
|
181
|
|
|
|
|
182
|
|
|
// has admin privilege |
|
183
|
|
|
$this->assertTrue( $capability->check()->granted() ); |
|
184
|
|
|
} |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
View Code Duplication |
class Test_Jetpack_Capabilities_WP_Filter extends Test_Jetpack_Capabilities_Base { |
|
|
|
|
|
|
188
|
|
|
public function test_check_filter() { |
|
189
|
|
|
$capability = $this->builder |
|
190
|
|
|
->create( 'jetpack.backup.restore' ) |
|
|
|
|
|
|
191
|
|
|
->require_filter( 'my_filter', true ) |
|
192
|
|
|
->get(); |
|
193
|
|
|
|
|
194
|
|
|
// no admin privilege |
|
195
|
|
|
$this->assertFalse( $capability->check()->granted() ); |
|
196
|
|
|
|
|
197
|
|
|
add_filter( 'my_filter', '__return_true' ); |
|
198
|
|
|
|
|
199
|
|
|
// has admin privilege |
|
200
|
|
|
$this->assertTrue( $capability->check()->granted() ); |
|
201
|
|
|
} |
|
202
|
|
|
} |
|
203
|
|
|
|
|
204
|
|
|
class Test_Jetpack_Capabilities_JetpackActiveRule extends Test_Jetpack_Capabilities_Base { |
|
205
|
|
|
public function test_check_jetpack_is_active() { |
|
206
|
|
|
$capability = $this->builder |
|
207
|
|
|
->create( 'foo.bar' ) |
|
|
|
|
|
|
208
|
|
|
->require_jetpack_is_active() |
|
209
|
|
|
->get(); |
|
210
|
|
|
|
|
211
|
|
|
$this->mockJetpackIsActive( false ); |
|
212
|
|
|
|
|
213
|
|
|
// no admin privilege |
|
214
|
|
|
$this->assertFalse( $capability->check()->granted() ); |
|
215
|
|
|
|
|
216
|
|
|
$this->mockJetpackIsActive( true ); |
|
217
|
|
|
|
|
218
|
|
|
// has admin privilege |
|
219
|
|
|
$this->assertTrue( $capability->check()->granted() ); |
|
220
|
|
|
} |
|
221
|
|
|
|
|
222
|
|
|
private function mockJetpackIsActive( $is_active ) { |
|
223
|
|
|
$this->current_is_active = $is_active; |
|
224
|
|
|
|
|
225
|
|
|
$mockPlan = \Mockery::mock('alias:Jetpack'); |
|
226
|
|
|
|
|
227
|
|
|
// mock the static method Jetpack::supports and return the instance prop |
|
228
|
|
|
$mockPlan |
|
229
|
|
|
->shouldReceive('is_active') |
|
230
|
|
|
->andReturnUsing( function() { |
|
231
|
|
|
return $this->current_is_active; |
|
232
|
|
|
} ); |
|
233
|
|
|
} |
|
234
|
|
|
} |
|
235
|
|
|
|
|
236
|
|
|
class Test_Jetpack_Capabilities_BlogStickersRule extends Test_Jetpack_Capabilities_Base { |
|
237
|
|
|
public function test_check_has_blog_sticker() { |
|
238
|
|
|
$capability = $this->builder |
|
239
|
|
|
->create( 'foo.bar' ) |
|
|
|
|
|
|
240
|
|
|
->require_any_blog_sticker( [ 'expected_sticker' ] ) |
|
241
|
|
|
->get(); |
|
242
|
|
|
|
|
243
|
|
|
$current_blog_stickers = [ 'not_expected_sticker' ]; |
|
244
|
|
|
|
|
245
|
|
|
// mock the has_blog_sticker function |
|
246
|
|
|
$builder = new MockBuilder(); |
|
247
|
|
|
$builder->setNamespace( 'Automattic\Jetpack\Capabilities' ) |
|
248
|
|
|
->setName( 'has_any_blog_stickers' ) |
|
249
|
|
|
->setFunction( function( $stickers, $blog_id ) use ( &$current_blog_stickers ) { |
|
250
|
|
|
return ! empty( array_intersect( $stickers, $current_blog_stickers ) ); |
|
251
|
|
|
} ); |
|
252
|
|
|
$builder->build()->enable(); |
|
253
|
|
|
|
|
254
|
|
|
// does not have sticker |
|
255
|
|
|
$this->assertFalse( $capability->check()->granted() ); |
|
256
|
|
|
|
|
257
|
|
|
$current_blog_stickers[] = 'expected_sticker'; |
|
258
|
|
|
|
|
259
|
|
|
// has sticker |
|
260
|
|
|
$this->assertTrue( $capability->check()->granted() ); |
|
261
|
|
|
} |
|
262
|
|
|
} |
|
263
|
|
|
|
|
264
|
|
|
class Test_Jetpack_Capabilities_Builder extends Test_Jetpack_Capabilities_Base { |
|
265
|
|
|
public function test_builder_registers_capability() { |
|
266
|
|
|
$capability = $this->builder |
|
267
|
|
|
->create() |
|
268
|
|
|
->register( 'jetpack.test' ) |
|
269
|
|
|
->get(); |
|
270
|
|
|
|
|
271
|
|
|
$this->assertSame( $capability, \Automattic\Jetpack\Capabilities::get( 'jetpack.test' ) ); |
|
272
|
|
|
|
|
273
|
|
|
} |
|
274
|
|
|
|
|
275
|
|
|
public function test_builder_supports_nesting_optional_rules() { |
|
276
|
|
|
$capability = $this->builder |
|
277
|
|
|
->create() |
|
278
|
|
|
->require_any( function( $builder ) { |
|
|
|
|
|
|
279
|
|
|
echo "Adding nested roles\n"; |
|
280
|
|
|
$builder |
|
281
|
|
|
->require_wp_role( 'subscriber' ) |
|
282
|
|
|
->require_wp_role( 'administrator' ); |
|
283
|
|
|
} ) |
|
284
|
|
|
->register( 'jetpack.test' ) |
|
285
|
|
|
->get(); |
|
286
|
|
|
|
|
287
|
|
|
$this->assertFalse( $capability->check()->granted() ); |
|
288
|
|
|
|
|
289
|
|
|
$this->setUserRole( 'subscriber' ); |
|
290
|
|
|
|
|
291
|
|
|
$this->assertTrue( $capability->check()->granted() ); |
|
292
|
|
|
|
|
293
|
|
|
$this->setUserRole( 'administrator' ); |
|
294
|
|
|
|
|
295
|
|
|
$this->assertTrue( $capability->check()->granted() ); |
|
296
|
|
|
|
|
297
|
|
|
$this->setUserRole( 'guest' ); |
|
298
|
|
|
|
|
299
|
|
|
$this->assertFalse( $capability->check()->granted() ); |
|
300
|
|
|
} |
|
301
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.