Completed
Push — update/story-block-loading-med... ( e6e62b...d81748 )
by
unknown
28:46 queued 18:45
created

Test_REST_Endpoints::test_connection_reconnect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 23
rs 9.552
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3
namespace Automattic\Jetpack\Connection;
4
5
require_once ABSPATH . WPINC . '/class-IXR.php';
6
7
use Automattic\Jetpack\Connection\Plugin as Connection_Plugin;
8
use Automattic\Jetpack\Connection\Plugin_Storage as Connection_Plugin_Storage;
9
use phpmock\MockBuilder;
10
use PHPUnit\Framework\TestCase;
11
use WP_REST_Request;
12
use WP_REST_Server;
13
use Requests_Utility_CaseInsensitiveDictionary;
14
15
/**
16
 * Unit tests for the REST API endpoints.
17
 *
18
 * @package automattic/jetpack-connection
19
 * @see \Automattic\Jetpack\Connection\REST_Connector
20
 */
21
class Test_REST_Endpoints extends TestCase {
22
23
	/**
24
	 * REST Server object.
25
	 *
26
	 * @var WP_REST_Server
27
	 */
28
	private $server;
29
30
	/**
31
	 * Setting up the test.
32
	 */
33
	public function setUp() {
34
		parent::setUp();
35
36
		global $wp_rest_server;
37
38
		$wp_rest_server = new WP_REST_Server();
39
		$this->server   = $wp_rest_server;
40
41
		do_action( 'rest_api_init' );
42
		new REST_Connector( new Manager() );
43
44
		add_action( 'jetpack_disabled_raw_options', array( $this, 'bypass_raw_options' ) );
45
	}
46
47
	/**
48
	 * Returning the environment into its initial state.
49
	 */
50
	public function tearDown() {
51
		parent::tearDown();
52
53
		remove_action( 'jetpack_disabled_raw_options', array( $this, 'bypass_raw_options' ) );
54
	}
55
56
	/**
57
	 * Testing the `/jetpack/v4/remote_authorize` endpoint.
58
	 */
59
	public function test_remote_authorize() {
60
		$this->request = new WP_REST_Request( 'POST', '/jetpack/v4/remote_authorize' );
61
		$this->request->set_header( 'Content-Type', 'application/json' );
62
		$this->request->set_body( '{ "state": 111, "secret": "12345", "redirect_uri": "https://example.org", "code": "54321" }' );
63
64
		$response = $this->server->dispatch( $this->request );
65
		$data     = $response->get_data();
66
67
		$this->assertEquals( 400, $data['code'] );
68
		$this->assertContains( '[verify_secrets_missing]', $data['message'] );
69
	}
70
71
	/**
72
	 * Testing the `/jetpack/v4/connection` endpoint.
73
	 */
74
	public function test_connection() {
75
		$builder = new MockBuilder();
76
		$builder->setNamespace( 'Automattic\Jetpack' )
77
				->setName( 'apply_filters' )
78
				->setFunction(
79
					function( $hook, $value ) {
80
						return 'jetpack_offline_mode' === $hook ? true : $value;
81
					}
82
				);
83
84
		$mock = $builder->build();
85
		$mock->enable();
86
87
		$this->request = new WP_REST_Request( 'GET', '/jetpack/v4/connection' );
88
89
		$response = $this->server->dispatch( $this->request );
90
		$data     = $response->get_data();
91
92
		$this->assertFalse( $data['isActive'] );
93
		$this->assertFalse( $data['isRegistered'] );
94
		$this->assertTrue( $data['offlineMode']['isActive'] );
95
	}
96
97
	/**
98
	 * Testing the `/jetpack/v4/connection/plugins` endpoint.
99
	 */
100
	public function test_connection_plugins() {
101
		$user = wp_get_current_user();
102
		$user->add_cap( 'activate_plugins' );
103
104
		$plugins = array(
105
			array(
106
				'name' => 'Plugin Name 1',
107
				'slug' => 'plugin-slug-1',
108
			),
109
			array(
110
				'name' => 'Plugin Name 2',
111
				'slug' => 'plugin-slug-2',
112
			),
113
		);
114
115
		array_walk(
116
			$plugins,
117
			function( $plugin ) {
118
				( new Connection_Plugin( $plugin['slug'] ) )->add( $plugin['name'] );
119
			}
120
		);
121
122
		Connection_Plugin_Storage::configure();
123
124
		$this->request = new WP_REST_Request( 'GET', '/jetpack/v4/connection/plugins' );
125
126
		$response = $this->server->dispatch( $this->request );
127
128
		$this->assertEquals( $plugins, $response->get_data() );
129
130
		$user->remove_cap( 'activate_plugins' );
131
	}
132
133
	/**
134
	 * Testing the `connection/reconnect` endpoint.
135
	 */
136
	public function test_connection_reconnect() {
137
		$user = wp_get_current_user();
138
		$user->add_cap( 'jetpack_disconnect' );
139
140
		$this->request = new WP_REST_Request( 'POST', '/jetpack/v4/connection/reconnect' );
141
		$this->request->set_header( 'Content-Type', 'application/json' );
142
		$this->request->set_body( wp_json_encode( array( 'action' => 'reconnect' ) ) );
143
144
		set_transient( 'jetpack_assumed_site_creation_date', '2020-02-28 01:13:27' );
145
		add_filter( 'pre_http_request', array( $this, 'intercept_register_request' ), 10, 3 );
146
147
		$response = $this->server->dispatch( $this->request );
148
		$this->assertEquals( 200, $response->get_status() );
149
150
		$data = $response->get_data();
151
		$this->assertEquals( 'in_progress', $data['status'] );
152
		$this->assertEquals( 0, strpos( $data['authorizeUrl'], 'https://jetpack.wordpress.com/jetpack.authorize/1' ) );
153
154
		remove_filter( 'pre_http_request', array( $this, 'intercept_register_request' ), 10 );
155
		delete_transient( 'jetpack_assumed_site_creation_date' );
156
157
		$user->remove_cap( 'jetpack_disconnect' );
158
	}
159
160
	/**
161
	 * This filter callback allow us to skip the database query by `Jetpack_Options` to retrieve the option.
162
	 *
163
	 * @param array $options List of options already skipping the database request.
164
	 *
165
	 * @return array
166
	 */
167
	public function bypass_raw_options( array $options ) {
168
		$options[ Manager::SECRETS_OPTION_NAME ] = true;
169
170
		return $options;
171
	}
172
173
	/**
174
	 * Intercept the `jetpack.register` API request sent to WP.com, and mock the response.
175
	 *
176
	 * @param bool|array $response The existing response.
177
	 * @param array      $args The request arguments.
178
	 * @param string     $url The request URL.
179
	 *
180
	 * @return array
181
	 */
182
	public function intercept_register_request( $response, $args, $url ) {
183
		if ( false === strpos( $url, 'jetpack.register' ) ) {
184
			return $response;
185
		}
186
187
		return array(
188
			'headers'  => new Requests_Utility_CaseInsensitiveDictionary( array( 'content-type' => 'application/json' ) ),
189
			'body'     => wp_json_encode(
190
				array(
191
					'jetpack_id'     => '12345',
192
					'jetpack_secret' => 'sample_secret',
193
				)
194
			),
195
			'response' => array(
196
				'code'    => 200,
197
				'message' => 'OK',
198
			),
199
		);
200
	}
201
202
}
203