Skip to content

Commit ac4c623

Browse files
committed
test: Assert application password extras functionality
1 parent 962cb89 commit ac4c623

File tree

2 files changed

+369
-0
lines changed

2 files changed

+369
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<?php
2+
/**
3+
* Tests for Jetpack_Application_Password_Extras class
4+
*
5+
* @package automattic/jetpack
6+
*/
7+
8+
use PHPUnit\Framework\Attributes\CoversClass;
9+
10+
require_once JETPACK__PLUGIN_DIR . '/tests/php/lib/Jetpack_REST_TestCase.php';
11+
require_once JETPACK__PLUGIN_DIR . '/_inc/lib/class-jetpack-application-password-extras.php';
12+
13+
/**
14+
* Class Jetpack_Application_Password_Extras_Test
15+
*
16+
* @covers \Jetpack_Application_Password_Extras
17+
*/
18+
#[CoversClass( Jetpack_Application_Password_Extras::class )]
19+
class Jetpack_Application_Password_Extras_Test extends Jetpack_REST_TestCase {
20+
21+
/**
22+
* Mock user ID.
23+
*
24+
* @var int
25+
*/
26+
private static $user_id = 0;
27+
28+
/**
29+
* Create shared database fixtures.
30+
*
31+
* @param WP_UnitTest_Factory $factory Fixture factory.
32+
*/
33+
public static function wpSetUpBeforeClass( $factory ) {
34+
static::$user_id = $factory->user->create( array( 'role' => 'administrator' ) );
35+
}
36+
37+
/**
38+
* Setup the environment for a test.
39+
*/
40+
public function set_up() {
41+
parent::set_up();
42+
wp_set_current_user( static::$user_id );
43+
}
44+
45+
/**
46+
* Tear down the environment after a test.
47+
*/
48+
public function tear_down() {
49+
parent::tear_down();
50+
unset( $_GET['p'] );
51+
unset( $_GET['page_id'] );
52+
unset( $GLOBALS['wp_current_filter'] );
53+
}
54+
55+
/**
56+
* Test that init method registers the hook correctly.
57+
*/
58+
public function test_init_registers_hook() {
59+
remove_all_filters( 'application_password_is_api_request' );
60+
Jetpack_Application_Password_Extras::init();
61+
62+
$this->assertNotFalse(
63+
has_filter( 'application_password_is_api_request', array( 'Jetpack_Application_Password_Extras', 'application_password_extras' ) ),
64+
'Hook should be registered'
65+
);
66+
}
67+
68+
/**
69+
* Test that non-matching requests preserve original false value.
70+
*/
71+
public function test_non_matching_request_preserves_original_false_value() {
72+
set_current_screen( 'dashboard' );
73+
74+
$result = Jetpack_Application_Password_Extras::application_password_extras( false );
75+
$this->assertFalse( $result, 'Should preserve false when not in matching context' );
76+
}
77+
78+
/**
79+
* Test that non-matching requests preserve original true value.
80+
*/
81+
public function test_non_matching_request_preserves_original_true_value() {
82+
set_current_screen( 'dashboard' );
83+
84+
$result = Jetpack_Application_Password_Extras::application_password_extras( true );
85+
$this->assertTrue( $result, 'Should preserve true when not in matching context' );
86+
}
87+
88+
/**
89+
* Test that admin-ajax requests are allowed.
90+
*/
91+
public function test_admin_ajax_request_allowed() {
92+
set_current_screen( 'dashboard' );
93+
add_filter( 'wp_doing_ajax', '__return_true' );
94+
95+
$result = Jetpack_Application_Password_Extras::application_password_extras( false );
96+
97+
remove_filter( 'wp_doing_ajax', '__return_true' );
98+
99+
$this->assertTrue( $result, 'Result should be true' );
100+
}
101+
102+
/**
103+
* Test that post preview requests are allowed.
104+
*/
105+
public function test_post_preview_request_allowed() {
106+
$_GET['p'] = '123';
107+
108+
$result = Jetpack_Application_Password_Extras::application_password_extras( false );
109+
110+
$this->assertTrue( $result, 'Post preview requests should be allowed' );
111+
}
112+
113+
/**
114+
* Test that page preview requests are allowed.
115+
*/
116+
public function test_page_preview_request_allowed() {
117+
$_GET['page_id'] = '456';
118+
119+
$result = Jetpack_Application_Password_Extras::application_password_extras( false );
120+
121+
$this->assertTrue( $result, 'Page preview requests should be allowed' );
122+
}
123+
124+
/**
125+
* Test multiple conditions at once.
126+
*/
127+
public function test_multiple_conditions_prioritize_first_match() {
128+
set_current_screen( 'dashboard' );
129+
add_filter( 'wp_doing_ajax', '__return_true' );
130+
$_GET['p'] = '123';
131+
132+
$result = Jetpack_Application_Password_Extras::application_password_extras( false );
133+
134+
remove_filter( 'wp_doing_ajax', '__return_true' );
135+
136+
$this->assertTrue( $result, 'Should return true when any condition matches' );
137+
}
138+
139+
/**
140+
* Test that get_abilities returns all expected abilities.
141+
*/
142+
public function test_get_abilities_complete() {
143+
$abilities = Jetpack_Application_Password_Extras::get_abilities();
144+
145+
$expected_abilities = array(
146+
'admin-ajax' => true,
147+
'post-previews' => true,
148+
);
149+
150+
$this->assertEquals( $expected_abilities, $abilities, 'get_abilities should return all expected abilities' );
151+
}
152+
}
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
<?php
2+
/**
3+
* Tests for /wpcom/v2/application-password-extras endpoints.
4+
*
5+
* @package automattic/jetpack
6+
*/
7+
8+
use PHPUnit\Framework\Attributes\CoversClass;
9+
use PHPUnit\Framework\Attributes\DataProvider;
10+
use WpOrg\Requests\Requests;
11+
12+
require_once dirname( __DIR__, 2 ) . '/lib/Jetpack_REST_TestCase.php';
13+
require_once JETPACK__PLUGIN_DIR . '/_inc/lib/class-jetpack-application-password-extras.php';
14+
15+
/**
16+
* Class WPCOM_REST_API_V2_Endpoint_Application_Password_Extras_Test
17+
*
18+
* @covers \WPCOM_REST_API_V2_Endpoint_Application_Password_Extras
19+
*/
20+
#[CoversClass( WPCOM_REST_API_V2_Endpoint_Application_Password_Extras::class )]
21+
class WPCOM_REST_API_V2_Endpoint_Application_Password_Extras_Test extends Jetpack_REST_TestCase {
22+
23+
/**
24+
* Mock user ID.
25+
*
26+
* @var int
27+
*/
28+
private static $user_id = 0;
29+
30+
/**
31+
* Mock editor user ID.
32+
*
33+
* @var int
34+
*/
35+
private static $editor_id = 0;
36+
37+
/**
38+
* Create shared database fixtures.
39+
*
40+
* @param WP_UnitTest_Factory $factory Fixture factory.
41+
*/
42+
public static function wpSetUpBeforeClass( $factory ) {
43+
static::$user_id = $factory->user->create( array( 'role' => 'administrator' ) );
44+
static::$editor_id = $factory->user->create( array( 'role' => 'editor' ) );
45+
}
46+
47+
/**
48+
* Setup the environment for a test.
49+
*/
50+
public function set_up() {
51+
parent::set_up();
52+
53+
// Initialize the class to ensure it's available
54+
Jetpack_Application_Password_Extras::init();
55+
56+
wp_set_current_user( static::$user_id );
57+
}
58+
59+
/**
60+
* Test that routes are registered correctly.
61+
*/
62+
public function test_routes_registered() {
63+
$routes = rest_get_server()->get_routes();
64+
65+
$this->assertArrayHasKey( '/wpcom/v2/application-password-extras/abilities', $routes );
66+
$this->assertArrayHasKey( '/wpcom/v2/application-password-extras/admin-ajax', $routes );
67+
$this->assertArrayHasKey( '/wpcom/v2/application-password-extras/post-previews', $routes );
68+
}
69+
70+
/**
71+
* Test permission check for unauthenticated users.
72+
*/
73+
public function test_unauthenticated_user_cannot_access_abilities() {
74+
wp_set_current_user( 0 );
75+
76+
$request = new WP_REST_Request( Requests::GET, '/wpcom/v2/application-password-extras/abilities' );
77+
$response = $this->server->dispatch( $request );
78+
79+
$this->assertErrorResponse( 'rest_forbidden', $response, 401 );
80+
$data = $response->get_data();
81+
$this->assertEquals( 'Sorry, you must be logged in to access this endpoint.', $data['message'] );
82+
}
83+
84+
/**
85+
* Test permission check for authenticated users.
86+
*/
87+
public function test_authenticated_user_can_access_abilities() {
88+
wp_set_current_user( static::$user_id );
89+
90+
$request = new WP_REST_Request( Requests::GET, '/wpcom/v2/application-password-extras/abilities' );
91+
$response = $this->server->dispatch( $request );
92+
93+
$this->assertEquals( 200, $response->get_status() );
94+
}
95+
96+
/**
97+
* Test that get_abilities endpoint returns correct data.
98+
*/
99+
public function test_get_abilities_endpoint_returns_correct_data() {
100+
wp_set_current_user( static::$user_id );
101+
102+
$request = new WP_REST_Request( Requests::GET, '/wpcom/v2/application-password-extras/abilities' );
103+
$response = $this->server->dispatch( $request );
104+
$data = $response->get_data();
105+
106+
$this->assertEquals( 200, $response->get_status() );
107+
$this->assertIsArray( $data );
108+
$this->assertArrayHasKey( 'admin-ajax', $data );
109+
$this->assertArrayHasKey( 'post-previews', $data );
110+
$this->assertTrue( $data['admin-ajax'] );
111+
$this->assertTrue( $data['post-previews'] );
112+
}
113+
114+
/**
115+
* Data provider for endpoint tests
116+
*
117+
* @return array
118+
*/
119+
public static function endpoint_provider() {
120+
return array(
121+
'abilities endpoint' => array( '/wpcom/v2/application-password-extras/abilities' ),
122+
'admin-ajax endpoint' => array( '/wpcom/v2/application-password-extras/admin-ajax' ),
123+
'post-previews endpoint' => array( '/wpcom/v2/application-password-extras/post-previews' ),
124+
);
125+
}
126+
127+
/**
128+
* Test that all endpoints work correctly for authenticated users.
129+
*
130+
* @dataProvider endpoint_provider
131+
* @param string $endpoint The endpoint to test.
132+
*/
133+
#[DataProvider( 'endpoint_provider' )]
134+
public function test_endpoints_work_for_authenticated_users( $endpoint ) {
135+
wp_set_current_user( static::$user_id );
136+
137+
$request = new WP_REST_Request( Requests::GET, $endpoint );
138+
$response = $this->server->dispatch( $request );
139+
$data = $response->get_data();
140+
141+
$this->assertEquals( 200, $response->get_status() );
142+
$this->assertIsArray( $data );
143+
$this->assertArrayHasKey( 'admin-ajax', $data );
144+
$this->assertArrayHasKey( 'post-previews', $data );
145+
}
146+
147+
/**
148+
* Test that all endpoints require authentication.
149+
*
150+
* @dataProvider endpoint_provider
151+
* @param string $endpoint The endpoint to test.
152+
*/
153+
#[DataProvider( 'endpoint_provider' )]
154+
public function test_endpoints_require_authentication( $endpoint ) {
155+
wp_set_current_user( 0 );
156+
157+
$request = new WP_REST_Request( Requests::GET, $endpoint );
158+
$response = $this->server->dispatch( $request );
159+
160+
$this->assertErrorResponse( 'rest_forbidden', $response, 401 );
161+
}
162+
163+
/**
164+
* Test that editor users can access abilities.
165+
*/
166+
public function test_editor_can_access_abilities() {
167+
wp_set_current_user( static::$editor_id );
168+
169+
$request = new WP_REST_Request( Requests::GET, '/wpcom/v2/application-password-extras/abilities' );
170+
$response = $this->server->dispatch( $request );
171+
172+
$this->assertEquals( 200, $response->get_status() );
173+
$data = $response->get_data();
174+
$this->assertIsArray( $data );
175+
}
176+
177+
/**
178+
* Test that only GET requests are allowed.
179+
*/
180+
public function test_only_get_requests_allowed() {
181+
wp_set_current_user( static::$user_id );
182+
183+
$disallowed_methods = array(
184+
Requests::POST,
185+
Requests::PUT,
186+
Requests::DELETE,
187+
Requests::PATCH,
188+
);
189+
190+
foreach ( $disallowed_methods as $method ) {
191+
$request = new WP_REST_Request( $method, '/wpcom/v2/application-password-extras/abilities' );
192+
$response = $this->server->dispatch( $request );
193+
194+
// Routes that don't support a method typically return 404 (not found) in WordPress REST API
195+
$this->assertContains(
196+
$response->get_status(),
197+
array( 404, 405 ),
198+
"Method $method should not be allowed (status should be 404 or 405)"
199+
);
200+
}
201+
}
202+
203+
/**
204+
* Test response headers are set correctly.
205+
*/
206+
public function test_response_headers() {
207+
wp_set_current_user( static::$user_id );
208+
209+
$request = new WP_REST_Request( Requests::GET, '/wpcom/v2/application-password-extras/abilities' );
210+
$response = $this->server->dispatch( $request );
211+
212+
$headers = $response->get_headers();
213+
214+
// Standard REST API headers should be present
215+
$this->assertIsArray( $headers );
216+
}
217+
}

0 commit comments

Comments
 (0)