Completed
Push — fix/nonce-cleanup-locked ( 3c5ab0 )
by
unknown
26:07 queued 16:49
created

Test_Nonce_Handler::test_cleanup_locked()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 1
nop 0
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
/**
3
 * The nonce handler tests.
4
 *
5
 * @package automattic/jetpack-connection
6
 */
7
8
namespace Automattic\Jetpack\Connection;
9
10
use PHPUnit\Framework\TestCase;
11
12
/**
13
 * The nonce handler tests.
14
 */
15
class Test_Nonce_Handler extends TestCase {
16
17
	/**
18
	 * The nonce timestamp.
19
	 */
20
	const TIMESTAMP = '1598639691';
21
22
	/**
23
	 * The nonce.
24
	 */
25
	const NONCE = 'rAnDoM';
26
27
	/**
28
	 * Reset the environment after each test.
29
	 */
30
	public function tearDown() {
31
		parent::tearDown();
32
33
		Nonce_Handler::invalidate_request_nonces();
34
35
		remove_action( 'shutdown', array( Nonce_Handler::class, 'clean_runtime' ) );
36
	}
37
38
	/**
39
	 * Testing the nonce adding functionality.
40
	 */
41
	public function test_add() {
42
		// Confirm that the nonce gets added.
43
		self::assertTrue( Nonce_Handler::add( static::TIMESTAMP, static::NONCE ) );
44
45
		// Confirm that the nonce is loaded from cache and still valid during the request.
46
		self::assertTrue( Nonce_Handler::add( static::TIMESTAMP, static::NONCE ) );
47
	}
48
49
	/**
50
	 * Testing the shutdown cleanup hook.
51
	 */
52
	public function test_shutdown_cleanup() {
53
		global $wp_filter;
54
55
		// Using a custom function to avoid collisions with existing callbacks.
56
		$return_false = function() {
57
			return false;
58
		};
59
60
		add_filter( 'jetpack_connection_add_nonce_cleanup', $return_false );
61
		Nonce_Handler::add( static::TIMESTAMP, static::NONCE );
62
		$is_callback_missing = empty( $wp_filter['shutdown']->callbacks[10][ Nonce_Handler::class . '::clean_runtime' ] );
63
		remove_filter( 'jetpack_connection_add_nonce_cleanup', $return_false );
64
		Nonce_Handler::invalidate_request_nonces();
65
66
		Nonce_Handler::add( static::TIMESTAMP, static::NONCE );
67
		$is_callback_placed = ! empty( $wp_filter['shutdown']->callbacks[10][ Nonce_Handler::class . '::clean_runtime' ] );
68
69
		self::assertTrue( $is_callback_missing, 'Cleanup callback is in place, it should not exist' );
70
		self::assertTrue( $is_callback_placed, 'Cleanup callback is missing, it should have been added' );
71
	}
72
73
	/**
74
	 * Trying to add an existing nonce, and making sure it's considered invalid (returns false).
75
	 */
76
	public function test_add_existing() {
77
		$query_filter_run = false;
78
79
		$query_filter = function( $result, $query ) use ( &$query_filter_run ) {
80
			if ( ! $query_filter_run && false !== strpos( $query, 'jetpack_nonce_' ) ) {
81
				$query_filter_run = true;
82
				$nonce_name       = 'jetpack_nonce_' . static::TIMESTAMP . '_' . static::NONCE;
83
				$this->assertEquals( "SELECT 1 FROM `options` WHERE option_name = '{$nonce_name}'", $query );
84
85
				return array( (object) array( 1 => '1' ) );
86
			}
87
88
			return $result;
89
		};
90
91
		add_filter( 'wordbless_wpdb_query_results', $query_filter, 10, 2 );
92
93
		$result = Nonce_Handler::add( static::TIMESTAMP, static::NONCE );
94
95
		remove_filter( 'wordbless_wpdb_query_results', $query_filter );
96
97
		self::assertFalse( $result );
98
		self::assertTrue( $query_filter_run, "The SQL query assertions haven't run." );
99
	}
100
101
	/**
102
	 * Testing the runtime nonce cleanup functionality.
103
	 */
104
	public function test_delete() {
105
		$nonce_ids        = array( 1111, 2222 );
106
		$limit            = 42;
107
		$cutoff_timestamp = static::TIMESTAMP;
108
109
		$query_filter_select_run = false;
110
		$query_filter_delete_run = false;
111
112
		$query_filter_select = function( $result, $query ) use ( &$query_filter_select_run, $nonce_ids, $limit, $cutoff_timestamp ) {
113
			if ( ! $query_filter_select_run && 0 === strpos( $query, 'SELECT ' ) && false !== strpos( $query, 'jetpack_nonce_' ) ) {
114
				global $wpdb;
115
116
				$query_filter_select_run = true;
117
				self::assertEquals( "SELECT option_id FROM `{$wpdb->options}` WHERE `option_name` >= 'jetpack_nonce_' AND `option_name` < 'jetpack_nonce_{$cutoff_timestamp}' LIMIT {$limit}", $query );
118
119
				return array( (object) array( 'option_id' => $nonce_ids[0] ), (object) array( 'option_id' => $nonce_ids[1] ) );
120
			}
121
122
			return $result;
123
		};
124
125
		$query_filter_delete = function( $result, $query ) use ( &$query_filter_delete_run, $nonce_ids ) {
126
			if ( ! $query_filter_delete_run && 0 === strpos( $query, 'DELETE ' ) && false !== strpos( $query, 'option_id' ) ) {
127
				global $wpdb;
128
129
				$query_filter_delete_run = true;
130
				self::assertEquals( "DELETE FROM `{$wpdb->options}` WHERE `option_id` IN ( " . implode( ', ', $nonce_ids ) . ' )', $query );
131
			}
132
133
			return $result;
134
		};
135
136
		add_filter( 'wordbless_wpdb_query_results', $query_filter_select, 10, 2 );
137
		add_filter( 'wordbless_wpdb_query_results', $query_filter_delete, 10, 2 );
138
139
		Nonce_Handler::delete( $limit, $cutoff_timestamp );
140
141
		remove_filter( 'wordbless_wpdb_query_results', $query_filter_select );
142
		remove_filter( 'wordbless_wpdb_query_results', $query_filter_delete );
143
144
		self::assertTrue( $query_filter_select_run, "The SQL query assertions haven't run." );
145
		self::assertTrue( $query_filter_delete_run, "The SQL query assertions haven't run." );
146
	}
147
148
}
149