Completed
Push — try/capabilities ( a2fcc0...6ae562 )
by
unknown
08:11
created

Test_Jetpack_Capabilities_JetpackActiveRule   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 31
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 10
c 0
b 0
f 0
wmc 2
lcom 1
cbo 4

2 Methods

Rating   Name   Duplication   Size   Complexity  
A test_check_jetpack_is_active() 0 16 1
A mockJetpackIsActive() 0 12 1
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 {
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

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.

Loading history...
90
	public function test_jetpack_plan_rule() {
91
		$capability = $this->builder
92
			->create( 'jetpack.backup.restore' )
0 ignored issues
show
Unused Code introduced by
The call to Builder::create() has too many arguments starting with 'jetpack.backup.restore'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
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 {
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

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.

Loading history...
122
	public function test_jetpack_plan_supports_rule() {
123
		$capability = $this->builder
124
			->create( 'memberships' )
0 ignored issues
show
Unused Code introduced by
The call to Builder::create() has too many arguments starting with 'memberships'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
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 {
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

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.

Loading history...
154
	public function test_check_role() {
155
		$capability = $this->builder
156
			->create( 'jetpack.backup.restore' )
0 ignored issues
show
Unused Code introduced by
The call to Builder::create() has too many arguments starting with 'jetpack.backup.restore'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
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 {
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

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.

Loading history...
171
	public function test_check_capability() {
172
		$capability = $this->builder
173
			->create( 'jetpack.backup.restore' )
0 ignored issues
show
Unused Code introduced by
The call to Builder::create() has too many arguments starting with 'jetpack.backup.restore'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
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 {
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

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.

Loading history...
188
	public function test_check_filter() {
189
		$capability = $this->builder
190
			->create( 'jetpack.backup.restore' )
0 ignored issues
show
Unused Code introduced by
The call to Builder::create() has too many arguments starting with 'jetpack.backup.restore'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
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' )
0 ignored issues
show
Unused Code introduced by
The call to Builder::create() has too many arguments starting with 'foo.bar'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
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' )
0 ignored issues
show
Unused Code introduced by
The call to Builder::create() has too many arguments starting with 'foo.bar'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
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 ) {
0 ignored issues
show
Documentation introduced by
function ($builder) { ...ole('administrator'); } is of type object<Closure>, but the function expects a object<Automattic\Jetpack\Capabilities\function>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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
}