Completed
Push — update/idc-endpoint-migration ( eee79e...2b4bfe )
by
unknown
651:54 queued 641:53
created

Test_REST_Endpoints::mock_jetpack_options()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 16

Duplication

Lines 16
Ratio 100 %

Importance

Changes 0
Metric Value
cc 5
nc 5
nop 2
dl 16
loc 16
rs 9.4222
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3
namespace Automattic\Jetpack\IdentityCrisis;
4
5
use Automattic\Jetpack\Connection\Manager;
6
use Automattic\Jetpack\Connection\REST_Connector;
7
use Automattic\Jetpack\Constants;
8
use Automattic\Jetpack\Identity_Crisis;
9
use Jetpack_options;
10
use PHPUnit\Framework\TestCase;
11
use WorDBless\Options as WorDBless_Options;
12
use WP_REST_Request;
13
use WP_REST_Server;
14
15
/**
16
 * Unit tests for the REST API endpoints.
17
 *
18
 * @package automattic/jetpack-identity-crisis
19
 */
20
class Test_REST_Endpoints extends TestCase {
21
22
	const BLOG_TOKEN = 'new.blogtoken';
23
	const BLOG_ID    = 42;
24
	const USER_ID    = 111;
25
26
	/**
27
	 * REST Server object.
28
	 *
29
	 * @var WP_REST_Server
30
	 */
31
	private $server;
32
33
	/**
34
	 * The original hostname to restore after tests are finished.
35
	 *
36
	 * @var string
37
	 */
38
	private $api_host_original;
39
40
	/**
41
	 * Setting up the test.
42
	 *
43
	 * @before
44
	 */
45
	public function set_up() {
46
		global $wp_rest_server;
47
48
		$wp_rest_server = new WP_REST_Server();
49
		$this->server   = $wp_rest_server;
50
51
		Identity_Crisis::init();
52
53
		do_action( 'rest_api_init' );
54
		new REST_Connector( new Manager() );
55
56
		$this->api_host_original                                  = Constants::get_constant( 'JETPACK__WPCOM_JSON_API_BASE' );
57
		Constants::$set_constants['JETPACK__WPCOM_JSON_API_BASE'] = 'https://public-api.wordpress.com';
58
59
		Constants::$set_constants['JETPACK__API_BASE'] = 'https://jetpack.wordpress.com/jetpack.';
60
61
		set_transient( 'jetpack_assumed_site_creation_date', '2020-02-28 01:13:27' );
62
	}
63
64
	/**
65
	 * Returning the environment into its initial state.
66
	 *
67
	 * @after
68
	 */
69
	public function tear_down() {
70
71
		Constants::$set_constants['JETPACK__WPCOM_JSON_API_BASE'] = $this->api_host_original;
72
73
		delete_transient( 'jetpack_assumed_site_creation_date' );
74
75
		WorDBless_Options::init()->clear_options();
76
	}
77
78
	/**
79
	 * Testing the `/jetpack/v4/identity-crisis/confirm-safe-mode` endpoint.
80
	 */
81
	public function test_confirm_safe_mode() {
82
		add_filter( 'pre_http_request', array( $this, 'intercept_auth_token_request' ), 10, 3 );
83
84
		Jetpack_Options::update_option( 'safe_mode_confirmed', false );
85
86
		$user = wp_get_current_user();
87
		$user->add_cap( 'jetpack_disconnect' );
88
89
		$request = new WP_REST_Request( 'POST', '/jetpack/v4/identity-crisis/confirm-safe-mode' );
90
		$request->set_header( 'Content-Type', 'application/json' );
91
92
		$response = $this->server->dispatch( $request );
93
		$data     = $response->get_data();
94
95
		$user->remove_cap( 'jetpack_disconnect' );
96
97
		remove_filter( 'pre_http_request', array( $this, 'intercept_auth_token_request' ) );
98
		remove_filter( 'jetpack_options', array( $this, 'mock_jetpack_site_connection_options' ) );
99
100
		$this->assertEquals( 200, $response->get_status() );
101
		$this->assertEquals( 'success', $data['code'] );
102
		$this->assertTrue( Jetpack_Options::get_option( 'safe_mode_confirmed' ) );
103
	}
104
105
	/**
106
	 * Testing the `/jetpack/v4/identity-crisis/confirm-safe-mode` endpoint.
107
	 */
108
	public function test_confirm_safe_mode_no_access() {
109
		add_filter( 'pre_http_request', array( $this, 'intercept_auth_token_request' ), 10, 3 );
110
111
		Jetpack_Options::update_option( 'safe_mode_confirmed', false );
112
113
		$request = new WP_REST_Request( 'POST', '/jetpack/v4/identity-crisis/confirm-safe-mode' );
114
		$request->set_header( 'Content-Type', 'application/json' );
115
116
		$response = $this->server->dispatch( $request );
117
118
		remove_filter( 'pre_http_request', array( $this, 'intercept_auth_token_request' ) );
119
		remove_filter( 'jetpack_options', array( $this, 'mock_jetpack_site_connection_options' ) );
120
121
		$this->assertEquals( 401, $response->get_status() );
122
		$this->assertFalse( Jetpack_Options::get_option( 'safe_mode_confirmed' ) );
123
	}
124
125
	/**
126
	 * Testing the `/jetpack/v4/identity-crisis/migrate` endpoint.
127
	 */
128
	public function test_migrate_stats_and_subscribers() {
129
		add_filter( 'pre_http_request', array( $this, 'intercept_auth_token_request' ), 10, 3 );
130
131
		Jetpack_Options::update_option( 'sync_error_idc', true );
132
		Jetpack_Options::update_option( 'migrate_for_idc', false );
133
134
		$user = wp_get_current_user();
135
		$user->add_cap( 'jetpack_disconnect' );
136
137
		$request = new WP_REST_Request( 'POST', '/jetpack/v4/identity-crisis/migrate' );
138
		$request->set_header( 'Content-Type', 'application/json' );
139
140
		$response = $this->server->dispatch( $request );
141
		$data     = $response->get_data();
142
143
		$user->remove_cap( 'jetpack_disconnect' );
144
145
		remove_filter( 'pre_http_request', array( $this, 'intercept_auth_token_request' ) );
146
		remove_filter( 'jetpack_options', array( $this, 'mock_jetpack_site_connection_options' ) );
147
148
		$this->assertEquals( 200, $response->get_status() );
149
		$this->assertEquals( 'success', $data['code'] );
150
		$this->assertFalse( Jetpack_Options::get_option( 'sync_error_idc' ) );
151
		$this->assertTrue( Jetpack_Options::get_option( 'migrate_for_idc' ) );
152
	}
153
154
	/**
155
	 * Testing the `/jetpack/v4/identity-crisis/migrate` endpoint.
156
	 */
157
	public function test_migrate_stats_and_subscribers_no_access() {
158
		add_filter( 'pre_http_request', array( $this, 'intercept_auth_token_request' ), 10, 3 );
159
160
		Jetpack_Options::update_option( 'sync_error_idc', true );
161
		Jetpack_Options::update_option( 'migrate_for_idc', false );
162
163
		$request = new WP_REST_Request( 'POST', '/jetpack/v4/identity-crisis/migrate' );
164
		$request->set_header( 'Content-Type', 'application/json' );
165
166
		$response = $this->server->dispatch( $request );
167
168
		remove_filter( 'pre_http_request', array( $this, 'intercept_auth_token_request' ) );
169
		remove_filter( 'jetpack_options', array( $this, 'mock_jetpack_site_connection_options' ) );
170
171
		$this->assertEquals( 401, $response->get_status() );
172
		$this->assertFalse( Jetpack_Options::get_option( 'safe_mode_confirmed' ) );
173
		$this->assertTrue( Jetpack_Options::get_option( 'sync_error_idc' ) );
174
		$this->assertFalse( Jetpack_Options::get_option( 'migrate_for_idc' ) );
175
	}
176
177
	/**
178
	 * Intercept the `jetpack-token-health` API request sent to WP.com, and mock the "invalid blog token" response.
179
	 *
180
	 * @param bool|array $response The existing response.
181
	 * @param array      $args The request arguments.
182
	 * @param string     $url The request URL.
183
	 *
184
	 * @return array
185
	 */
186 View Code Duplication
	public function intercept_auth_token_request( $response, $args, $url ) {
187
		if ( false === strpos( $url, '/jetpack.token/' ) ) {
188
			return $response;
189
		}
190
191
		return array(
192
			'headers'  => new Requests_Utility_CaseInsensitiveDictionary( array( 'content-type' => 'application/json' ) ),
193
			'body'     => wp_json_encode(
194
				array(
195
					'access_token' => 'mock.token',
196
					'token_type'   => 'X_JETPACK',
197
					'scope'        => ( new Manager() )->sign_role( 'administrator' ),
198
				)
199
			),
200
			'response' => array(
201
				'code'    => 200,
202
				'message' => 'OK',
203
			),
204
		);
205
	}
206
207
	/**
208
	 * Intercept the `Jetpack_Options` call and mock the values.
209
	 * Site level / user-less connection set-up.
210
	 *
211
	 * @param mixed  $value The current option value.
212
	 * @param string $name Option name.
213
	 *
214
	 * @return mixed
215
	 */
216
	public function mock_jetpack_site_connection_options( $value, $name ) {
217
		switch ( $name ) {
218
			case 'blog_token':
219
				return self::BLOG_TOKEN;
220
			case 'id':
221
				return self::BLOG_ID;
222
		}
223
224
		return $value;
225
	}
226
227
	/**
228
	 * Intercept the `Jetpack_Options` call and mock the values.
229
	 * Full connection set-up.
230
	 *
231
	 * @param mixed  $value The current option value.
232
	 * @param string $name Option name.
233
	 *
234
	 * @return mixed
235
	 */
236 View Code Duplication
	public function mock_jetpack_options( $value, $name ) {
237
		switch ( $name ) {
238
			case 'blog_token':
239
				return self::BLOG_TOKEN;
240
			case 'id':
241
				return self::BLOG_ID;
242
			case 'master_user':
243
				return self::USER_ID;
244
			case 'user_tokens':
245
				return array(
246
					self::USER_ID => 'new.usertoken.' . self::USER_ID,
247
				);
248
		}
249
250
		return $value;
251
	}
252
253
}
254