Completed
Push — try/capabilities ( 1eedd1...45f305 )
by
unknown
06:43
created

mockJetpackIsActive()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
namespace Automattic\Jetpack;
4
5
use Automattic\Jetpack\Capabilities;
6
use phpmock\functions\FunctionProvider;
7
8
class Test_Jetpack_Capabilities_Base extends \WP_UnitTestCase {
9
	var $builder;
10
	var $current_product_slug;
11
	var $current_supports_slug;
12
13
	public function setUp() {
14
		\Automattic\Jetpack\Capabilities::clear();
15
		$this->builder = new Capabilities\Builder();
16
		$this->setUserRole( 'editor' );
17
	}
18
19
	public function tearDown() {
20
		\Mockery::close();
21
	}
22
23
	/**
24
	 * Utility functions
25
	 */
26
	protected function setUserRole( $role ) {
27
		$user = wp_get_current_user();
28
		$user->set_role( $role );
29
	}
30
31
	protected function addUserCapability( $cap ) {
32
		$user = wp_get_current_user();
33
		$user->add_cap( $cap );
34
	}
35
}
36
37
/**
38
 * Test registering and getting capabilities
39
 */
40
class Test_Jetpack_Capabilities_Global extends Test_Jetpack_Capabilities_Base {
41
	public function test_register_rule() {
42
		$rule = new Capabilities\AllRule();
43
		\Automattic\Jetpack\Capabilities::register( $rule, 'foo' );
44
45
		$this->assertSame( $rule, \Automattic\Jetpack\Capabilities::get( 'foo' ) );
46
	}
47
48
	public function test_map_meta_cap_wraps_jetpack_capabilities() {
49
		// let's create a capability we don't comply with... yet
50
		$capability = $this->builder
51
			->create()
52
			->require_wp_role( 'administrator' )
53
			->register( 'jetpack.backup.restore' )->get();
54
55
		// quick assertion to make sure it's false
56
		$this->assertFalse( $capability->check()->granted() );
57
58
		// oh look! it's part of WP's caps now
59
		$this->assertFalse( current_user_can( 'jetpack.backup.restore' ) );
60
61
		// now let's comply
62
		$this->setUserRole( 'administrator' );
63
64
		// has admin privilege
65
		$this->assertTrue( current_user_can( 'jetpack.backup.restore' ) );
66
	}
67
68
	public function test_build_capability_automatically_registers_it() {
69
		$cap = Capabilities::build( 'foo' )->require_wp_role( 'administrator' )->get();
70
71
		$this->assertSame( $cap, \Automattic\Jetpack\Capabilities::get( 'foo' ) );
72
73
		// quick assertion to make sure it's false
74
		$this->assertFalse( \Automattic\Jetpack\Capabilities::granted( 'foo' ) );
75
76
		// oh look! it's part of WP's caps now
77
		$this->assertFalse( current_user_can( 'foo' ) );
78
79
		// now let's comply
80
		$this->setUserRole( 'administrator' );
81
82
		// has admin privilege
83
		$this->assertTrue( current_user_can( 'foo' ) );
84
	}
85
}
86
87 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...
88
	public function test_jetpack_plan_rule() {
89
		$capability = $this->builder
90
			->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...
91
			->require_minimum_jetpack_plan( 'a_nice_plan' )
92
			->get();
93
94
		// expected plan
95
		$this->mockJetpackPlan( 'a_nice_plan' );
96
97
		$this->assertTrue( $capability->check()->granted() );
98
99
		// unexpected plan
100
		$this->mockJetpackPlan( 'some_other_plan' );
101
102
		$this->assertFalse( $capability->check()->granted() );
103
	}
104
105
	private function mockJetpackPlan( $product_slug ) {
106
		$this->current_product_slug = $product_slug;
107
108
		$mockPlan = \Mockery::mock('alias:Jetpack_Plan');
109
110
		// mock the static method Jetpack_Plan::get and return the instance prop
111
		$mockPlan
112
			->shouldReceive('get')
113
			->andReturnUsing( function() {
114
				return [ 'product_slug' => $this->current_product_slug ];
115
			} );
116
	}
117
}
118
119 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...
120
	public function test_jetpack_plan_supports_rule() {
121
		$capability = $this->builder
122
			->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...
123
			->require_jetpack_plan_supports( 'recurring-payments' )
124
			->get();
125
126
		// expected supports
127
		$this->mockJetpackPlanSupports( 'recurring-payments' );
128
129
		$this->assertTrue( $capability->check()->granted() );
130
131
		// unexpected supports (clears previous value)
132
		$this->mockJetpackPlanSupports( 'not-recurring-payments' );
133
134
		$this->assertFalse( $capability->check()->granted() );
135
	}
136
137
	private function mockJetpackPlanSupports( $supports_slug ) {
138
		$this->current_supports_slug = $supports_slug;
139
140
		$mockPlan = \Mockery::mock('alias:Jetpack_Plan');
141
142
		// mock the static method Jetpack_Plan::supports and return the instance prop
143
		$mockPlan
144
			->shouldReceive('supports')
145
			->andReturnUsing( function( $slug ) {
146
				return $slug === $this->current_supports_slug;
147
			} );
148
	}
149
}
150
151 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...
152
	public function test_check_role() {
153
		$capability = $this->builder
154
			->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...
155
			->require_wp_role( 'administrator' )
156
			->get();
157
158
		// no admin privilege
159
		$this->assertFalse( $capability->check()->granted() );
160
161
		$this->setUserRole( 'administrator' );
162
163
		// has admin privilege
164
		$this->assertTrue( $capability->check()->granted() );
165
	}
166
}
167
168 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...
169
	public function test_check_capability() {
170
		$capability = $this->builder
171
			->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...
172
			->require_wp_capability( 'do_a_thing' )
173
			->get();
174
175
		// no admin privilege
176
		$this->assertFalse( $capability->check()->granted() );
177
178
		$this->addUserCapability( 'do_a_thing' );
179
180
		// has admin privilege
181
		$this->assertTrue( $capability->check()->granted() );
182
	}
183
}
184
185 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...
186
	public function test_check_filter() {
187
		$capability = $this->builder
188
			->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...
189
			->require_filter( 'my_filter', true )
190
			->get();
191
192
		// no admin privilege
193
		$this->assertFalse( $capability->check()->granted() );
194
195
		add_filter( 'my_filter', '__return_true' );
196
197
		// has admin privilege
198
		$this->assertTrue( $capability->check()->granted() );
199
	}
200
}
201
202
class Test_Jetpack_Capabilities_JetpackActive extends Test_Jetpack_Capabilities_Base {
203
	public function test_check_filter() {
204
		$capability = $this->builder
205
			->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...
206
			->require_jetpack_is_active()
207
			->get();
208
209
		$this->mockJetpackIsActive( false );
210
211
		// no admin privilege
212
		$this->assertFalse( $capability->check()->granted() );
213
214
		$this->mockJetpackIsActive( true );
215
216
		// has admin privilege
217
		$this->assertTrue( $capability->check()->granted() );
218
	}
219
220
	private function mockJetpackIsActive( $is_active ) {
221
		$this->current_is_active = $is_active;
222
223
		$mockPlan = \Mockery::mock('alias:Jetpack');
224
225
		// mock the static method Jetpack::supports and return the instance prop
226
		$mockPlan
227
			->shouldReceive('is_active')
228
			->andReturnUsing( function() {
229
				return $this->current_is_active;
230
			} );
231
	}
232
}
233
234
class Test_Jetpack_Capabilities_Builder extends Test_Jetpack_Capabilities_Base {
235
	public function test_builder_registers_capability() {
236
		$capability = $this->builder
237
			->create()
238
			->register( 'jetpack.test' )
239
			->get();
240
241
		$this->assertSame( $capability, \Automattic\Jetpack\Capabilities::get( 'jetpack.test' ) );
242
243
	}
244
245
	public function test_builder_supports_nesting_optional_rules() {
246
		$capability = $this->builder
247
			->create()
248
			->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...
249
				echo "Adding nested roles\n";
250
				$builder
251
					->require_wp_role( 'subscriber' )
252
					->require_wp_role( 'administrator' );
253
			} )
254
			->register( 'jetpack.test' )
255
			->get();
256
257
		$this->assertFalse( $capability->check()->granted() );
258
259
		$this->setUserRole( 'subscriber' );
260
261
		$this->assertTrue( $capability->check()->granted() );
262
263
		$this->setUserRole( 'administrator' );
264
265
		$this->assertTrue( $capability->check()->granted() );
266
267
		$this->setUserRole( 'guest' );
268
269
		$this->assertFalse( $capability->check()->granted() );
270
	}
271
}