From fe6d58b014a3f941888309e64f205965e2ff771a Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 24 Feb 2016 10:03:45 -0500 Subject: [PATCH 1/4] Added Comment Meta Endpoints --- ...class-wp-rest-meta-comments-controller.php | 100 +++ lib/class-wp-rest-meta-controller.php | 13 +- plugin.php | 8 + tests/test-rest-meta-comments-controller.php | 787 ++++++++++++++++++ 4 files changed, 907 insertions(+), 1 deletion(-) create mode 100644 lib/class-wp-rest-meta-comments-controller.php create mode 100644 tests/test-rest-meta-comments-controller.php diff --git a/lib/class-wp-rest-meta-comments-controller.php b/lib/class-wp-rest-meta-comments-controller.php new file mode 100644 index 0000000..8067d6d --- /dev/null +++ b/lib/class-wp-rest-meta-comments-controller.php @@ -0,0 +1,100 @@ +parent_controller = new WP_REST_Comments_Controller(); + $this->namespace = 'wp/v2'; + $this->rest_base = 'meta'; + } + + /** + * Check if a given request has access to get meta for a comment. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $comment_id = (int) $request['parent_id']; + $comment = get_comment( $comment_id ); + + if ( empty( $comment ) || empty( $comment->comment_ID ) ) { + return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment id.' ), array( 'status' => 404 ) ); + } + + if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) { + return new WP_Error( 'rest_forbidden', __( 'Sorry, you cannot view the meta for this comment.' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to get a specific meta entry for a comment. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + return $this->get_items_permissions_check( $request ); + } + + /** + * Check if a given request has access to create a meta entry for a comment. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + return $this->get_items_permissions_check( $request ); + } + + /** + * Check if a given request has access to update a meta entry for a comment. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + return $this->get_items_permissions_check( $request ); + } + + /** + * Check if a given request has access to delete meta for a comment. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $comment_id = (int) $request['parent_id']; + $comment = get_comment( $comment_id ); + + if ( empty( $comment ) || empty( $comment->comment_ID ) ) { + return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment id.' ), array( 'status' => 404 ) ); + } + + if ( ! current_user_can( 'moderate_comments', $comment->comment_ID ) ) { + return new WP_Error( 'rest_forbidden', __( 'Sorry, you cannot delete the meta for this comment.' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } +} diff --git a/lib/class-wp-rest-meta-controller.php b/lib/class-wp-rest-meta-controller.php index 52a8b63..cff7fa7 100644 --- a/lib/class-wp-rest-meta-controller.php +++ b/lib/class-wp-rest-meta-controller.php @@ -149,7 +149,18 @@ protected function get_id_column() { * @return string */ protected function get_parent_column() { - return ( 'user' === $this->parent_type ) ? 'user_id' : 'post_id'; + $parent_column = 'post_id'; + + switch ( $this->parent_type ) { + case 'user': + return 'user_id'; + case 'comment': + return 'comment_id'; + default: + return $parent_column; + } + + return $parent_column; } /** diff --git a/plugin.php b/plugin.php index b030038..704b5ff 100644 --- a/plugin.php +++ b/plugin.php @@ -21,12 +21,20 @@ function meta_rest_api_init() { require_once dirname( __FILE__ ) . '/lib/class-wp-rest-meta-posts-controller.php'; } + if ( class_exists( 'WP_REST_Controller' ) + && ! class_exists( 'WP_REST_Meta_Comments_Controller' ) ) { + require_once dirname( __FILE__ ) . '/lib/class-wp-rest-meta-comments-controller.php'; + } + foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) { if ( post_type_supports( $post_type->name, 'custom-fields' ) ) { $meta_controller = new WP_REST_Meta_Posts_Controller( $post_type->name ); $meta_controller->register_routes(); } } + + $comment_meta_controller = new WP_REST_Meta_Comments_Controller(); + $comment_meta_controller->register_routes(); } add_action( 'rest_api_init', 'meta_rest_api_init', 11 ); diff --git a/tests/test-rest-meta-comments-controller.php b/tests/test-rest-meta-comments-controller.php new file mode 100644 index 0000000..840fe2c --- /dev/null +++ b/tests/test-rest-meta-comments-controller.php @@ -0,0 +1,787 @@ +admin_id = $this->factory->user->create( array( + 'role' => 'administrator', + )); + $this->subscriber_id = $this->factory->user->create( array( + 'role' => 'subscriber', + )); + $this->author_id = $this->factory->user->create( array( + 'role' => 'author', + )); + $this->post_id = $this->factory->post->create(); + $this->approved_id = $this->factory->comment->create( array( + 'comment_approved' => 1, + 'comment_post_ID' => $this->post_id, + 'user_id' => 0, + )); + $this->hold_id = $this->factory->comment->create( array( + 'comment_approved' => 0, + 'comment_post_ID' => $this->post_id, + 'user_id' => $this->subscriber_id, + )); + } + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wp/v2/comments/(?P[\d]+)/meta', $routes ); + $this->assertCount( 2, $routes['/wp/v2/comments/(?P[\d]+)/meta'] ); + $this->assertArrayHasKey( '/wp/v2/comments/(?P[\d]+)/meta/(?P[\d]+)', $routes ); + $this->assertCount( 3, $routes['/wp/v2/comments/(?P[\d]+)/meta/(?P[\d]+)'] ); + } + public function test_context_param() { + // Collection + $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/comments/' . $this->approved_id . '/meta' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'edit', $data['endpoints'][0]['args']['context']['default'] ); + $this->assertEquals( array( 'edit' ), $data['endpoints'][0]['args']['context']['enum'] ); + // Single + $meta_id_basic = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/comments/' . $this->approved_id . '/meta/' . $meta_id_basic ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'edit', $data['endpoints'][0]['args']['context']['default'] ); + $this->assertEquals( array( 'edit' ), $data['endpoints'][0]['args']['context']['enum'] ); + } + public function test_get_item() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $data = $response->get_data(); + $this->assertEquals( $meta_id, $data['id'] ); + $this->assertEquals( 'testkey', $data['key'] ); + $this->assertEquals( 'testvalue', $data['value'] ); + } + public function test_get_items() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $meta_id_basic = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $meta_id_other1 = add_comment_meta( $this->approved_id, 'testotherkey', 'testvalue1' ); + $meta_id_other2 = add_comment_meta( $this->approved_id, 'testotherkey', 'testvalue2' ); + $value = array( 'testvalue1', 'testvalue2' ); + // serialized + add_comment_meta( $this->approved_id, 'testkey', $value ); + $value = (object) array( 'testvalue' => 'test' ); + // serialized object + add_comment_meta( $this->approved_id, 'testkey', $value ); + $value = serialize( array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ) ); + // serialized string + add_comment_meta( $this->approved_id, 'testkey', $value ); + // protected + add_comment_meta( $this->approved_id, '_testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $data = $response->get_data(); + foreach ( $data as $row ) { + $row = (array) $row; + $this->assertArrayHasKey( 'id', $row ); + $this->assertArrayHasKey( 'key', $row ); + $this->assertArrayHasKey( 'value', $row ); + if ( $row['id'] === $meta_id_basic ) { + $this->assertEquals( 'testkey', $row['key'] ); + $this->assertEquals( 'testvalue', $row['value'] ); + } + if ( $row['id'] === $meta_id_other1 ) { + $this->assertEquals( 'testotherkey', $row['key'] ); + $this->assertEquals( 'testvalue1', $row['value'] ); + } + if ( $row['id'] === $meta_id_other2 ) { + $this->assertEquals( 'testotherkey', $row['key'] ); + $this->assertEquals( 'testvalue2', $row['value'] ); + } + } + } + public function test_get_item_no_comment_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['parent_id'] = 0; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response, 404 ); + } + public function test_get_item_invalid_comment_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['parent_id'] = -1; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response, 404 ); + } + public function test_get_item_no_meta_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', 0, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response, 404 ); + } + public function test_get_item_invalid_meta_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['id'] = 'a'; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_id', $response, 404 ); + } + public function test_get_item_protected() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, '_testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + } + public function test_get_item_serialized_array() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', array( 'testvalue' => 'test' ) ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + } + public function test_get_item_serialized_object() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', (object) array( 'testvalue' => 'test' ) ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + } + public function test_get_item_unauthenticated() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); + } + public function test_get_item_wrong_comment() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $meta_id_two = add_comment_meta( $this->hold_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->hold_id, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_comment_mismatch', $response, 400 ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id_two ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_comment_mismatch', $response, 400 ); + } + public function test_get_items_no_comment_id() { + wp_set_current_user( $this->admin_id ); + add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request['parent_id'] = 0; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response ); + } + public function test_get_items_invalid_comment_id() { + wp_set_current_user( $this->admin_id ); + add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request['parent_id'] = -1; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response ); + } + public function test_get_items_unauthenticated() { + wp_set_current_user( $this->admin_id ); + add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_forbidden', $response ); + } + public function test_create_item() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => 'testvalue', + ) ); + $response = $this->server->dispatch( $request ); + $meta = get_comment_meta( $this->approved_id, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( 'testvalue', $meta[0] ); + $data = $response->get_data(); + $this->assertArrayHasKey( 'id', $data ); + $this->assertEquals( 'testkey', $data['key'] ); + $this->assertEquals( 'testvalue', $data['value'] ); + } + public function test_create_item_no_comment_id() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => 'testvalue', + ) ); + $request['parent_id'] = 0; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response, 404 ); + } + public function test_create_item_invalid_comment_id() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => 'testvalue', + ) ); + $request['parent_id'] = -1; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response, 404 ); + } + public function test_create_item_no_value() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertArrayHasKey( 'id', $data ); + $this->assertEquals( 'testkey', $data['key'] ); + $this->assertEquals( '', $data['value'] ); + } + public function test_create_item_no_key() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'value' => 'testvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_missing_callback_param', $response, 400 ); + } + public function test_create_item_empty_string_key() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => '', + 'value' => 'testvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_key', $response, 400 ); + } + public function test_create_item_invalid_key() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => false, + 'value' => 'testvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_key', $response, 400 ); + } + public function test_create_item_unauthenticated() { + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => 'testvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); + $this->assertEmpty( get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_create_item_serialized_array() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => array( 'testvalue1', 'testvalue2' ), + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); + $this->assertEmpty( get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_create_item_serialized_object() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => (object) array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ), + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); + $this->assertEmpty( get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_create_item_serialized_string() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => serialize( array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ) ), + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEmpty( get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_create_item_failed_get() { + $this->markTestSkipped(); + $this->endpoint = $this->getMock( 'WP_REST_Meta_Comments', array( 'get_meta' ), array( $this->fake_server ) ); + $test_error = new WP_Error( 'rest_test_error', 'Test error' ); + $this->endpoint->expects( $this->any() )->method( 'get_meta' )->will( $this->returnValue( $test_error ) ); + wp_set_current_user( $this->admin_id ); + $response = $this->endpoint->add_meta( $this->approved_id, array( + 'key' => 'testkey', + 'value' => 'testvalue', + ) ); + $this->assertErrorResponse( 'rest_test_error', $response ); + } + public function test_create_item_protected() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => '_testkey', + 'value' => 'testvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + $this->assertEmpty( get_comment_meta( $this->approved_id, '_testkey' ) ); + } + /** + * Ensure slashes aren't added + */ + public function test_create_item_unslashed() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => "test unslashed ' value", + ) ); + $this->server->dispatch( $request ); + $meta = get_comment_meta( $this->approved_id, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( "test unslashed ' value", $meta[0] ); + } + /** + * Ensure slashes aren't touched in data + */ + public function test_create_item_slashed() { + wp_set_current_user( $this->admin_id ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => "test slashed \\' value", + ) ); + $this->server->dispatch( $request ); + $meta = get_comment_meta( $this->approved_id, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( "test slashed \\' value", $meta[0] ); + } + public function test_update_item() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $data = $response->get_data(); + $this->assertEquals( $meta_id, $data['id'] ); + $this->assertEquals( 'testkey', $data['key'] ); + $this->assertEquals( 'testnewvalue', $data['value'] ); + $meta = get_comment_meta( $this->approved_id, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( 'testnewvalue', $meta[0] ); + } + public function test_update_meta_key() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'key' => 'testnewkey', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $data = $response->get_data(); + $this->assertEquals( $meta_id, $data['id'] ); + $this->assertEquals( 'testnewkey', $data['key'] ); + $this->assertEquals( 'testvalue', $data['value'] ); + $meta = get_comment_meta( $this->approved_id, 'testnewkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( 'testvalue', $meta[0] ); + // Ensure it was actually renamed, not created + $meta = get_comment_meta( $this->approved_id, 'testkey', false ); + $this->assertEmpty( $meta ); + } + public function test_update_meta_key_and_value() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $data = $response->get_data(); + $this->assertEquals( $meta_id, $data['id'] ); + $this->assertEquals( 'testnewkey', $data['key'] ); + $this->assertEquals( 'testnewvalue', $data['value'] ); + $meta = get_comment_meta( $this->approved_id, 'testnewkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( 'testnewvalue', $meta[0] ); + // Ensure it was actually renamed, not created + $meta = get_comment_meta( $this->approved_id, 'testkey', false ); + $this->assertEmpty( $meta ); + } + public function test_update_meta_empty() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array() ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_data_invalid', $response, 400 ); + } + public function test_update_meta_no_comment_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', 0, $meta_id ) ); + $request->set_body_params( array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response, 404 ); + } + public function test_update_meta_invalid_comment_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER, $meta_id ) ); + $request->set_body_params( array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response, 404 ); + } + public function test_update_meta_no_meta_id() { + wp_set_current_user( $this->admin_id ); + add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, 0 ) ); + $request->set_body_params( array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_id', $response, 404 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_update_meta_invalid_meta_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['id'] = 'a'; + $request->set_body_params( array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_id', $response, 404 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_update_meta_unauthenticated() { + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_update_meta_wrong_comment() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $meta_id_two = add_comment_meta( $this->hold_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->hold_id, $meta_id ) ); + $request->set_body_params( array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_comment_mismatch', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->hold_id, 'testkey' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id_two ) ); + $request->set_body_params( array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_comment_mismatch', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_update_meta_serialized_array() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'value' => array( 'testvalue1', 'testvalue2' ), + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_update_meta_serialized_object() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'value' => (object) array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ), + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_update_meta_serialized_string() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'value' => serialize( array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ) ), + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_update_meta_existing_serialized() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', array( 'testvalue1', 'testvalue2' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEquals( array( array( 'testvalue1', 'testvalue2' ) ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_update_meta_protected() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, '_testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, '_testkey' ) ); + } + public function test_update_meta_protected_new() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'key' => '_testnewkey', + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey' ) ); + $this->assertEmpty( get_comment_meta( $this->approved_id, '_testnewkey' ) ); + } + public function test_update_meta_invalid_key() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'key' => false, + 'value' => 'testnewvalue', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_key', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + /** + * Ensure slashes aren't added + */ + public function test_update_meta_unslashed() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => "test unslashed ' value", + ) ); + $this->server->dispatch( $request ); + $meta = get_comment_meta( $this->approved_id, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( "test unslashed ' value", $meta[0] ); + } + /** + * Ensure slashes aren't touched in data + */ + public function test_update_meta_slashed() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => "test slashed \\' value", + ) ); + $this->server->dispatch( $request ); + $meta = get_comment_meta( $this->approved_id, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( "test slashed \\' value", $meta[0] ); + } + public function test_delete_item() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['force'] = true; + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $data = $response->get_data(); + $this->assertArrayHasKey( 'message', $data ); + $this->assertNotEmpty( $data['message'] ); + $meta = get_comment_meta( $this->approved_id, 'testkey', false ); + $this->assertEmpty( $meta ); + } + public function test_delete_item_no_trash() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_trash_not_supported', $response, 501 ); + // Ensure the meta still exists + $meta = get_metadata_by_mid( 'comment', $meta_id ); + $this->assertNotEmpty( $meta ); + } + public function test_delete_item_no_comment_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['force'] = true; + $request['parent_id'] = 0; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response, 404 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey', false ) ); + } + public function test_delete_item_invalid_comment_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['force'] = true; + $request['parent_id'] = -1; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_comment_invalid_id', $response, 404 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey', false ) ); + } + public function test_delete_item_no_meta_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['force'] = true; + $request['id'] = 0; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_id', $response, 404 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey', false ) ); + } + public function test_delete_item_invalid_meta_id() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['force'] = true; + $request['id'] = -1; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_id', $response, 404 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey', false ) ); + } + public function test_delete_item_unauthenticated() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + wp_set_current_user( 0 ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['force'] = true; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey', false ) ); + } + public function test_delete_item_wrong_comment() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $meta_id_two = add_comment_meta( $this->hold_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->hold_id, $meta_id ) ); + $request['force'] = true; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_comment_mismatch', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->hold_id, 'testkey' ) ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id_two ) ); + $request['force'] = true; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_comment_mismatch', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_delete_item_serialized_array() { + wp_set_current_user( $this->admin_id ); + $value = array( 'testvalue1', 'testvalue2' ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', $value ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['force'] = true; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEquals( array( $value ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_delete_item_serialized_object() { + wp_set_current_user( $this->admin_id ); + $value = (object) array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', $value ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['force'] = true; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEquals( array( $value ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_delete_item_serialized_string() { + wp_set_current_user( $this->admin_id ); + $value = serialize( array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ) ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', $value ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['force'] = true; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEquals( array( $value ), get_comment_meta( $this->approved_id, 'testkey' ) ); + } + public function test_delete_item_protected() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, '_testkey', 'testvalue' ); + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $request['force'] = true; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, '_testkey' ) ); + } + public function test_prepare_item() { + wp_set_current_user( $this->admin_id ); + $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( $meta_id, $data['id'] ); + $this->assertEquals( 'testkey', $data['key'] ); + $this->assertEquals( 'testvalue', $data['value'] ); + } + public function test_get_item_schema() { + // No op + } +} From e4c16be8f077172bcb2e4d3dd11c27dafcd1a5a3 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 25 Feb 2016 16:11:59 -0500 Subject: [PATCH 2/4] Fixed Permissions Check and Unit Tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * REMOVED: ‘moderate_comments’ does not accept a second parameter * REMOVED: wp_set_current_user($this->admin_id); not needed for some unit tests --- lib/class-wp-rest-meta-comments-controller.php | 2 +- tests/test-rest-meta-comments-controller.php | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/class-wp-rest-meta-comments-controller.php b/lib/class-wp-rest-meta-comments-controller.php index 8067d6d..712104e 100644 --- a/lib/class-wp-rest-meta-comments-controller.php +++ b/lib/class-wp-rest-meta-comments-controller.php @@ -92,7 +92,7 @@ public function delete_item_permissions_check( $request ) { return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment id.' ), array( 'status' => 404 ) ); } - if ( ! current_user_can( 'moderate_comments', $comment->comment_ID ) ) { + if ( ! current_user_can( 'moderate_comments' ) ) { return new WP_Error( 'rest_forbidden', __( 'Sorry, you cannot delete the meta for this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } return true; diff --git a/tests/test-rest-meta-comments-controller.php b/tests/test-rest-meta-comments-controller.php index 840fe2c..14ca26f 100644 --- a/tests/test-rest-meta-comments-controller.php +++ b/tests/test-rest-meta-comments-controller.php @@ -160,7 +160,6 @@ public function test_get_item_serialized_object() { $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); } public function test_get_item_unauthenticated() { - wp_set_current_user( $this->admin_id ); $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); wp_set_current_user( 0 ); $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); @@ -195,7 +194,6 @@ public function test_get_items_invalid_comment_id() { $this->assertErrorResponse( 'rest_comment_invalid_id', $response ); } public function test_get_items_unauthenticated() { - wp_set_current_user( $this->admin_id ); add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); wp_set_current_user( 0 ); $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d/meta', $this->approved_id ) ); @@ -708,7 +706,6 @@ public function test_delete_item_invalid_meta_id() { $this->assertEquals( array( 'testvalue' ), get_comment_meta( $this->approved_id, 'testkey', false ) ); } public function test_delete_item_unauthenticated() { - wp_set_current_user( $this->admin_id ); $meta_id = add_comment_meta( $this->approved_id, 'testkey', 'testvalue' ); wp_set_current_user( 0 ); $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/comments/%d/meta/%d', $this->approved_id, $meta_id ) ); From 5f7992d71fd3d2620b625cc77f22353bbb45b1a3 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 25 Feb 2016 16:38:19 -0500 Subject: [PATCH 3/4] Merge remote-tracking branch 'WP-API/master' into add/comment-meta-endpoints-2 # Conflicts: # plugin.php --- lib/class-wp-rest-meta-users-controller.php | 99 ++ plugin.php | 9 + tests/test-rest-meta-users-controller.php | 1087 +++++++++++++++++++ 3 files changed, 1195 insertions(+) create mode 100644 lib/class-wp-rest-meta-users-controller.php create mode 100644 tests/test-rest-meta-users-controller.php diff --git a/lib/class-wp-rest-meta-users-controller.php b/lib/class-wp-rest-meta-users-controller.php new file mode 100644 index 0000000..8cd1475 --- /dev/null +++ b/lib/class-wp-rest-meta-users-controller.php @@ -0,0 +1,99 @@ +parent_controller = new WP_REST_Users_Controller(); + $this->namespace = 'wp/v2'; + $this->rest_base = 'meta'; + } + + /** + * Check if a given request has access to get meta for a user. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $user = get_user_by( 'id', (int) $request['parent_id'] ); + + if ( empty( $user ) || empty( $user->ID ) ) { + return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user id.' ), array( 'status' => 404 ) ); + } + + if ( ! current_user_can( 'edit_user', $user->ID ) ) { + return new WP_Error( 'rest_forbidden', __( 'Sorry, you cannot view the meta for this user.' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to get a specific meta entry for a user. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + return $this->get_items_permissions_check( $request ); + } + + /** + * Check if a given request has access to create a meta entry for a user. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + return $this->get_items_permissions_check( $request ); + } + + /** + * Check if a given request has access to update a meta entry for a user. + * + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + return $this->get_items_permissions_check( $request ); + } + + /** + * Check if a given request has access to delete meta for a user. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $user = get_user_by( 'id', (int) $request['parent_id'] ); + + if ( empty( $user ) || empty( $user->ID ) ) { + return new WP_Error( 'rest_user_invalid_id', __( 'Invalid user id.' ), array( 'status' => 404 ) ); + } + + if ( ! current_user_can( 'delete_user', $user->ID ) ) { + return new WP_Error( 'rest_forbidden', __( 'Sorry, you cannot delete the meta for this user.' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } +} diff --git a/plugin.php b/plugin.php index 704b5ff..b279231 100644 --- a/plugin.php +++ b/plugin.php @@ -21,6 +21,11 @@ function meta_rest_api_init() { require_once dirname( __FILE__ ) . '/lib/class-wp-rest-meta-posts-controller.php'; } + if ( class_exists( 'WP_REST_Controller' ) + && ! class_exists( 'WP_REST_Meta_Users_Controller' ) ) { + require_once dirname( __FILE__ ) . '/lib/class-wp-rest-meta-users-controller.php'; + } + if ( class_exists( 'WP_REST_Controller' ) && ! class_exists( 'WP_REST_Meta_Comments_Controller' ) ) { require_once dirname( __FILE__ ) . '/lib/class-wp-rest-meta-comments-controller.php'; @@ -33,8 +38,12 @@ function meta_rest_api_init() { } } + $user_meta_controller = new WP_REST_Meta_Users_Controller(); + $user_meta_controller->register_routes(); + $comment_meta_controller = new WP_REST_Meta_Comments_Controller(); $comment_meta_controller->register_routes(); + } add_action( 'rest_api_init', 'meta_rest_api_init', 11 ); diff --git a/tests/test-rest-meta-users-controller.php b/tests/test-rest-meta-users-controller.php new file mode 100644 index 0000000..1b602c8 --- /dev/null +++ b/tests/test-rest-meta-users-controller.php @@ -0,0 +1,1087 @@ +user = $this->factory->user->create( array( + 'role' => 'administrator', + ) ); + } + + public function test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( '/wp/v2/users/(?P[\d]+)/meta', $routes ); + $this->assertCount( 2, $routes['/wp/v2/users/(?P[\d]+)/meta'] ); + $this->assertArrayHasKey( '/wp/v2/users/(?P[\d]+)/meta/(?P[\d]+)', $routes ); + $this->assertCount( 3, $routes['/wp/v2/users/(?P[\d]+)/meta/(?P[\d]+)'] ); + } + + public function test_context_param() { + $this->user = $this->factory->user->create(); + // Collection + $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users/' . $this->user . '/meta' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'edit', $data['endpoints'][0]['args']['context']['default'] ); + $this->assertEquals( array( 'edit' ), $data['endpoints'][0]['args']['context']['enum'] ); + // Single + $meta_id_basic = add_user_meta( $this->user, 'testkey', 'testvalue' ); + $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users/' . $this->user . '/meta/' . $meta_id_basic ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'edit', $data['endpoints'][0]['args']['context']['default'] ); + $this->assertEquals( array( 'edit' ), $data['endpoints'][0]['args']['context']['enum'] ); + } + + public function test_get_item() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + $data = $response->get_data(); + $this->assertCount( 3, $data ); + + if ( $data['id'] === $meta_id ) { + $this->assertEquals( 'testkey', $data['key'] ); + $this->assertEquals( 'testvalue', $data['value'] ); + } else { + $this->fail(); + } + } + + public function test_get_items() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + + $meta_id_serialized = add_user_meta( $this->user, 'testkey_serialized', array( 'testvalue1', 'testvalue2' ) ); + $meta_id_serialized_object = add_user_meta( $this->user, 'testkey_serialized_object', (object) array( 'testvalue' => 'test' ) ); + $meta_id_serialized_array = add_user_meta( $this->user, 'testkey_serialized_array', serialize( array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ) ) ); + $meta_id_protected = add_user_meta( $this->user, '_testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + $data = $response->get_data(); + + foreach ( $data as $row ) { + $row = (array) $row; + $this->assertArrayHasKey( 'id', $row ); + $this->assertArrayHasKey( 'key', $row ); + $this->assertArrayHasKey( 'value', $row ); + + if ( $row['id'] === $meta_id_serialized ) { + $this->assertEquals( 'testkey_serialized', $row['key'] ); + $this->assertEquals( array( 'testvalue1', 'testvalue2' ), $row['value'] ); + } + + if ( $row['id'] === $meta_id_serialized_object ) { + $this->assertEquals( 'testkey_serialized_object', $row['key'] ); + $this->assertEquals( (object) array( 'testvalue' => 'test' ), $row['value'] ); + } + + if ( $row['id'] === $meta_id_serialized_array ) { + $this->assertEquals( 'testkey_serialized_array', $row['key'] ); + $this->assertEquals( serialize( array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ) ), $row['value'] ); + } + } + } + + public function test_get_item_no_user_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['parent_id'] = 0; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 ); + } + + public function test_get_item_invalid_user_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['parent_id'] = -1; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 ); + } + + public function test_get_item_no_meta_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', 0, $meta_id ) ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 ); + } + + public function test_get_item_invalid_meta_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['id'] = 'a'; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_id', $response, 404 ); + } + + public function test_get_item_protected() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, '_testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + } + + public function test_get_item_serialized_array() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', array( 'testvalue' => 'test' ) ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + } + + public function test_get_item_serialized_object() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', (object) array( 'testvalue' => 'test' ) ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + } + + public function test_get_item_unauthenticated() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); + } + + public function test_get_item_wrong_user() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $this->user_two = $this->factory->user->create(); + $meta_id_two = add_user_meta( $this->user_two, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user_two, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_user_mismatch', $response, 400 ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id_two ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_user_mismatch', $response, 400 ); + } + + public function test_get_items_no_user_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request['parent_id'] = 0; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response ); + } + + public function test_get_items_invalid_user_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request['parent_id'] = -1; + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response ); + } + + public function test_get_items_unauthenticated() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + add_user_meta( $this->user, 'testkey', 'testvalue' ); + + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_forbidden', $response ); + } + + public function test_create_item() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( array( + 'key' => 'testkey', + 'value' => 'testvalue', + ) ); + $response = $this->server->dispatch( $request ); + + $meta = get_user_meta( $this->user, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( 'testvalue', $meta[0] ); + + $data = $response->get_data(); + $this->assertArrayHasKey( 'id', $data ); + $this->assertEquals( 'testkey', $data['key'] ); + $this->assertEquals( 'testvalue', $data['value'] ); + } + + public function test_create_item_no_user_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => 'testkey', + 'value' => 'testvalue', + ); + + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $request['parent_id'] = 0; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 ); + } + + public function test_create_item_invalid_user_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => 'testkey', + 'value' => 'testvalue', + ); + + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $request['parent_id'] = -1; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 ); + } + + public function test_create_item_no_value() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => 'testkey', + ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + + $data = $response->get_data(); + $this->assertArrayHasKey( 'id', $data ); + $this->assertEquals( 'testkey', $data['key'] ); + $this->assertEquals( '', $data['value'] ); + } + + public function test_create_item_no_key() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'value' => 'testvalue', + ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_missing_callback_param', $response, 400 ); + } + + public function test_create_item_empty_string_key() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => '', + 'value' => 'testvalue', + ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_key', $response, 400 ); + } + + public function test_create_item_invalid_key() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => false, + 'value' => 'testvalue', + ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_key', $response, 400 ); + } + + public function test_create_item_unauthenticated() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => 'testkey', + 'value' => 'testvalue', + ); + + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); + $this->assertEmpty( get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_create_item_serialized_array() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => 'testkey', + 'value' => array( 'testvalue1', 'testvalue2' ), + ); + + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); + $this->assertEmpty( get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_create_item_serialized_object() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => 'testkey', + 'value' => (object) array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ), + ); + + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); + $this->assertEmpty( get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_create_item_serialized_string() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => 'testkey', + 'value' => serialize( array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ) ), + ); + + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEmpty( get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_create_item_failed_get() { + $this->markTestSkipped(); + + $this->endpoint = $this->getMock( 'WP_REST_Meta_Posts', array( 'get_meta' ), array( $this->fake_server ) ); + + $test_error = new WP_Error( 'rest_test_error', 'Test error' ); + $this->endpoint->expects( $this->any() )->method( 'get_meta' )->will( $this->returnValue( $test_error ) ); + + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => 'testkey', + 'value' => 'testvalue', + ); + + $response = $this->endpoint->add_meta( $this->user, $data ); + $this->assertErrorResponse( 'rest_test_error', $response ); + } + + public function test_create_item_protected() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => '_testkey', + 'value' => 'testvalue', + ); + + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + $this->assertEmpty( get_user_meta( $this->user, '_testkey' ) ); + } + + /** + * Ensure slashes aren't added + */ + public function test_create_item_unslashed() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => 'testkey', + 'value' => "test unslashed ' value", + ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $this->server->dispatch( $request ); + + $meta = get_user_meta( $this->user, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( "test unslashed ' value", $meta[0] ); + } + + /** + * Ensure slashes aren't touched in data + */ + public function test_create_item_slashed() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $data = array( + 'key' => 'testkey', + 'value' => "test slashed \\' value", + ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta', $this->user ) ); + $request->set_body_params( $data ); + + $this->server->dispatch( $request ); + + $meta = get_user_meta( $this->user, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( "test slashed \\' value", $meta[0] ); + } + + public function test_update_item() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( array( + 'value' => 'testnewvalue', + ) ); + + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $data = $response->get_data(); + $this->assertEquals( $meta_id, $data['id'] ); + $this->assertEquals( 'testkey', $data['key'] ); + $this->assertEquals( 'testnewvalue', $data['value'] ); + + $meta = get_user_meta( $this->user, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( 'testnewvalue', $meta[0] ); + } + + public function test_update_meta_key() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'key' => 'testnewkey', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $data = $response->get_data(); + $this->assertEquals( $meta_id, $data['id'] ); + $this->assertEquals( 'testnewkey', $data['key'] ); + $this->assertEquals( 'testvalue', $data['value'] ); + + $meta = get_user_meta( $this->user, 'testnewkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( 'testvalue', $meta[0] ); + + // Ensure it was actually renamed, not created + $meta = get_user_meta( $this->user, 'testkey', false ); + $this->assertEmpty( $meta ); + } + + public function test_update_meta_key_and_value() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $data = $response->get_data(); + $this->assertEquals( $meta_id, $data['id'] ); + $this->assertEquals( 'testnewkey', $data['key'] ); + $this->assertEquals( 'testnewvalue', $data['value'] ); + + $meta = get_user_meta( $this->user, 'testnewkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( 'testnewvalue', $meta[0] ); + + // Ensure it was actually renamed, not created + $meta = get_user_meta( $this->user, 'testkey', false ); + $this->assertEmpty( $meta ); + } + + public function test_update_meta_empty() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array(); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_data_invalid', $response, 400 ); + } + + public function test_update_meta_no_user_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', 0, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 ); + } + + public function test_update_meta_invalid_user_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 ); + } + + public function test_update_meta_no_meta_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, 0 ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_id', $response, 404 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_update_meta_invalid_meta_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['id'] = 'a'; + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_id', $response, 404 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_update_meta_unauthenticated() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + wp_set_current_user( 0 ); + + $data = array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_update_meta_wrong_user() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $this->user_two = $this->factory->user->create(); + $meta_id_two = add_user_meta( $this->user_two, 'testkey', 'testvalue' ); + + $data = array( + 'key' => 'testnewkey', + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user_two, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_user_mismatch', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user_two, 'testkey' ) ); + + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id_two ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_user_mismatch', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_update_meta_serialized_array() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'value' => array( 'testvalue1', 'testvalue2' ), + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_update_meta_serialized_object() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'value' => (object) array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ), + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_update_meta_serialized_string() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'value' => serialize( array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ) ), + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_update_meta_existing_serialized() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', array( 'testvalue1', 'testvalue2' ) ); + + $data = array( + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEquals( array( array( 'testvalue1', 'testvalue2' ) ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_update_meta_protected() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, '_testkey', 'testvalue' ); + + $data = array( + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, '_testkey' ) ); + } + + public function test_update_meta_protected_new() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'key' => '_testnewkey', + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey' ) ); + $this->assertEmpty( get_user_meta( $this->user, '_testnewkey' ) ); + } + + public function test_update_meta_invalid_key() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'key' => false, + 'value' => 'testnewvalue', + ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_key', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey' ) ); + } + + /** + * Ensure slashes aren't added + */ + public function test_update_meta_unslashed() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'key' => 'testkey', + 'value' => "test unslashed ' value", + ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $this->server->dispatch( $request ); + + $meta = get_user_meta( $this->user, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( "test unslashed ' value", $meta[0] ); + } + + /** + * Ensure slashes aren't touched in data + */ + public function test_update_meta_slashed() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $data = array( + 'key' => 'testkey', + 'value' => "test slashed \\' value", + ); + $request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request->set_body_params( $data ); + + $this->server->dispatch( $request ); + + $meta = get_user_meta( $this->user, 'testkey', false ); + $this->assertNotEmpty( $meta ); + $this->assertCount( 1, $meta ); + $this->assertEquals( "test slashed \\' value", $meta[0] ); + } + + public function test_delete_item() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['force'] = true; + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $data = $response->get_data(); + $this->assertArrayHasKey( 'message', $data ); + $this->assertNotEmpty( $data['message'] ); + + $meta = get_user_meta( $this->user, 'testkey', false ); + $this->assertEmpty( $meta ); + } + + public function test_delete_item_no_trash() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_trash_not_supported', $response, 501 ); + + // Ensure the meta still exists + $meta = get_metadata_by_mid( 'user', $meta_id ); + $this->assertNotEmpty( $meta ); + } + + public function test_delete_item_no_user_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['force'] = true; + $request['parent_id'] = 0; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 ); + + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey', false ) ); + } + + public function test_delete_item_invalid_user_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['force'] = true; + $request['parent_id'] = -1; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 ); + + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey', false ) ); + } + + public function test_delete_item_no_meta_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['force'] = true; + $request['id'] = 0; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_id', $response, 404 ); + + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey', false ) ); + } + + public function test_delete_item_invalid_meta_id() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['force'] = true; + $request['id'] = 'a'; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_id', $response, 404 ); + + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey', false ) ); + } + + public function test_delete_item_unauthenticated() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['force'] = true; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); + + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey', false ) ); + } + + public function test_delete_item_wrong_user() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $this->user_two = $this->factory->user->create(); + $meta_id_two = add_user_meta( $this->user_two, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user_two, $meta_id ) ); + $request['force'] = true; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_user_mismatch', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user_two, 'testkey' ) ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id_two ) ); + $request['force'] = true; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_user_mismatch', $response, 400 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_delete_item_serialized_array() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $value = array( 'testvalue1', 'testvalue2' ); + $meta_id = add_user_meta( $this->user, 'testkey', $value ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['force'] = true; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEquals( array( $value ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_delete_item_serialized_object() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $value = (object) array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ); + $meta_id = add_user_meta( $this->user, 'testkey', $value ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['force'] = true; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEquals( array( $value ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_delete_item_serialized_string() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $value = serialize( array( 'testkey1' => 'testvalue1', 'testkey2' => 'testvalue2' ) ); + $meta_id = add_user_meta( $this->user, 'testkey', $value ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['force'] = true; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_invalid_action', $response, 400 ); + $this->assertEquals( array( $value ), get_user_meta( $this->user, 'testkey' ) ); + } + + public function test_delete_item_protected() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + $meta_id = add_user_meta( $this->user, '_testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $request['force'] = true; + + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_meta_protected', $response, 403 ); + $this->assertEquals( array( 'testvalue' ), get_user_meta( $this->user, '_testkey' ) ); + } + + public function test_prepare_item() { + wp_set_current_user( $this->user ); + $this->allow_user_to_manage_multisite(); + + $meta_id = add_user_meta( $this->user, 'testkey', 'testvalue' ); + + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d/meta/%d', $this->user, $meta_id ) ); + $response = $this->server->dispatch( $request ); + + $data = $response->get_data(); + $this->assertEquals( $meta_id, $data['id'] ); + $this->assertEquals( 'testkey', $data['key'] ); + $this->assertEquals( 'testvalue', $data['value'] ); + } + + public function test_get_item_schema() { + // No op + } + + protected function allow_user_to_manage_multisite() { + wp_set_current_user( $this->user ); + $user = wp_get_current_user(); + if ( is_multisite() ) { + update_site_option( 'site_admins', array( $user->user_login ) ); + } + return; + } +} From f68134f3a6168b817c25c0ffe92024a77ac5e8e1 Mon Sep 17 00:00:00 2001 From: Kyle Date: Fri, 26 Feb 2016 10:06:40 -0500 Subject: [PATCH 4/4] Updated `delete_item_permissions_check` * UPDATED: The `delete_item_permissions_check` function now uses the `edit_comment` cap instead of the `moderate_comments` cap --- lib/class-wp-rest-meta-comments-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/class-wp-rest-meta-comments-controller.php b/lib/class-wp-rest-meta-comments-controller.php index 712104e..f7bf190 100644 --- a/lib/class-wp-rest-meta-comments-controller.php +++ b/lib/class-wp-rest-meta-comments-controller.php @@ -92,7 +92,7 @@ public function delete_item_permissions_check( $request ) { return new WP_Error( 'rest_comment_invalid_id', __( 'Invalid comment id.' ), array( 'status' => 404 ) ); } - if ( ! current_user_can( 'moderate_comments' ) ) { + if ( ! current_user_can( 'edit_comment', $comment->comment_ID ) ) { return new WP_Error( 'rest_forbidden', __( 'Sorry, you cannot delete the meta for this comment.' ), array( 'status' => rest_authorization_required_code() ) ); } return true;