From 522494857e20eb4e440416bdfd97d632fbf7622d Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 22 Jul 2016 18:09:53 -0700 Subject: [PATCH 1/9] Filter customize_snapshot posts permalinks --- php/class-post-type.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/php/class-post-type.php b/php/class-post-type.php index 292e3089..665802d5 100644 --- a/php/class-post-type.php +++ b/php/class-post-type.php @@ -101,6 +101,7 @@ public function register() { register_post_type( static::SLUG, $args ); + add_filter( 'post_type_link', array( $this, 'filter_post_type_link' ), 10, 2 ); add_action( 'add_meta_boxes_' . static::SLUG, array( $this, 'remove_publish_metabox' ), 100 ); add_action( 'load-revision.php', array( $this, 'suspend_kses_for_snapshot_revision_restore' ) ); add_filter( 'bulk_actions-edit-' . static::SLUG, array( $this, 'filter_bulk_actions' ) ); @@ -110,6 +111,23 @@ public function register() { add_filter( 'user_has_cap', array( $this, 'filter_user_has_cap' ), 10, 2 ); } + /** + * Filter post link. + * + * @param string $url URL. + * @param \WP_Post $post Post. + * @return string URL. + */ + public function filter_post_type_link( $url, $post ) { + if ( self::SLUG === $post->post_type ) { + $url = add_query_arg( + array( 'customzie_snapshot_uuid' => $post->post_name ), + home_url( '/' ) + ); + } + return $url; + } + /** * Suspend kses which runs on content_save_pre and can corrupt JSON in post_content. * @@ -329,7 +347,7 @@ public function render_data_metabox( $post ) { esc_html__( 'Edit in Customizer', 'customize-snapshots' ) ); - $frontend_view_url = add_query_arg( array_map( 'rawurlencode', $args ), home_url() ); + $frontend_view_url = get_permalink( $post->ID ); echo sprintf( '%s', esc_url( $frontend_view_url ), From d294ae5bdcf29a102c278b6cd6a677d4ef0ea90b Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 22 Jul 2016 18:20:06 -0700 Subject: [PATCH 2/9] Use get_permalink for post_row_actions as well --- php/class-post-type.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php/class-post-type.php b/php/class-post-type.php index 665802d5..fff8cad7 100644 --- a/php/class-post-type.php +++ b/php/class-post-type.php @@ -274,10 +274,13 @@ public function filter_post_row_actions( $actions, $post ) { $actions ); - $frontend_view_url = add_query_arg( array_map( 'rawurlencode', $args ), home_url() ); $actions = array_merge( array( - 'front-view' => sprintf( '%s', esc_url( $frontend_view_url ), esc_html__( 'Preview Snapshot', 'customize-snapshots' ) ), + 'front-view' => sprintf( + '%s', + esc_url( get_permalink( $post->ID ) ), + esc_html__( 'Preview Snapshot', 'customize-snapshots' ) + ), ), $actions ); From 8b8219027475e0955fab721acc5b2cfbe05e6311 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 22 Jul 2016 23:47:42 -0700 Subject: [PATCH 3/9] Fix typo in customize_snapshot_uuid --- php/class-post-type.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/class-post-type.php b/php/class-post-type.php index fff8cad7..f87b4bf1 100644 --- a/php/class-post-type.php +++ b/php/class-post-type.php @@ -121,7 +121,7 @@ public function register() { public function filter_post_type_link( $url, $post ) { if ( self::SLUG === $post->post_type ) { $url = add_query_arg( - array( 'customzie_snapshot_uuid' => $post->post_name ), + array( 'customize_snapshot_uuid' => $post->post_name ), home_url( '/' ) ); } From 1bf82172ac5a56482327cf350f56a097ac96d06d Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 22 Jul 2016 23:59:30 -0700 Subject: [PATCH 4/9] Add initial read-only REST API endpoints for snapshots --- php/class-post-type.php | 6 +- php/class-snapshot-rest-api-controller.php | 212 +++++++++++++++++++++ 2 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 php/class-snapshot-rest-api-controller.php diff --git a/php/class-post-type.php b/php/class-post-type.php index f87b4bf1..475f34fb 100644 --- a/php/class-post-type.php +++ b/php/class-post-type.php @@ -94,7 +94,11 @@ public function register() { 'publish_posts' => 'do_not_allow', ), 'rewrite' => false, - 'show_in_customizer' => false, + 'show_in_customizer' => false, // Prevent inception. + 'show_in_rest' => true, + 'rest_base' => 'customize_snapshots', + 'rest_controller_class' => __NAMESPACE__ . '\\Snapshot_REST_API_Controller', + 'customize_snapshot_post_type_obj' => $this, 'menu_icon' => 'dashicons-camera', 'register_meta_box_cb' => array( $this, 'setup_metaboxes' ), ); diff --git a/php/class-snapshot-rest-api-controller.php b/php/class-snapshot-rest-api-controller.php new file mode 100644 index 00000000..c30ad46e --- /dev/null +++ b/php/class-snapshot-rest-api-controller.php @@ -0,0 +1,212 @@ +customize_snapshot_post_type_obj ) ) { + throw new Exception( 'Missing customize_snapshot post type obj or arg for customize_snapshot_post_type_obj' ); + } + $this->snapshot_post_type = $post_type_obj->customize_snapshot_post_type_obj; + parent::__construct( $post_type ); + } + + /** + * Get the Post's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = parent::get_item_schema(); + $schema['properties']['content'] = array( + 'description' => __( 'Object mapping setting ID to an object of setting params, including value.', 'customize-snapshots' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + ); + return $schema; + } + + /** + * Get the query params for collections of attachments. + * + * @return array + */ + public function get_collection_params() { + $params = parent::get_collection_params(); + $params['author']['sanitize_callback'] = array( $this, 'parse_author_list' ); + $params['author_exclude']['sanitize_callback'] = array( $this, 'parse_author_list' ); + return $params; + } + + /** + * Parse comma-separated list of authors represented as IDs or usernames. + * + * @param string $author_list Authors. + * @return array User IDs. + */ + public function parse_author_list( $author_list ) { + if ( empty( $author_list ) ) { + return array(); + } + $authors = array(); + foreach ( preg_split( '/\s*,\s*/', trim( $author_list ) ) as $author ) { + if ( is_numeric( $author ) ) { + $authors[] = intval( $author ); + } else { + $user = get_user_by( 'slug', sanitize_user( $author ) ); + if ( $user ) { + $authors[] = $user->ID; + } else { + $authors[] = -1; + } + } + } + return $authors; + } + + /** + * Check for fundamental customize capability to do anything with snapshots. + * + * @return bool|\WP_Error + */ + protected function check_initial_access_permission() { + if ( ! current_user_can( 'customize' ) ) { + return new \WP_Error( 'rest_customize_unauthorized', __( 'Sorry, Customizer snapshots require proper authentication.', 'customize-snapshots' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has basic access to read a snapshot. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function get_item_permissions_check( $request ) { + $error = $this->check_initial_access_permission(); + if ( is_wp_error( $error ) ) { + return $error; + } + return parent::get_item_permissions_check( $request ); + } + + /** + * Check if a given request has basic access to read snapshots. + * + * @param \WP_REST_Request $request Full details about the request. + * @return \WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + $error = $this->check_initial_access_permission(); + if ( is_wp_error( $error ) ) { + return $error; + } + return parent::get_items_permissions_check( $request ); + } + + /** + * Restrict read permission to whether the user can edit. + * + * @param \WP_Post $post Post object. + * @return boolean Can we read it? + */ + public function check_read_permission( $post ) { + $post_type_obj = get_post_type_object( 'customize_snapshot' ); + if ( ! current_user_can( $post_type_obj->cap->edit_post, $post->ID ) ) { + return false; + } + return current_user_can( 'customize' ) && parent::check_read_permission( $post ); + } + + /** + * Prepare a single post output for response. + * + * @param \WP_Post $post Post object. + * @param \WP_REST_Request $request Request object. + * @return \WP_REST_Response $response Response. + */ + public function prepare_item_for_response( $post, $request ) { + $response = parent::prepare_item_for_response( $post, $request ); + $response->data['content'] = $this->snapshot_post_type->get_post_content( $post ); + return $response; + } + + /** + * Prepare a single post for create or update. + * + * @todo This will be irrelevant when create_item and update_item are implemented, as they can use Post_Type::save() directly. + * + * @param \WP_REST_Request $request Request object. + * @return \WP_Error|\stdClass $prepared_post Post object. + */ + protected function prepare_item_for_database( $request ) { + $prepared_post = parent::prepare_item_for_database( $request ); + if ( ! is_wp_error( $prepared_post ) && is_array( $request['content'] ) ) { + $prepared_post->post_content = wp_json_encode( $request['content'] ); + } + return $prepared_post; + } + + /** + * Create one item from the collection. + * + * @param \WP_REST_Request $request Full data about the request. + * @return \WP_Error|\WP_REST_Response + */ + public function create_item( $request ) { + unset( $request ); + return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not yet implemented.", 'customize-snapshots' ), __METHOD__ ), array( 'status' => 405 ) ); + } + + /** + * Update one item from the collection. + * + * @param \WP_REST_Request $request Full data about the request. + * @return \WP_Error|\WP_REST_Response + */ + public function update_item( $request ) { + unset( $request ); + return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not yet implemented.", 'customize-snapshots' ), __METHOD__ ), array( 'status' => 405 ) ); + } + + /** + * Delete one item from the collection. + * + * @param \WP_REST_Request $request Full data about the request. + * @return \WP_Error|\WP_REST_Response + */ + public function delete_item( $request ) { + unset( $request ); + return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not yet implemented.", 'customize-snapshots' ), __METHOD__ ), array( 'status' => 405 ) ); + } +} From 4bc8990cff42755c97ca983b1216731434a4d28e Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 23 Jul 2016 08:17:09 -0700 Subject: [PATCH 5/9] Add test for filter_post_type_link --- tests/php/test-class-post-type.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/php/test-class-post-type.php b/tests/php/test-class-post-type.php index 7b2d65c9..feeeb352 100644 --- a/tests/php/test-class-post-type.php +++ b/tests/php/test-class-post-type.php @@ -46,6 +46,7 @@ public function test_register() { $post_type->register(); $this->assertTrue( post_type_exists( Post_Type::SLUG ) ); + $this->assertEquals( 10, has_filter( 'post_type_link', array( $post_type, 'filter_post_type_link' ) ) ); $this->assertEquals( 100, has_action( 'add_meta_boxes_' . Post_Type::SLUG, array( $post_type, 'remove_publish_metabox' ) ) ); $this->assertEquals( 10, has_action( 'load-revision.php', array( $post_type, 'suspend_kses_for_snapshot_revision_restore' ) ) ); $this->assertEquals( 10, has_filter( 'bulk_actions-edit-' . Post_Type::SLUG, array( $post_type, 'filter_bulk_actions' ) ) ); @@ -55,7 +56,30 @@ public function test_register() { $this->assertEquals( 10, has_filter( 'user_has_cap', array( $post_type, 'filter_user_has_cap' ) ) ); } + /** + * Test filter_post_type_link. + * + * @covers Post_Type::filter_post_type_link() + */ + function test_filter_post_type_link() { + $post_type = new Post_Type( $this->plugin->customize_snapshot_manager ); + + $post_id = $post_type->save( array( + 'uuid' => self::UUID, + 'data' => array( + 'blogname' => array( 'value' => 'Hello' ), + ), + ) ); + $this->assertContains( + 'customize_snapshot_uuid=' . self::UUID, + $post_type->filter_post_type_link( '', get_post( $post_id ) ) + ); + + remove_all_filters( 'post_type_link' ); + $post_type->register(); + $this->assertContains( 'customize_snapshot_uuid=' . self::UUID, get_permalink( $post_id ) ); + } /** * Suspend kses which runs on content_save_pre and can corrupt JSON in post_content. From 4b3cb85aed36ab0daf9cfa283a92673e21141bec Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 23 Jul 2016 08:26:30 -0700 Subject: [PATCH 6/9] Add custom phpunit config with rest-api as dependency --- .dev-lib | 5 +++++ phpunit.xml.dist | 32 +++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) mode change 120000 => 100644 phpunit.xml.dist diff --git a/.dev-lib b/.dev-lib index d5046767..76f633ce 100644 --- a/.dev-lib +++ b/.dev-lib @@ -1,3 +1,8 @@ PATH_INCLUDES='*.* php js css tests' WPCS_GIT_TREE=develop ASSETS_DIR=wp-assets + +function after_wp_install { + echo "Installing REST API..." + svn export -q https://plugins.svn.wordpress.org/rest-api/trunk/ "$WP_CORE_DIR/src/wp-content/plugins/rest-api" +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 120000 index 69def723..00000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1 +0,0 @@ -dev-lib/phpunit-plugin.xml \ No newline at end of file diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..fc237299 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,31 @@ + + + + + + + + + ./tests/ + + + + + + ./ + + ./dev-lib + ./node_modules + ./tests + ./vendor + + + + From 13f8edfd8813c11b8c3f6f1771d2252a11d3cc63 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 23 Jul 2016 09:53:58 -0700 Subject: [PATCH 7/9] Allow author and date_gmt to be supplied in Post_Type::save() --- php/class-post-type.php | 6 ++++++ tests/php/test-class-post-type.php | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/php/class-post-type.php b/php/class-post-type.php index 475f34fb..85eb6524 100644 --- a/php/class-post-type.php +++ b/php/class-post-type.php @@ -531,6 +531,12 @@ public function save( array $args ) { } $post_arr['post_status'] = $args['status']; } + if ( ! empty( $args['author'] ) ) { + $post_arr['post_author'] = $args['author']; + } + if ( ! empty( $args['date_gmt'] ) ) { + $post_arr['post_date_gmt'] = $args['date_gmt']; + } $this->suspend_kses(); if ( $is_update ) { diff --git a/tests/php/test-class-post-type.php b/tests/php/test-class-post-type.php index feeeb352..46e8ddcb 100644 --- a/tests/php/test-class-post-type.php +++ b/tests/php/test-class-post-type.php @@ -489,6 +489,25 @@ public function test_save() { $this->assertEquals( get_stylesheet(), get_post_meta( $r, '_snapshot_theme', true ) ); $this->assertEquals( $this->plugin->version, get_post_meta( $r, '_snapshot_version', true ) ); + + // Success with author supplied. + $user_id = $this->factory()->user->create( array( 'role' => 'administrator' ) ); + $post_id = $post_type->save( array( + 'uuid' => self::UUID, + 'data' => $data, + 'status' => 'publish', + 'author' => $user_id, + ) ); + $this->assertEquals( $user_id, get_post( $post_id )->post_author ); + + // Success with future date. + $post_id = $post_type->save( array( + 'uuid' => self::UUID, + 'data' => $data, + 'status' => 'publish', + 'date_gmt' => gmdate( 'Y-m-d H:i:s', time() + 24 * 3600 ), + ) ); + $this->assertEquals( 'future', get_post_status( $post_id ) ); } /** From 03808cd8084a3bf834d8f221979b80ce53d6ac44 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 23 Jul 2016 09:56:36 -0700 Subject: [PATCH 8/9] Add unit tests for REST API --- php/class-snapshot-rest-api-controller.php | 31 +-- ...est-class-snapshot-rest-api-controller.php | 251 ++++++++++++++++++ 2 files changed, 253 insertions(+), 29 deletions(-) create mode 100644 tests/php/test-class-snapshot-rest-api-controller.php diff --git a/php/class-snapshot-rest-api-controller.php b/php/class-snapshot-rest-api-controller.php index c30ad46e..f12d40cd 100644 --- a/php/class-snapshot-rest-api-controller.php +++ b/php/class-snapshot-rest-api-controller.php @@ -10,7 +10,7 @@ /** * REST API Controller Class * - * @todo Add support for editing. + * @todo Add support for editing. Make sure Post_Type::save() is used. * @todo Add support for PATCH requests. * @todo Allow use of UUID instead of ID in routes. * @todo Disallow edits to slug. @@ -101,7 +101,7 @@ public function parse_author_list( $author_list ) { */ protected function check_initial_access_permission() { if ( ! current_user_can( 'customize' ) ) { - return new \WP_Error( 'rest_customize_unauthorized', __( 'Sorry, Customizer snapshots require proper authentication.', 'customize-snapshots' ), array( 'status' => rest_authorization_required_code() ) ); + return new \WP_Error( 'rest_customize_unauthorized', __( 'Sorry, Customizer snapshots require proper authentication (the customize capability).', 'customize-snapshots' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -161,33 +161,6 @@ public function prepare_item_for_response( $post, $request ) { return $response; } - /** - * Prepare a single post for create or update. - * - * @todo This will be irrelevant when create_item and update_item are implemented, as they can use Post_Type::save() directly. - * - * @param \WP_REST_Request $request Request object. - * @return \WP_Error|\stdClass $prepared_post Post object. - */ - protected function prepare_item_for_database( $request ) { - $prepared_post = parent::prepare_item_for_database( $request ); - if ( ! is_wp_error( $prepared_post ) && is_array( $request['content'] ) ) { - $prepared_post->post_content = wp_json_encode( $request['content'] ); - } - return $prepared_post; - } - - /** - * Create one item from the collection. - * - * @param \WP_REST_Request $request Full data about the request. - * @return \WP_Error|\WP_REST_Response - */ - public function create_item( $request ) { - unset( $request ); - return new \WP_Error( 'invalid-method', sprintf( __( "Method '%s' not yet implemented.", 'customize-snapshots' ), __METHOD__ ), array( 'status' => 405 ) ); - } - /** * Update one item from the collection. * diff --git a/tests/php/test-class-snapshot-rest-api-controller.php b/tests/php/test-class-snapshot-rest-api-controller.php new file mode 100644 index 00000000..5d1c6608 --- /dev/null +++ b/tests/php/test-class-snapshot-rest-api-controller.php @@ -0,0 +1,251 @@ +plugin = get_plugin_instance(); + + $this->plugin->customize_snapshot_manager->post_type->register(); + + $snapshot_data = array( + array( + 'status' => 'draft', + 'date_gmt' => '2010-01-01 00:00:00', + ), + array( + 'status' => 'pending', + 'date_gmt' => '2010-01-01 00:00:00', + ), + array( + 'status' => 'publish', + 'date_gmt' => '2010-01-01 00:00:00', + ), + array( + 'status' => 'future', + 'date_gmt' => gmdate( 'Y-m-d H:i:s', time() + 24 * 3600 ), + ), + ); + foreach ( $snapshot_data as $i => $snapshot_params ) { + $user_id = $this->factory()->user->create( array( 'role' => 'administrator' ) ); + $post_id = $this->plugin->customize_snapshot_manager->post_type->save( array_merge( + $snapshot_params, + array( + 'uuid' => Customize_Snapshot_Manager::generate_uuid(), + 'author' => $user_id, + 'data' => array( 'blogname' => array( 'value' => "Snapshot $i" ) ), + ) + ) ); + $this->snapshot_by_status[ $snapshot_params['status'] ] = $post_id; + } + + global $wp_rest_server; + $wp_rest_server = null; + $this->server = rest_get_server(); + } + + /** + * Test unauthenticated requests for /wp/v2/customize_snapshots + */ + function test_get_collection_unauthenticated() { + wp_set_current_user( 0 ); + $this->assertFalse( current_user_can( 'customize' ) ); + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots' ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_customize_unauthorized', $response ); + } + + /** + * Test unauthorized requests for /wp/v2/customize_snapshots + */ + function test_get_collection_unauthorized() { + wp_set_current_user( $this->factory()->user->create( array( 'role' => 'contributor' ) ) ); + $this->assertFalse( current_user_can( 'customize' ) ); + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots' ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_customize_unauthorized', $response ); + } + + /** + * Test unauthorized requests for /wp/v2/customize_snapshots + */ + function test_get_collection_authorized() { + wp_set_current_user( $this->factory()->user->create( array( 'role' => 'administrator' ) ) ); + $this->assertTrue( current_user_can( 'customize' ) ); + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots' ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test getting published items. + */ + function test_get_collection_published() { + wp_set_current_user( $this->factory()->user->create( array( 'role' => 'administrator' ) ) ); + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots' ); + $request->set_param( 'context', 'edit' ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $items = $response->get_data(); + $this->assertCount( 1, $items ); + $this->assertEquals( 'publish', $items[0]['status'] ); + $this->assertArrayHasKey( 'content', $items[0] ); + $this->assertArrayHasKey( 'blogname', $items[0]['content'] ); + $this->assertArrayHasKey( 'value', $items[0]['content']['blogname'] ); + + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots' ); + $request->set_param( 'context', 'edit' ); + $request->set_url_params( array( 'status' => 'publish' ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( $items, $response->get_data() ); + } + + /** + * Test getting any items. + */ + function test_get_collection_any() { + wp_set_current_user( $this->factory()->user->create( array( 'role' => 'administrator' ) ) ); + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots' ); + $request->set_param( 'context', 'edit' ); + $request->set_param( 'status', 'any' ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $items = $response->get_data(); + $this->assertCount( 4, $items ); + $item_statuses = wp_list_pluck( $items, 'status' ); + $this->assertContains( 'draft', $item_statuses ); + $this->assertContains( 'pending', $item_statuses ); + $this->assertContains( 'publish', $item_statuses ); + $this->assertContains( 'future', $item_statuses ); + } + + /** + * Test getting items by author. + */ + function test_get_collection_by_author() { + wp_set_current_user( $this->factory()->user->create( array( 'role' => 'administrator' ) ) ); + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots' ); + $request->set_param( 'context', 'edit' ); + $request->set_param( 'status', 'any' ); + $response = $this->server->dispatch( $request ); + $items = $response->get_data(); + $item_authors = array_values( wp_list_pluck( $items, 'author' ) ); + + $item_author_mapping = array(); + foreach ( $items as $item ) { + $item_author_mapping[ $item['author'] ] = $item['slug']; + } + + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots' ); + $request->set_param( 'context', 'edit' ); + $request->set_param( 'status', 'any' ); + $request->set_param( 'author', $item_authors[0] ); + $response = $this->server->dispatch( $request ); + $items = $response->get_data(); + $this->assertCount( 1, $items ); + $this->assertEquals( $items[0]['slug'], $item_author_mapping[ $item_authors[0] ] ); + + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots' ); + $request->set_param( 'context', 'edit' ); + $request->set_param( 'status', 'any' ); + $request->set_param( 'author', get_user_by( 'id', $item_authors[0] )->user_nicename ); + $response = $this->server->dispatch( $request ); + $items = $response->get_data(); + $this->assertCount( 1, $items ); + $this->assertEquals( $items[0]['slug'], $item_author_mapping[ $item_authors[0] ] ); + + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots' ); + $request->set_param( 'context', 'edit' ); + $request->set_param( 'status', 'any' ); + $request->set_param( 'author', join( ',', $item_authors ) ); + $response = $this->server->dispatch( $request ); + $items = $response->get_data(); + $this->assertCount( 4, $items ); + } + + /** + * Test getting published items. + */ + function test_get_item_published() { + wp_set_current_user( $this->factory()->user->create( array( 'role' => 'administrator' ) ) ); + $post = get_post( $this->snapshot_by_status['publish'] ); + $request = new \WP_REST_Request( 'GET', '/wp/v2/customize_snapshots/' . $post->ID ); + $request->set_param( 'context', 'edit' ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $item = $response->get_data(); + $this->assertArrayHasKey( 'content', $item ); + $this->assertArrayHasKey( 'blogname', $item['content'] ); + $this->assertArrayHasKey( 'value', $item['content']['blogname'] ); + $this->assertEquals( 'publish', $item['status'] ); + } + + /** + * Test create item. + */ + function test_create_item() { + wp_set_current_user( $this->factory()->user->create( array( 'role' => 'administrator' ) ) ); + $request = new \WP_REST_Request( 'POST', '/wp/v2/customize_snapshots' ); + $request->set_param( 'content', array( 'blogname' => array( 'value' => 'test' ) ) ); + $request->set_param( 'slug', Customize_Snapshot_Manager::generate_uuid() ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_cannot_create', $response ); + } + + /** + * Test update item. + */ + function test_update_item() { + wp_set_current_user( $this->factory()->user->create( array( 'role' => 'administrator' ) ) ); + $post = get_post( $this->snapshot_by_status['publish'] ); + $request = new \WP_REST_Request( 'PUT', '/wp/v2/customize_snapshots/' . $post->ID ); + $request->set_param( 'content', array( 'blogname' => array( 'value' => 'test' ) ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'invalid-method', $response ); + } + + /** + * Test update item. + */ + function test_delete_item() { + wp_set_current_user( $this->factory()->user->create( array( 'role' => 'administrator' ) ) ); + $post = get_post( $this->snapshot_by_status['publish'] ); + $request = new \WP_REST_Request( 'DELETE', '/wp/v2/customize_snapshots/' . $post->ID ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'invalid-method', $response ); + } +} From c1b9f1c1aa0013fdc1d320ae8ea88ed133650f4b Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 23 Jul 2016 10:01:40 -0700 Subject: [PATCH 9/9] Update wp-dev-lib 30b4b22...4aba13a: Merge pull request #194 from shadyvb/feature/editorconfig https://github.com/xwp/wp-dev-lib/compare/30b4b22...4aba13a --- dev-lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-lib b/dev-lib index 30b4b229..4aba13a8 160000 --- a/dev-lib +++ b/dev-lib @@ -1 +1 @@ -Subproject commit 30b4b229691a9f4b006ded13c738a06961085887 +Subproject commit 4aba13a8b5c29f7ce53940bf733550e1c8c01e6c