Completed
Push — update/phpunit-php-8 ( e34c58...05aa04 )
by
unknown
137:27 queued 129:12
created

Error_Handler_Test::test_verify_error()   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 0
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
2
/**
3
 * Connection Manager functionality testing.
4
 *
5
 * @package automattic/jetpack-connection
6
 */
7
8
namespace Automattic\Jetpack\Connection;
9
10
use WorDBless\BaseTestCase;
11
12
/**
13
 * Connection Manager functionality testing.
14
 */
15
class Error_Handler_Test extends BaseTestCase {
16
	use \Yoast\PHPUnitPolyfills\Polyfills\AssertIsType;
17
18
	/**
19
	 * Initialize tests
20
	 *
21
	 * @before
22
	 */
23
	public function set_up() {
24
		$this->error_handler = Error_Handler::get_instance();
25
	}
26
27
	/**
28
	 * Generates a sample WP_Error object in the same format Manager class does for broken signatures
29
	 *
30
	 * @param string $error_code The error code you want the error to have.
31
	 * @param string $user_id The user id you want the token to have.
32
	 * @return \WP_Error
33
	 */
34 View Code Duplication
	public function get_sample_error( $error_code, $user_id ) {
35
36
		$signature_details = array(
37
			'token'     => 'dhj938djh938d:1:' . $user_id,
38
			'timestamp' => time(),
39
			'nonce'     => 'asd3d32d',
40
			'body_hash' => 'dsf34frf',
41
			'method'    => 'POST',
42
			'url'       => 'https://example.org',
43
			'signature' => 'sdf234fe',
44
		);
45
46
		return new \WP_Error(
47
			$error_code,
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with $error_code.

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
			'An error was triggered',
49
			compact( 'signature_details' )
50
		);
51
52
	}
53
54
	/**
55
	 * Test storing an error
56
	 */
57
	public function test_store_error() {
58
59
		add_filter( 'jetpack_connection_bypass_error_reporting_gate', '__return_true' );
60
61
		$error = $this->get_sample_error( 'invalid_token', 1 );
62
63
		$this->error_handler->report_error( $error );
64
65
		$stored_errors = $this->error_handler->get_stored_errors();
66
67
		$this->assertSame( 1, count( $stored_errors ) );
68
69
		$this->arrayHasKey( 'invalid_token', $stored_errors );
70
71
		$this->assertSame( 1, count( $stored_errors['invalid_token'] ) );
72
73
		$this->arrayHasKey( '1', $stored_errors['invalid_token'] );
74
75
		$this->arrayHasKey( 'nonce', $stored_errors['invalid_token']['1'] );
76
		$this->arrayHasKey( 'error_code', $stored_errors['invalid_token']['1'] );
77
		$this->arrayHasKey( 'user_id', $stored_errors['invalid_token']['1'] );
78
		$this->arrayHasKey( 'error_message', $stored_errors['invalid_token']['1'] );
79
		$this->arrayHasKey( 'error_data', $stored_errors['invalid_token']['1'] );
80
		$this->arrayHasKey( 'timestamp', $stored_errors['invalid_token']['1'] );
81
		$this->arrayHasKey( 'nonce', $stored_errors['invalid_token']['1'] );
82
83
	}
84
85
	/**
86
	 * Test storing errors
87
	 */
88
	public function test_store_multiple_error_codes() {
89
90
		add_filter( 'jetpack_connection_bypass_error_reporting_gate', '__return_true' );
91
92
		$error  = $this->get_sample_error( 'invalid_token', 1 );
93
		$error2 = $this->get_sample_error( 'unknown_user', 1 );
94
95
		$this->error_handler->report_error( $error );
96
		$this->error_handler->report_error( $error2 );
97
98
		$stored_errors = $this->error_handler->get_stored_errors();
99
100
		$this->assertEquals( 2, count( $stored_errors ) );
101
102
		$this->arrayHasKey( 'invalid_token', $stored_errors );
103
104
		$this->assertSame( 1, count( $stored_errors['invalid_token'] ) );
105
		$this->assertSame( 1, count( $stored_errors['unknown_user'] ) );
106
107
		$this->arrayHasKey( '1', $stored_errors['unknown_user'] );
108
109
		$this->arrayHasKey( 'nonce', $stored_errors['unknown_user']['1'] );
110
		$this->arrayHasKey( 'error_code', $stored_errors['unknown_user']['1'] );
111
		$this->arrayHasKey( 'user_id', $stored_errors['unknown_user']['1'] );
112
		$this->arrayHasKey( 'error_message', $stored_errors['unknown_user']['1'] );
113
		$this->arrayHasKey( 'error_data', $stored_errors['unknown_user']['1'] );
114
		$this->arrayHasKey( 'timestamp', $stored_errors['unknown_user']['1'] );
115
		$this->arrayHasKey( 'nonce', $stored_errors['unknown_user']['1'] );
116
117
	}
118
119
	/**
120
	 * Test storing errors
121
	 */
122
	public function test_store_multiple_error_codes_multiple_users() {
123
124
		add_filter( 'jetpack_connection_bypass_error_reporting_gate', '__return_true' );
125
126
		$error  = $this->get_sample_error( 'invalid_token', 1 );
127
		$error2 = $this->get_sample_error( 'unknown_user', 1 );
128
		$error3 = $this->get_sample_error( 'unknown_user', 2 );
129
130
		$this->error_handler->report_error( $error );
131
		$this->error_handler->report_error( $error2 );
132
		$this->error_handler->report_error( $error3 );
133
134
		$stored_errors = $this->error_handler->get_stored_errors();
135
136
		$this->assertEquals( 2, count( $stored_errors ) );
137
138
		$this->arrayHasKey( 'invalid_token', $stored_errors );
139
140
		$this->assertSame( 1, count( $stored_errors['invalid_token'] ) );
141
		$this->assertEquals( 2, count( $stored_errors['unknown_user'] ) );
142
143
		$this->arrayHasKey( '2', $stored_errors['unknown_user'] );
144
145
		$this->arrayHasKey( 'nonce', $stored_errors['unknown_user']['2'] );
146
		$this->arrayHasKey( 'error_code', $stored_errors['unknown_user']['2'] );
147
		$this->arrayHasKey( 'user_id', $stored_errors['unknown_user']['2'] );
148
		$this->arrayHasKey( 'error_message', $stored_errors['unknown_user']['2'] );
149
		$this->arrayHasKey( 'error_data', $stored_errors['unknown_user']['2'] );
150
		$this->arrayHasKey( 'timestamp', $stored_errors['unknown_user']['2'] );
151
		$this->arrayHasKey( 'nonce', $stored_errors['unknown_user']['2'] );
152
153
	}
154
155
	/**
156
	 * Test gate
157
	 */
158
	public function test_gate() {
159
160
		$error  = $this->get_sample_error( 'invalid_token', 1 );
161
		$error2 = $this->get_sample_error( 'invalid_token', 1 );
162
		$error3 = $this->get_sample_error( 'unknown_user', 1 );
163
164
		$this->assertTrue( $this->error_handler->should_report_error( $error ) );
165
		$this->assertFalse( $this->error_handler->should_report_error( $error2 ), 'second attempt to report the same error code should be stopped by the gate' );
166
		$this->assertTrue( $this->error_handler->should_report_error( $error3 ) );
167
168
	}
169
170
	/**
171
	 * Test 5 errors per code
172
	 */
173
	public function test_max_five_errors_per_code() {
174
175
		add_filter( 'jetpack_connection_bypass_error_reporting_gate', '__return_true' );
176
177
		$error  = $this->get_sample_error( 'unknown_user', 3 );
178
		$error2 = $this->get_sample_error( 'unknown_user', 4 );
179
		$error3 = $this->get_sample_error( 'unknown_user', 5 );
180
		$error4 = $this->get_sample_error( 'unknown_user', 6 );
181
		$error5 = $this->get_sample_error( 'unknown_user', 7 );
182
		$error6 = $this->get_sample_error( 'unknown_user', 8 );
183
184
		$this->error_handler->report_error( $error );
185
		$this->error_handler->report_error( $error2 );
186
		$this->error_handler->report_error( $error3 );
187
		$this->error_handler->report_error( $error4 );
188
		$this->error_handler->report_error( $error5 );
189
		$this->error_handler->report_error( $error6 );
190
191
		$stored_errors = $this->error_handler->get_stored_errors();
192
193
		$this->assertEquals( 5, count( $stored_errors['unknown_user'] ) );
194
195
		$this->assertArrayNotHasKey( '3', $stored_errors['unknown_user'], 'first inserted error must have been excluded' );
196
		$this->assertArrayHasKey( '8', $stored_errors['unknown_user'], 'sixth inserted error must be present' );
197
198
	}
199
200
	/**
201
	 * Data provider for test_get_user_id_from_token
202
	 *
203
	 * @return array
204
	 */
205
	public function get_user_id_from_token_data() {
206
		return array(
207
			array(
208
				'token'    => 'asdsaddasa:1:3',
209
				'expected' => 3,
210
			),
211
			array(
212
				'token'    => 'asdsaddasa:1:2',
213
				'expected' => 2,
214
			),
215
			array(
216
				'token'    => 'asdsaddasa:1',
217
				'expected' => 'invalid',
218
			),
219
			array(
220
				'token'    => 'asdsaddasa:1:',
221
				'expected' => 'invalid',
222
			),
223
			array(
224
				'token'    => 'asdsaddasa:1:asd',
225
				'expected' => 'invalid',
226
			),
227
			array(
228
				'token'    => 'asdsaddasa:1:333',
229
				'expected' => 333,
230
			),
231
		);
232
	}
233
234
	/**
235
	 * Test get_user_id_from_token
236
	 *
237
	 * @param string         $token token.
238
	 * @param string|integer $expected expected user_id.
239
	 *
240
	 * @dataProvider get_user_id_from_token_data
241
	 */
242
	public function test_get_user_id_from_token( $token, $expected ) {
243
		$this->assertEquals( $expected, $this->error_handler->get_user_id_from_token( $token ) );
244
	}
245
246
	/**
247
	 * Test get_error_by_nonce
248
	 */
249
	public function test_get_error_by_nonce() {
250
		$error  = $this->get_sample_error( 'unknown_user', 3 );
251
		$error2 = $this->get_sample_error( 'invalid_token', 4 );
252
		$error3 = $this->get_sample_error( 'no_user_tokens', 5 );
253
254
		$this->error_handler->report_error( $error );
255
		$this->error_handler->report_error( $error2 );
256
		$this->error_handler->report_error( $error3 );
257
258
		$stored_errors = $this->error_handler->get_stored_errors();
259
260
		$error = $this->error_handler->get_error_by_nonce( $stored_errors['no_user_tokens']['5']['nonce'] );
261
262
		$this->assertEquals( $error, $stored_errors['no_user_tokens']['5'] );
263
	}
264
265
	/**
266
	 * Test verify error
267
	 */
268
	public function test_verify_error() {
269
		$error = $this->get_sample_error( 'unknown_user', 3 );
270
		$this->error_handler->report_error( $error );
271
272
		$stored_errors = $this->error_handler->get_stored_errors();
273
274
		$this->error_handler->verify_error( $stored_errors['unknown_user']['3'] );
275
276
		$verified_errors = $this->error_handler->get_verified_errors();
277
278
		$this->assertEquals( $verified_errors['unknown_user']['3'], $stored_errors['unknown_user']['3'] );
279
	}
280
281
	/**
282
	 * Test encryption available.
283
	 */
284
	public function test_encryption() {
285
		$error = $this->get_sample_error( 'unknown_user', 3 );
286
		$this->error_handler->report_error( $error );
287
288
		$stored_errors = $this->error_handler->get_stored_errors();
289
290
		$encrypted = $this->error_handler->encrypt_data_to_wpcom( $stored_errors['unknown_user']['3'] );
291
292
		$this->assertIsString( $encrypted );
293
		$this->assertEquals( 472, strlen( $encrypted ) );
294
295
	}
296
297
	/**
298
	 * Test Garbage collector.
299
	 */
300
	public function test_garbage_collector() {
301
		$error  = $this->get_sample_error( 'unknown_user', 3 );
302
		$error2 = $this->get_sample_error( 'invalid_token', 4 );
303
		$error3 = $this->get_sample_error( 'no_user_tokens', 5 );
304
		$error4 = $this->get_sample_error( 'no_user_tokens', 6 );
305
306
		$this->error_handler->report_error( $error );
307
		$this->error_handler->report_error( $error2 );
308
		$this->error_handler->report_error( $error3 );
309
		$this->error_handler->report_error( $error4 );
310
311
		// Manipulate the timestamps directly in the database.
312
		$saved_options = get_option( Error_Handler::STORED_ERRORS_OPTION );
313
		$this->assertEquals( 3, count( $saved_options ) );
314
		$this->assertSame( 1, count( $saved_options['no_user_tokens'] ) );
315
		$saved_options['invalid_token'][4]['timestamp']  = time() - DAY_IN_SECONDS * 4;
316
		$saved_options['no_user_tokens'][6]['timestamp'] = time() - DAY_IN_SECONDS * 4;
317
		update_option( Error_Handler::STORED_ERRORS_OPTION, $saved_options );
318
319
		$errors = $this->error_handler->get_stored_errors();
320
321
		$this->assertEquals( 2, count( $errors ) );
322
323
		$this->assertArrayHasKey( 'unknown_user', $errors );
324
		$this->assertArrayHasKey( 'no_user_tokens', $errors );
325
		$this->assertArrayNotHasKey( 'invalid_token', $errors );
326
327
		$this->assertSame( 1, count( $errors['no_user_tokens'] ) );
328
329
	}
330
}
331