Completed
Push — add/connection-ui-initial-stat... ( 38c415...23fccd )
by
unknown
54:07 queued 44:38
created

intercept_jetpack_token_health_request_failed()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14

Duplication

Lines 14
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 3
dl 14
loc 14
rs 9.7998
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
2
/**
3
 * Tokens functionality testing.
4
 *
5
 * @package automattic/jetpack-connection
6
 */
7
8
namespace Automattic\Jetpack\Connection;
9
10
use Automattic\Jetpack\Constants;
11
use PHPUnit\Framework\TestCase;
12
use Requests_Utility_CaseInsensitiveDictionary;
13
use WP_Error;
14
15
/**
16
 * Tokens functionality testing.
17
 */
18
class TokensTest extends TestCase {
19
	/**
20
	 * Initialize the object before running the test method.
21
	 *
22
	 * @before
23
	 */
24
	public function set_up() {
25
		$this->tokens = $this->getMockBuilder( 'Automattic\Jetpack\Connection\Tokens' )
26
			->setMethods( array( 'get_access_token' ) )
27
			->getMock();
28
	}
29
30
	/**
31
	 * Clean up the testing environment.
32
	 *
33
	 * @after
34
	 */
35
	public function tear_down() {
36
		remove_all_filters( 'jetpack_options' );
37
		unset( $this->tokens );
38
		Constants::clear_constants();
39
	}
40
41
	/**
42
	 * Test the `validate` functionality when the site is not registered.
43
	 *
44
	 * @covers Automattic\Jetpack\Connection\Tokens::validate
45
	 */
46
	public function test_validate_when_site_is_not_registered() {
47
		$expected = new WP_Error( 'site_not_registered', 'Site not registered.' );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'site_not_registered'.

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...
48
		$this->assertEquals( $expected, $this->tokens->validate() );
49
	}
50
51
	/**
52
	 * Test the `validate` functionality when the current user is not connnected, aka user token is missing.
53
	 *
54
	 * @covers Automattic\Jetpack\Connection\Tokens::validate
55
	 */
56
	public function test_validate_with_missing_user_token() {
57
		add_filter(
58
			'jetpack_options',
59
			function ( $value, $name ) {
60
				return 'id' === $name ? 123 : $value;
61
			},
62
			10,
63
			2
64
		);
65
		$blog_token = (object) array(
66
			'secret'           => 'abcd.1234',
67
			'external_user_id' => null,
68
		);
69
70
		$user_token = false;
71
72
		$this->tokens->expects( $this->exactly( 2 ) )
73
			->method( 'get_access_token' )
74
			->will( $this->onConsecutiveCalls( $blog_token, $user_token ) );
75
		$this->assertFalse( $this->tokens->validate() );
76
	}
77
78
	/**
79
	 * Test the `validate` functionality when the remote request to the `jetpack-token-health` endpoint fails.
80
	 *
81
	 * @covers Automattic\Jetpack\Connection\Tokens::validate
82
	 */
83
	public function test_validate_with_failed_remote_request() {
84
		add_filter(
85
			'jetpack_options',
86
			function ( $value, $name ) {
87
				return 'id' === $name ? 123 : $value;
88
			},
89
			10,
90
			2
91
		);
92
		add_filter( 'pre_http_request', array( $this, 'intercept_jetpack_token_health_request_failed' ), 10, 3 );
93
		$blog_token = (object) array(
94
			'secret'           => 'abcd.1234',
95
			'external_user_id' => null,
96
		);
97
98
		$user_token = (object) array(
99
			'secret'           => 'abcd.4321',
100
			'external_user_id' => 1,
101
		);
102
103
		$this->tokens->expects( $this->exactly( 2 ) )
104
			->method( 'get_access_token' )
105
			->will( $this->onConsecutiveCalls( $blog_token, $user_token ) );
106
107
		$this->assertFalse( $this->tokens->validate() );
108
109
		remove_filter( 'pre_http_request', array( $this, 'intercept_jetpack_token_health_request_failed' ), 10 );
110
	}
111
112
	/**
113
	 * Test the `validate` functionality when the remote request to the `jetpack-token-health` endpoint succeeds.
114
	 *
115
	 * @covers Automattic\Jetpack\Connection\Tokens::validate
116
	 */
117
	public function test_validate() {
118
		add_filter(
119
			'jetpack_options',
120
			function ( $value, $name ) {
121
				return 'id' === $name ? 123 : $value;
122
			},
123
			10,
124
			2
125
		);
126
		add_filter( 'pre_http_request', array( $this, 'intercept_jetpack_token_health_request_success' ), 10, 3 );
127
		$blog_token = (object) array(
128
			'secret'           => 'abcd.1234',
129
			'external_user_id' => null,
130
		);
131
132
		$user_token = (object) array(
133
			'secret'           => 'abcd.4321',
134
			'external_user_id' => 1,
135
		);
136
137
		$this->tokens->expects( $this->exactly( 2 ) )
138
			->method( 'get_access_token' )
139
			->will( $this->onConsecutiveCalls( $blog_token, $user_token ) );
140
141
		$expected = array(
142
			'blog_token' => array(
143
				'is_healthy' => true,
144
			),
145
			'user_token' => array(
146
				'is_healthy'     => true,
147
				'is_master_user' => true,
148
			),
149
		);
150
		$this->assertSame( $expected, $this->tokens->validate() );
151
152
		remove_filter( 'pre_http_request', array( $this, 'intercept_jetpack_token_health_request_success' ), 10 );
153
	}
154
155
	/**
156
	 * Test the `get_signed_token` functionality.
157
	 *
158
	 * @covers Automattic\Jetpack\Connection\Tokens::get_signed_token
159
	 */
160 View Code Duplication
	public function test_get_signed_token() {
161
		$access_token = (object) array(
162
			'external_user_id' => 1,
163
		);
164
165
		// Missing secret.
166
		$invalid_token_error = new WP_Error( 'invalid_token' );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_token'.

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...
167
		$this->assertEquals( $invalid_token_error, ( new Tokens() )->get_signed_token( $access_token ) );
168
		// Secret is null.
169
		$access_token->secret = null;
170
		$this->assertEquals( $invalid_token_error, ( new Tokens() )->get_signed_token( $access_token ) );
171
		// Secret is empty.
172
		$access_token->secret = '';
173
		$this->assertEquals( $invalid_token_error, ( new Tokens() )->get_signed_token( $access_token ) );
174
		// Valid secret.
175
		$access_token->secret = 'abcd.1234';
176
177
		$signed_token = ( new Tokens() )->get_signed_token( $access_token );
178
		$this->assertTrue( strpos( $signed_token, 'token' ) !== false );
179
		$this->assertTrue( strpos( $signed_token, 'timestamp' ) !== false );
180
		$this->assertTrue( strpos( $signed_token, 'nonce' ) !== false );
181
		$this->assertTrue( strpos( $signed_token, 'signature' ) !== false );
182
	}
183
184
	/**
185
	 * Intercept the `jetpack-token-health` API request sent to WP.com, and mock failed response.
186
	 *
187
	 * @param bool|array $response The existing response.
188
	 * @param array      $args The request arguments.
189
	 * @param string     $url The request URL.
190
	 *
191
	 * @return array
192
	 */
193 View Code Duplication
	public function intercept_jetpack_token_health_request_failed( $response, $args, $url ) {
194
		if ( false === strpos( $url, 'jetpack-token-health' ) ) {
195
			return $response;
196
		}
197
198
		return array(
199
			'headers'  => new Requests_Utility_CaseInsensitiveDictionary( array( 'content-type' => 'application/json' ) ),
200
			'body'     => wp_json_encode( array( 'dummy_error' => true ) ),
201
			'response' => array(
202
				'code'    => 500,
203
				'message' => 'failed',
204
			),
205
		);
206
	}
207
208
	/**
209
	 * Intercept the `jetpack-token-health` API request sent to WP.com, and mock successful response.
210
	 *
211
	 * @param bool|array $response The existing response.
212
	 * @param array      $args The request arguments.
213
	 * @param string     $url The request URL.
214
	 *
215
	 * @return array
216
	 */
217
	public function intercept_jetpack_token_health_request_success( $response, $args, $url ) {
218
		if ( false === strpos( $url, 'jetpack-token-health' ) ) {
219
			return $response;
220
		}
221
222
		$body = array(
223
			'blog_token' => array(
224
				'is_healthy' => true,
225
			),
226
			'user_token' => array(
227
				'is_healthy'     => true,
228
				'is_master_user' => true,
229
			),
230
		);
231
232
		return array(
233
			'headers'  => new Requests_Utility_CaseInsensitiveDictionary( array( 'content-type' => 'application/json' ) ),
234
			'body'     => wp_json_encode( $body ),
235
			'response' => array(
236
				'code'    => 200,
237
				'message' => 'OK',
238
			),
239
		);
240
	}
241
}
242