last_inserted_notice_id = (int) $matches[1]; } return $query; } public function add_filter_update_last_active_query() { add_filter( 'query', array( $this, 'catch_inserted_id' ) ); } public function set_last_inserted_notice_id( $notice_obj ) { remove_filter( 'query', array( $this, 'catch_inserted_id' ) ); if ( $this->last_inserted_notice_id ) { $notice_obj->id = $this->last_inserted_notice_id; $this->last_inserted_notice_id = null; } } public function test_register_routes() { $routes = $this->server->get_routes(); $endpoint = $this->endpoint_url; // Main. $this->assertArrayHasKey( $endpoint, $routes ); $this->assertCount( 2, $routes[ $endpoint ] ); // Single. $single_endpoint = $endpoint . '/(?P[\d]+)'; $this->assertArrayHasKey( $single_endpoint, $routes ); $this->assertCount( 3, $routes[ $single_endpoint ] ); // Dismiss. $dismiss_endpoint = $endpoint . '/dismiss'; $this->assertArrayHasKey( $dismiss_endpoint, $routes ); $this->assertCount( 1, $routes[ $dismiss_endpoint ] ); } public function create_notice( $notices = array() ) { $created = array(); foreach ( $notices as $notice ) { $props = wp_parse_args( $notice, array( 'subject' => 'example subject', 'message' => 'example message', 'date_sent' => bp_core_current_time(), 'is_active' => 1, ) ); $new_notice = new BP_Messages_Notice(); foreach ( $props as $key => $prop ) { $new_notice->{$key} = $prop; } if ( $new_notice->save() ) { $created[] = $new_notice; } } return $created; } /** * @group get_items */ public function test_get_items() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'foo', ), 'n2' => array( 'subject' => 'bar', ), ); $created = $this->create_notice( $tested ); $request = new WP_REST_Request( 'GET', $this->endpoint_url ); $request->set_param( 'context', 'edit' ); $response = $this->server->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); $all_data = $response->get_data(); $this->assertNotEmpty( $all_data ); $this->assertCount( 2, $all_data ); $data = wp_list_filter( $all_data, array( 'is_active' => true ) ); $data_n = reset( $data ); $n = wp_filter_object_list( $created, array( 'id' => $data_n['id'] ), 'and', 'id' ); $key = key( $n ); $this->check_notice_data( $created[ $key ], $data_n, 'edit' ); } /** * @group get_items */ public function test_get_items_no_edit_access() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'foo', ), 'n2' => array( 'subject' => 'bar', ), ); $this->create_notice( $tested ); $u1 = static::factory()->user->create(); wp_set_current_user( $u1 ); $request = new WP_REST_Request( 'GET', $this->endpoint_url ); $request->set_param( 'context', 'edit' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'rest_forbidden', $response, rest_authorization_required_code() ); } /** * @group get_items */ public function test_get_items_view_active() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'foo', 'is_active' => 0, ), 'n2' => array( 'subject' => 'bar', ), ); $created = $this->create_notice( $tested ); $n = wp_filter_object_list( $created, array( 'is_active' => 1 ), 'and', 'id' ); $key = key( $n ); $u1 = static::factory()->user->create(); wp_set_current_user( $u1 ); $request = new WP_REST_Request( 'GET', $this->endpoint_url ); $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); $data = $response->get_data(); $this->assertNotEmpty( $data ); $this->assertCount( 1, $data, 'There should only be one active notice in the view context' ); $this->check_notice_data( $created[ $key ], $data[0] ); } /** * @group get_items */ public function test_get_items_no_active() { wp_set_current_user( $this->user ); $u1 = static::factory()->user->create(); wp_set_current_user( $u1 ); $request = new WP_REST_Request( 'GET', $this->endpoint_url ); $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $this->assertCount( 0, $data, 'There should be no active notices available' ); } /** * @group get_item */ public function test_get_item() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'foo', 'is_active' => 0, ), 'n2' => array( 'subject' => 'bar', ), ); $created = $this->create_notice( $tested ); $n = wp_filter_object_list( $created, array( 'is_active' => 1 ), 'and', 'id' ); $id = current( $n ); $key = key( $n ); $u1 = static::factory()->user->create(); wp_set_current_user( $u1 ); $request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $id ); $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); $data = $response->get_data(); $this->assertNotEmpty( $data ); $this->check_notice_data( $created[ $key ], $data ); } /** * @group get_item */ public function test_get_item_admin_access() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'foo', 'is_active' => 0, ), 'n2' => array( 'subject' => 'bar', ), ); $created = $this->create_notice( $tested ); $n = wp_filter_object_list( $created, array( 'is_active' => 0 ), 'and', 'id' ); $id = current( $n ); $key = key( $n ); $request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $id ); $request->set_param( 'context', 'edit' ); $response = $this->server->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); $data = $response->get_data(); $this->assertNotEmpty( $data ); $this->check_notice_data( $created[ $key ], $data, 'edit' ); } /** * @group get_item */ public function test_get_item_no_access() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'foo', 'is_active' => 0, ), 'n2' => array( 'subject' => 'bar', ), ); $created = $this->create_notice( $tested ); $n = wp_filter_object_list( $created, array( 'is_active' => 0 ), 'and', 'id' ); $id = current( $n ); $u1 = static::factory()->user->create(); wp_set_current_user( $u1 ); $request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $id ); $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() ); } /** * @group get_item */ public function test_get_item_view_active() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'bar', 'is_active' => 0, ), 'n2' => array( 'subject' => 'foo', ), ); $created = $this->create_notice( $tested ); $n = wp_filter_object_list( $created, array( 'is_active' => 1 ), 'and', 'id' ); $id = current( $n ); $key = key( $n ); $u1 = static::factory()->user->create(); wp_set_current_user( $u1 ); $request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $id ); $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); $data = $response->get_data(); $this->assertNotEmpty( $data ); $this->check_notice_data( $created[ $key ], $data ); } /** * @group get_item */ public function test_get_item_with_invalid_id() { wp_set_current_user( $this->user ); $request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ); $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 ); } /** * @group create_item */ public function test_create_item() { wp_set_current_user( $this->user ); $request = new WP_REST_Request( 'POST', $this->endpoint_url ); $request->set_param( 'context', 'edit' ); $request->set_query_params( array( 'subject' => 'Foo Bar', 'message' => 'Content', ) ); $response = $this->server->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); $data = $response->get_data(); $this->assertNotEmpty( $data ); $this->assertTrue( $data['is_active'] ); $this->assertSame( 'Content', $data['message']['raw'] ); } /** * @group create_item */ public function test_create_item_no_access() { wp_set_current_user( static::factory()->user->create() ); $request = new WP_REST_Request( 'POST', $this->endpoint_url ); $request->set_param( 'context', 'edit' ); $request->set_query_params( array( 'subject' => 'Foo Bar', 'message' => 'Ouch!', ) ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() ); } /** * @group create_item */ public function test_create_item_no_subject() { wp_set_current_user( $this->user ); $request = new WP_REST_Request( 'POST', $this->endpoint_url ); $request->set_param( 'context', 'edit' ); $request->set_query_params( array( 'subject' => '', 'message' => 'Aïe!', ) ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_user_cannot_create_sitewide_notice', $response, 500 ); } /** * @group update_item */ public function test_update_item() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'Foo Bar', 'is_active' => 0, ), ); $created = $this->create_notice( $tested ); $n = current( $created ); $request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $n->id ) ); $request->set_param( 'context', 'edit' ); $request->set_param( 'is_active', true ); $request->set_param( 'message', 'Yeah!' ); $response = $this->server->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); $data = $response->get_data(); $this->assertNotEmpty( $data ); $this->assertTrue( $data['is_active'] ); $this->assertSame( 'Yeah!', $data['message']['raw'] ); } /** * @group update_item */ public function test_update_item_no_access() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'Foo Bar', ), ); $created = $this->create_notice( $tested ); $n = current( $created ); $u1 = static::factory()->user->create(); wp_set_current_user( $u1 ); $request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $n->id ) ); $request->set_param( 'context', 'edit' ); $request->set_param( 'message', 'Ouch!' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() ); } /** * @group update_item */ public function test_update_item_no_message() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'Foo Bar', ), ); $created = $this->create_notice( $tested ); $n = current( $created ); $request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', $n->id ) ); $request->set_param( 'context', 'edit' ); $request->set_param( 'message', '' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_sitewide_notices_update_failed', $response, 500 ); } /** * @group update_item */ public function test_update_item_with_invalid_id() { wp_set_current_user( $this->user ); $request = new WP_REST_Request( 'PUT', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) ); $request->set_param( 'context', 'edit' ); $request->set_param( 'message', 'Ouch!' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 ); } /** * @group delete_item */ public function test_delete_item() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'Foo Bar', ), ); $created = $this->create_notice( $tested ); $n = current( $created ); $request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $n->id ) ); $request->set_param( 'context', 'edit' ); $response = $this->server->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); $data = $response->get_data(); $this->assertNotEmpty( $data ); $this->assertTrue( $data['deleted'] ); $this->assertSame( 'Foo Bar', $data['previous']['subject']['raw'] ); } /** * @group delete_item */ public function test_delete_item_no_access() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'Ouch!', ), ); $created = $this->create_notice( $tested ); $n = current( $created ); $u1 = static::factory()->user->create(); wp_set_current_user( $u1 ); $request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', $n->id ) ); $request->set_param( 'context', 'edit' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() ); } /** * @group delete_item */ public function test_delete_item_with_invalid_id() { wp_set_current_user( $this->user ); $request = new WP_REST_Request( 'DELETE', sprintf( $this->endpoint_url . '/%d', REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ) ); $request->set_param( 'context', 'edit' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 ); } /** * @group dismiss_item */ public function test_dismiss_item() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'Taz', ), ); $created = $this->create_notice( $tested ); $n = current( $created ); $u1 = static::factory()->user->create(); wp_set_current_user( $u1 ); $request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/dismiss' ); $request->set_param( 'context', 'edit' ); $response = $this->server->dispatch( $request ); $this->assertSame( 200, $response->get_status() ); $data = $response->get_data(); $this->assertNotEmpty( $data ); $this->assertTrue( $data['dismissed'] ); $this->assertSame( 'Taz', $data['previous']['subject']['rendered'] ); $this->assertContains( $n->id, bp_get_user_meta( $u1, 'closed_notices', true ) ); } /** * @group dismiss_item */ public function test_dismiss_item_no_actives() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'Taz', 'is_active' => 0, ), ); $this->create_notice( $tested ); $u1 = static::factory()->user->create(); wp_set_current_user( $u1 ); $request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/dismiss' ); $request->set_param( 'context', 'edit' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_invalid_id', $response, 404 ); } /** * @group dismiss_item */ public function test_dismiss_item_not_logged_in() { wp_set_current_user( $this->user ); $tested = array( 'n1' => array( 'subject' => 'Taz', ), ); $this->create_notice( $tested ); wp_set_current_user( 0 ); $request = new WP_REST_Request( 'PUT', $this->endpoint_url . '/dismiss' ); $request->set_param( 'context', 'edit' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() ); } /** * @group prepare_item */ public function test_prepare_item() { global $wp_rest_additional_fields; $original_fields = $wp_rest_additional_fields; $notice = new BP_Messages_Notice(); $notice->id = 123; $notice->subject = 'Notice subject'; $notice->message = 'Notice message'; $notice->date_sent = '2020-01-02 03:04:05'; $notice->is_active = 1; register_rest_field( 'bp_sitewide_notices', 'test_edit_field', array( 'get_callback' => static function () { return 'Additional value'; }, 'schema' => array( 'type' => 'string', 'context' => array( 'edit' ), ), ) ); try { foreach ( array( null, 'view', 'edit' ) as $context ) { $request = new WP_REST_Request( 'GET', $this->endpoint_url . '/' . $notice->id ); if ( null !== $context ) { $request->set_param( 'context', $context ); } $response = $this->endpoint->prepare_item_for_response( $notice, $request ); $this->assertInstanceOf( 'WP_REST_Response', $response ); $this->assertSame( 200, $response->get_status() ); $data = $response->get_data(); $this->assertSame( 123, $data['id'] ); $this->check_notice_data( $notice, $data, $context ); $this->assertSame( '2020-01-02T03:04:05', $data['date_gmt'] ); if ( 'edit' !== $context ) { $this->assertArrayNotHasKey( 'raw', $data['subject'] ); $this->assertArrayNotHasKey( 'raw', $data['message'] ); $this->assertArrayNotHasKey( 'is_active', $data ); } $links = $response->get_links(); $this->assertSame( rest_url( $this->endpoint_url . '/' . $notice->id ), $links['self'][0]['href'] ); $this->assertSame( rest_url( $this->endpoint_url . '/' ), $links['collection'][0]['href'] ); if ( 'edit' === $context ) { $this->assertSame( 'Additional value', $data['test_edit_field'] ); } else { $this->assertArrayNotHasKey( 'test_edit_field', $data ); } } } finally { $wp_rest_additional_fields = $original_fields; } } protected function check_notice_data( $notice, $data, $context = 'view' ) { $this->assertSame( $notice->id, $data['id'] ); if ( 'edit' === $context ) { $this->assertSame( $notice->subject, $data['subject']['raw'] ); $this->assertSame( $notice->message, $data['message']['raw'] ); if ( (bool) $notice->is_active ) { $this->assertTrue( $data['is_active'] ); } else { $this->assertFalse( $data['is_active'] ); } } $this->assertSame( apply_filters( 'bp_get_message_notice_subject', wp_staticize_emoji( $notice->subject ) ), $data['subject']['rendered'] ); $this->assertSame( apply_filters( 'bp_get_message_notice_text', wp_staticize_emoji( $notice->message ) ), $data['message']['rendered'] ); $this->assertSame( bp_rest_prepare_date_response( $notice->date_sent, get_date_from_gmt( $notice->date_sent ) ), $data['date'] ); $this->assertSame( bp_rest_prepare_date_response( $notice->date_sent ), $data['date_gmt'] ); } public function test_get_item_schema() { $request = new WP_REST_Request( 'OPTIONS', $this->endpoint_url ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; $this->assertCount( 6, $properties ); $this->assertArrayHasKey( 'id', $properties ); $this->assertArrayHasKey( 'subject', $properties ); $this->assertArrayHasKey( 'message', $properties ); $this->assertArrayHasKey( 'date', $properties ); $this->assertArrayHasKey( 'date_gmt', $properties ); $this->assertArrayHasKey( 'is_active', $properties ); } public function test_context_param() { // Collection. $request = new WP_REST_Request( 'OPTIONS', $this->endpoint_url ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $this->assertSame( 'view', $data['endpoints'][0]['args']['context']['default'] ); $this->assertSame( array( 'view', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] ); } }