WordPress.org

Make WordPress Core

Ticket #38739: 38739.diff

File 38739.diff, 24.4 KB (added by jnylen0, 3 years ago)
  • src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php

    diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
    index 949a668..a2c28ee 100644
    a b class WP_REST_Users_Controller extends WP_REST_Controller { 
    417417                        $ret = wpmu_validate_user_signup( $user->user_login, $user->user_email );
    418418
    419419                        if ( is_wp_error( $ret['errors'] ) && ! empty( $ret['errors']->errors ) ) {
    420                                 return $ret['errors'];
     420                                return new WP_Error( 'rest_invalid_param', __( 'Invalid user parameter(s).' ), array( 'status' => 400, 'errors' => $ret['errors']->errors ) );
    421421                        }
    422422                }
    423423
    class WP_REST_Users_Controller extends WP_REST_Controller { 
    429429                        }
    430430
    431431                        $user->ID = $user_id;
    432                         $user_id  = wp_update_user( $user );
     432                        $user_id  = wp_update_user( wp_slash( (array) $user ) );
    433433
    434434                        if ( is_wp_error( $user_id ) ) {
    435435                                return $user_id;
    class WP_REST_Users_Controller extends WP_REST_Controller { 
    437437
    438438                        add_user_to_blog( get_site()->id, $user_id, '' );
    439439                } else {
    440                         $user_id = wp_insert_user( $user );
     440                        $user_id = wp_insert_user( wp_slash( (array) $user ) );
    441441
    442442                        if ( is_wp_error( $user_id ) ) {
    443443                                return $user_id;
    class WP_REST_Users_Controller extends WP_REST_Controller { 
    552552                // Ensure we're operating on the same user we already checked.
    553553                $user->ID = $id;
    554554
    555                 $user_id = wp_update_user( $user );
     555                $user_id = wp_update_user( wp_slash( (array) $user ) );
    556556
    557557                if ( is_wp_error( $user_id ) ) {
    558558                        return $user_id;
    class WP_REST_Users_Controller extends WP_REST_Controller { 
    997997        }
    998998
    999999        /**
     1000         * Check a username for the REST API.
     1001         *
     1002         * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
     1003         *
     1004         * @since 4.7.0
     1005         *
     1006         * @param  mixed            $value   The username submitted in the request.
     1007         * @param  WP_REST_Request  $request Full details about the request.
     1008         * @param  string           $param   The parameter name.
     1009         * @return WP_Error|string The sanitized username, if valid, otherwise an error.
     1010         */
     1011        public function check_username( $value, $request, $param ) {
     1012                $username = (string) rest_sanitize_value_from_schema( $value, $request, $param );
     1013
     1014                if ( ! validate_username( $username ) ) {
     1015                        return new WP_Error( 'rest_user_invalid_username', __( 'Username contains invalid characters.' ), array( 'status' => 400 ) );
     1016                }
     1017
     1018                $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
     1019
     1020                if ( in_array( strtolower( $username ), array_map( 'strtolower', $illegal_logins ) ) ) {
     1021                        return new WP_Error( 'rest_user_invalid_username', __( 'Sorry, that username is not allowed.' ), array( 'status' => 400 ) );
     1022                }
     1023
     1024                return $username;
     1025        }
     1026
     1027        /**
     1028         * Check a user password for the REST API.
     1029         *
     1030         * Performs a couple of checks like edit_user() in wp-admin/includes/user.php.
     1031         *
     1032         * @since 4.7.0
     1033         *
     1034         * @param  mixed            $value   The password submitted in the request.
     1035         * @param  WP_REST_Request  $request Full details about the request.
     1036         * @param  string           $param   The parameter name.
     1037         * @return WP_Error|string The sanitized password, if valid, otherwise an error.
     1038         */
     1039        public function check_user_password( $value, $request, $param ) {
     1040                $password = (string) rest_sanitize_value_from_schema( $value, $request, $param );
     1041
     1042                if ( empty( $password ) ) {
     1043                        return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot be empty.' ), array( 'status' => 400 ) );
     1044                }
     1045
     1046                if ( false !== strpos( $password, "\\" ) ) {
     1047                        return new WP_Error( 'rest_user_invalid_password', __( 'Passwords cannot contain the "\\" character.' ), array( 'status' => 400 ) );
     1048                }
     1049
     1050                return $password;
     1051        }
     1052
     1053        /**
    10001054         * Retrieves the user's schema, conforming to JSON Schema.
    10011055         *
    10021056         * @since 4.7.0
    class WP_REST_Users_Controller extends WP_REST_Controller { 
    10221076                                        'context'     => array( 'edit' ),
    10231077                                        'required'    => true,
    10241078                                        'arg_options' => array(
    1025                                                 'sanitize_callback' => 'sanitize_user',
     1079                                                'sanitize_callback' => array( $this, 'check_username' ),
    10261080                                        ),
    10271081                                ),
    10281082                                'name'        => array(
    class WP_REST_Users_Controller extends WP_REST_Controller { 
    10661120                                        'description' => __( 'Description of the resource.' ),
    10671121                                        'type'        => 'string',
    10681122                                        'context'     => array( 'embed', 'view', 'edit' ),
    1069                                         'arg_options' => array(
    1070                                                 'sanitize_callback' => 'wp_filter_post_kses',
    1071                                         ),
    10721123                                ),
    10731124                                'link'        => array(
    10741125                                        'description' => __( 'Author URL to the resource.' ),
    class WP_REST_Users_Controller extends WP_REST_Controller { 
    11191170                                        'type'        => 'string',
    11201171                                        'context'     => array(), // Password is never displayed.
    11211172                                        'required'    => true,
     1173                                        'arg_options' => array(
     1174                                                'sanitize_callback' => array( $this, 'check_user_password' ),
     1175                                        ),
    11221176                                ),
    11231177                                'capabilities'    => array(
    11241178                                        'description' => __( 'All capabilities assigned to the resource.' ),
  • tests/phpunit/includes/functions.php

    diff --git a/tests/phpunit/includes/functions.php b/tests/phpunit/includes/functions.php
    index a870276..3a7c9bd 100644
    a b function _upload_dir_https( $uploads ) { 
    161161
    162162        return $uploads;
    163163}
     164
     165// Skip `setcookie` calls in auth_cookie functions due to warning:
     166// Cannot modify header information - headers already sent by ...
     167
     168function wp_set_auth_cookie( $user_id, $remember = false, $secure = '', $token = '' ) {
     169        $auth_cookie = null;
     170        $expire = null;
     171        $expiration = null;
     172        $user_id = null;
     173        $scheme = null;
     174        /** This action is documented in wp-inclues/pluggable.php */
     175        do_action( 'set_auth_cookie', $auth_cookie, $expire, $expiration, $user_id, $scheme );
     176        $logged_in_cookie = null;
     177        /** This action is documented in wp-inclues/pluggable.php */
     178        do_action( 'set_logged_in_cookie', $logged_in_cookie, $expire, $expiration, $user_id, 'logged_in' );
     179}
     180
     181function wp_clear_auth_cookie() {
     182        /** This action is documented in wp-inclues/pluggable.php */
     183        do_action( 'clear_auth_cookie' );
     184}
  • tests/phpunit/tests/rest-api/rest-users-controller.php

    diff --git a/tests/phpunit/tests/rest-api/rest-users-controller.php b/tests/phpunit/tests/rest-api/rest-users-controller.php
    index a6e0515..b689114 100644
    a b  
    1010 * @group restapi
    1111 */
    1212class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase {
     13        protected static $superadmin;
    1314        protected static $user;
    1415        protected static $editor;
    1516        protected static $site;
    1617
    1718        public static function wpSetUpBeforeClass( $factory ) {
     19                self::$superadmin = $factory->user->create( array(
     20                        'role'       => 'administrator',
     21                        'user_login' => 'superadmin',
     22                ) );
    1823                self::$user = $factory->user->create( array(
    1924                        'role' => 'administrator',
    2025                ) );
    class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { 
    2530
    2631                if ( is_multisite() ) {
    2732                        self::$site = $factory->blog->create( array( 'domain' => 'rest.wordpress.org', 'path' => '/' ) );
     33                        update_site_option( 'site_admins', array( 'superadmin' ) );
    2834                }
    2935        }
    3036
    class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { 
    175181                $request = new WP_REST_Request( 'GET', '/wp/v2/users' );
    176182                $response = $this->server->dispatch( $request );
    177183                $headers = $response->get_headers();
    178                 $this->assertEquals( 50, $headers['X-WP-Total'] );
    179                 $this->assertEquals( 5, $headers['X-WP-TotalPages'] );
     184                $this->assertEquals( 51, $headers['X-WP-Total'] );
     185                $this->assertEquals( 6, $headers['X-WP-TotalPages'] );
    180186                $next_link = add_query_arg( array(
    181187                        'page'    => 2,
    182188                        ), rest_url( 'wp/v2/users' ) );
    class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { 
    190196                $request->set_param( 'page', 3 );
    191197                $response = $this->server->dispatch( $request );
    192198                $headers = $response->get_headers();
    193                 $this->assertEquals( 51, $headers['X-WP-Total'] );
     199                $this->assertEquals( 52, $headers['X-WP-Total'] );
    194200                $this->assertEquals( 6, $headers['X-WP-TotalPages'] );
    195201                $prev_link = add_query_arg( array(
    196202                        'page'    => 2,
    class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { 
    205211                $request->set_param( 'page', 6 );
    206212                $response = $this->server->dispatch( $request );
    207213                $headers = $response->get_headers();
    208                 $this->assertEquals( 51, $headers['X-WP-Total'] );
     214                $this->assertEquals( 52, $headers['X-WP-Total'] );
    209215                $this->assertEquals( 6, $headers['X-WP-TotalPages'] );
    210216                $prev_link = add_query_arg( array(
    211217                        'page'    => 5,
    class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { 
    217223                $request->set_param( 'page', 8 );
    218224                $response = $this->server->dispatch( $request );
    219225                $headers = $response->get_headers();
    220                 $this->assertEquals( 51, $headers['X-WP-Total'] );
     226                $this->assertEquals( 52, $headers['X-WP-Total'] );
    221227                $this->assertEquals( 6, $headers['X-WP-TotalPages'] );
    222228                $prev_link = add_query_arg( array(
    223229                        'page'    => 6,
    class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { 
    393399                $request = new WP_REST_Request( 'GET', '/wp/v2/users' );
    394400                $request->set_param( 'offset', 1 );
    395401                $response = $this->server->dispatch( $request );
    396                 $this->assertCount( 3, $response->get_data() );
     402                $this->assertCount( 4, $response->get_data() );
    397403                // 'offset' works with 'per_page'
    398404                $request->set_param( 'per_page', 2 );
    399405                $response = $this->server->dispatch( $request );
    class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { 
    715721                $this->check_add_edit_user_response( $response );
    716722        }
    717723
     724        public function test_create_item_invalid_username() {
     725                $this->allow_user_to_manage_multisite();
     726                wp_set_current_user( self::$user );
     727
     728                $params = array(
     729                        'username'    => '¯\_(ツ)_/¯',
     730                        'password'    => 'testpassword',
     731                        'email'       => 'test@example.com',
     732                        'name'        => 'Test User',
     733                        'nickname'    => 'testuser',
     734                        'slug'        => 'test-user',
     735                        'roles'       => array( 'editor' ),
     736                        'description' => 'New API User',
     737                        'url'         => 'http://example.com',
     738                );
     739
     740                // Username rules are different (more strict) for multisite; see `wpmu_validate_user_signup`
     741                if ( is_multisite() ) {
     742                        $params['username'] = 'no-dashes-allowed';
     743                }
     744
     745                $request = new WP_REST_Request( 'POST', '/wp/v2/users' );
     746                $request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
     747                $request->set_body_params( $params );
     748
     749                $response = $this->server->dispatch( $request );
     750                $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     751
     752                $data = $response->get_data();
     753                if ( is_multisite() ) {
     754                        $this->assertInternalType( 'array', $data['data']['errors'] );
     755                        $errors = $data['data']['errors'];
     756                        $this->assertInternalType( 'array', $errors['user_name'] );
     757                        $this->assertEquals( array( 'Usernames can only contain lowercase letters (a-z) and numbers.' ), $errors['user_name'] );
     758                } else {
     759                        $this->assertInternalType( 'array', $data['data']['params'] );
     760                        $errors = $data['data']['params'];
     761                        $this->assertInternalType( 'string', $errors['username'] );
     762                        $this->assertEquals( 'Username contains invalid characters.', $errors['username'] );
     763                }
     764        }
     765
     766        function get_illegal_user_logins() {
     767                return array( 'nope' );
     768        }
     769
     770        public function test_create_item_illegal_username() {
     771                $this->allow_user_to_manage_multisite();
     772                wp_set_current_user( self::$user );
     773
     774                add_filter( 'illegal_user_logins', array( $this, 'get_illegal_user_logins' ) );
     775
     776                $params = array(
     777                        'username'    => 'nope',
     778                        'password'    => 'testpassword',
     779                        'email'       => 'test@example.com',
     780                        'name'        => 'Test User',
     781                        'nickname'    => 'testuser',
     782                        'slug'        => 'test-user',
     783                        'roles'       => array( 'editor' ),
     784                        'description' => 'New API User',
     785                        'url'         => 'http://example.com',
     786                );
     787
     788                $request = new WP_REST_Request( 'POST', '/wp/v2/users' );
     789                $request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
     790                $request->set_body_params( $params );
     791
     792                $response = $this->server->dispatch( $request );
     793
     794                remove_filter( 'illegal_user_logins', array( $this, 'get_illegal_user_logins' ) );
     795
     796                $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     797
     798                $data = $response->get_data();
     799                $this->assertInternalType( 'array', $data['data']['params'] );
     800                $errors = $data['data']['params'];
     801                $this->assertInternalType( 'string', $errors['username'] );
     802                $this->assertEquals( 'Sorry, that username is not allowed.', $errors['username'] );
     803        }
     804
    718805        public function test_create_new_network_user_on_site_does_not_add_user_to_sub_site() {
    719806                if ( ! is_multisite() ) {
    720807                        $this->markTestSkipped( 'Test requires multisite.' );
    class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { 
    810897
    811898                wpmu_delete_user( $user_id );
    812899
    813                 $this->assertErrorResponse( 'user_name', $switched_response );
     900                $this->assertErrorResponse( 'rest_invalid_param', $switched_response, 400 );
     901                $data = $switched_response->get_data();
     902                $this->assertInternalType( 'array', $data['data']['errors'] );
     903                $errors = $data['data']['errors'];
     904                $this->assertInternalType( 'array', $errors['user_name'] );
     905                $this->assertEquals( array( 'Sorry, that username already exists!' ), $errors['user_name'] );
     906                $this->assertInternalType( 'array', $errors['user_email'] );
     907                $this->assertEquals( array( 'Sorry, that email address is already used!' ), $errors['user_email'] );
    814908        }
    815909
    816910        public function test_update_existing_network_user_on_sub_site_adds_user_to_site() {
    class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { 
    13051399                $this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 );
    13061400        }
    13071401
     1402        public function test_update_item_invalid_password() {
     1403                $this->allow_user_to_manage_multisite();
     1404                wp_set_current_user( self::$user );
     1405
     1406                $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', self::$editor ) );
     1407
     1408                $request->set_param( 'password', 'no\\backslashes\\allowed' );
     1409                $response = $this->server->dispatch( $request );
     1410                $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     1411
     1412                $request->set_param( 'password', '' );
     1413                $response = $this->server->dispatch( $request );
     1414                $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     1415        }
     1416
     1417        public function verify_user_roundtrip( $input = array(), $expected_output = array() ) {
     1418                if ( isset( $input['id'] ) ) {
     1419                        // Existing user; don't try to create one
     1420                        $user_id = $input['id'];
     1421                } else {
     1422                        // Create a new user
     1423                        $request = new WP_REST_Request( 'POST', '/wp/v2/users' );
     1424                        foreach ( $input as $name => $value ) {
     1425                                $request->set_param( $name, $value );
     1426                        }
     1427                        $request->set_param( 'email', 'cbg@androidsdungeon.com' );
     1428                        $response = $this->server->dispatch( $request );
     1429                        $this->assertEquals( 201, $response->get_status() );
     1430                        $actual_output = $response->get_data();
     1431
     1432                        // Compare expected API output to actual API output
     1433                        $this->assertEquals( $expected_output['username']   , $actual_output['username'] );
     1434                        $this->assertEquals( $expected_output['name']       , $actual_output['name'] );
     1435                        $this->assertEquals( $expected_output['first_name'] , $actual_output['first_name'] );
     1436                        $this->assertEquals( $expected_output['last_name']  , $actual_output['last_name'] );
     1437                        $this->assertEquals( $expected_output['url']        , $actual_output['url'] );
     1438                        $this->assertEquals( $expected_output['description'], $actual_output['description'] );
     1439                        $this->assertEquals( $expected_output['nickname']   , $actual_output['nickname'] );
     1440
     1441                        // Compare expected API output to WP internal values
     1442                        $user = get_userdata( $actual_output['id'] );
     1443                        $this->assertEquals( $expected_output['username']   , $user->user_login );
     1444                        $this->assertEquals( $expected_output['name']       , $user->display_name );
     1445                        $this->assertEquals( $expected_output['first_name'] , $user->first_name );
     1446                        $this->assertEquals( $expected_output['last_name']  , $user->last_name );
     1447                        $this->assertEquals( $expected_output['url']        , $user->user_url );
     1448                        $this->assertEquals( $expected_output['description'], $user->description );
     1449                        $this->assertEquals( $expected_output['nickname']   , $user->nickname );
     1450                        $this->assertTrue( wp_check_password( addslashes( $expected_output['password'] ), $user->user_pass ) );
     1451
     1452                        $user_id = $actual_output['id'];
     1453                }
     1454
     1455                // Update the user
     1456                $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
     1457                foreach ( $input as $name => $value ) {
     1458                        if ( 'username' !== $name ) {
     1459                                $request->set_param( $name, $value );
     1460                        }
     1461                }
     1462                $response = $this->server->dispatch( $request );
     1463                $this->assertEquals( 200, $response->get_status() );
     1464                $actual_output = $response->get_data();
     1465
     1466                // Compare expected API output to actual API output
     1467                if ( isset( $expected_output['username'] ) ) {
     1468                        $this->assertEquals( $expected_output['username'], $actual_output['username'] );
     1469                }
     1470                $this->assertEquals( $expected_output['name']       , $actual_output['name'] );
     1471                $this->assertEquals( $expected_output['first_name'] , $actual_output['first_name'] );
     1472                $this->assertEquals( $expected_output['last_name']  , $actual_output['last_name'] );
     1473                $this->assertEquals( $expected_output['url']        , $actual_output['url'] );
     1474                $this->assertEquals( $expected_output['description'], $actual_output['description'] );
     1475                $this->assertEquals( $expected_output['nickname']   , $actual_output['nickname'] );
     1476
     1477                // Compare expected API output to WP internal values
     1478                $user = get_userdata( $actual_output['id'] );
     1479                if ( isset( $expected_output['username'] ) ) {
     1480                        $this->assertEquals( $expected_output['username'], $user->user_login );
     1481                }
     1482                $this->assertEquals( $expected_output['name']       , $user->display_name );
     1483                $this->assertEquals( $expected_output['first_name'] , $user->first_name );
     1484                $this->assertEquals( $expected_output['last_name']  , $user->last_name );
     1485                $this->assertEquals( $expected_output['url']        , $user->user_url );
     1486                $this->assertEquals( $expected_output['description'], $user->description );
     1487                $this->assertEquals( $expected_output['nickname']   , $user->nickname );
     1488                $this->assertTrue( wp_check_password( addslashes( $expected_output['password'] ), $user->user_pass ) );
     1489        }
     1490
     1491        public function test_user_roundtrip_as_editor() {
     1492                wp_set_current_user( self::$editor );
     1493                $this->assertEquals( ! is_multisite(), current_user_can( 'unfiltered_html' ) );
     1494                $this->verify_user_roundtrip( array(
     1495                        'id'          => self::$editor,
     1496                        'name'        => '\o/ ¯\_(ツ)_/¯',
     1497                        'first_name'  => '\o/ ¯\_(ツ)_/¯',
     1498                        'last_name'   => '\o/ ¯\_(ツ)_/¯',
     1499                        'url'         => '\o/ ¯\_(ツ)_/¯',
     1500                        'description' => '\o/ ¯\_(ツ)_/¯',
     1501                        'nickname'    => '\o/ ¯\_(ツ)_/¯',
     1502                        'password'    => 'o/ ¯_(ツ)_/¯ \'"',
     1503                ), array(
     1504                        'name'        => '\o/ ¯\_(ツ)_/¯',
     1505                        'first_name'  => '\o/ ¯\_(ツ)_/¯',
     1506                        'last_name'   => '\o/ ¯\_(ツ)_/¯',
     1507                        'url'         => 'http://o/%20¯_(ツ)_/¯',
     1508                        'description' => '\o/ ¯\_(ツ)_/¯',
     1509                        'nickname'    => '\o/ ¯\_(ツ)_/¯',
     1510                        'password'    => 'o/ ¯_(ツ)_/¯ \'"',
     1511                ) );
     1512        }
     1513
     1514        public function test_user_roundtrip_as_editor_html() {
     1515                wp_set_current_user( self::$editor );
     1516                if ( is_multisite() ) {
     1517                        $this->assertFalse( current_user_can( 'unfiltered_html' ) );
     1518                        $this->verify_user_roundtrip( array(
     1519                                'id'          => self::$editor,
     1520                                'name'        => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1521                                'first_name'  => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1522                                'last_name'   => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1523                                'url'         => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1524                                'description' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1525                                'nickname'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1526                                'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1527                        ), array(
     1528                                'name'        => 'div strong',
     1529                                'first_name'  => 'div strong',
     1530                                'last_name'   => 'div strong',
     1531                                'url'         => 'http://divdiv/div%20strongstrong/strong%20scriptoh%20noes/script',
     1532                                'description' => 'div <strong>strong</strong> oh noes',
     1533                                'nickname'    => 'div strong',
     1534                                'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1535                        ) );
     1536                } else {
     1537                        $this->assertTrue( current_user_can( 'unfiltered_html' ) );
     1538                        $this->verify_user_roundtrip( array(
     1539                                'id'          => self::$editor,
     1540                                'name'        => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1541                                'first_name'  => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1542                                'last_name'   => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1543                                'url'         => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1544                                'description' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1545                                'nickname'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1546                                'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1547                        ), array(
     1548                                'name'        => 'div strong',
     1549                                'first_name'  => 'div strong',
     1550                                'last_name'   => 'div strong',
     1551                                'url'         => 'http://divdiv/div%20strongstrong/strong%20scriptoh%20noes/script',
     1552                                'description' => 'div <strong>strong</strong> oh noes',
     1553                                'nickname'    => 'div strong',
     1554                                'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1555                        ) );
     1556                }
     1557        }
     1558
     1559        public function test_user_roundtrip_as_superadmin() {
     1560                wp_set_current_user( self::$superadmin );
     1561                $this->assertTrue( current_user_can( 'unfiltered_html' ) );
     1562                $valid_username = is_multisite() ? 'noinvalidcharshere' : 'no-invalid-chars-here';
     1563                $this->verify_user_roundtrip( array(
     1564                        'username'    => $valid_username,
     1565                        'name'        => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1566                        'first_name'  => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1567                        'last_name'   => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1568                        'url'         => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1569                        'description' => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1570                        'nickname'    => '\\\&\\\ &amp; &invalid; < &lt; &amp;lt;',
     1571                        'password'    => '& &amp; &invalid; < &lt; &amp;lt;',
     1572                ), array(
     1573                        'username'    => $valid_username,
     1574                        'name'        => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
     1575                        'first_name'  => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
     1576                        'last_name'   => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
     1577                        'url'         => 'http://&amp;%20&amp;%20&amp;invalid;%20%20&lt;%20&amp;lt;',
     1578                        'description' => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
     1579                        'nickname'    => '\\\&amp;\\\ &amp; &amp;invalid; &lt; &lt; &amp;lt;',
     1580                        'password'    => '& &amp; &invalid; < &lt; &amp;lt;',
     1581                ) );
     1582        }
     1583
     1584        public function test_user_roundtrip_as_superadmin_html() {
     1585                wp_set_current_user( self::$superadmin );
     1586                $this->assertTrue( current_user_can( 'unfiltered_html' ) );
     1587                $valid_username = is_multisite() ? 'noinvalidcharshere' : 'no-invalid-chars-here';
     1588                $this->verify_user_roundtrip( array(
     1589                        'username'    => $valid_username,
     1590                        'name'        => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1591                        'first_name'  => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1592                        'last_name'   => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1593                        'url'         => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1594                        'description' => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1595                        'nickname'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1596                        'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1597                ), array(
     1598                        'username'    => $valid_username,
     1599                        'name'        => 'div strong',
     1600                        'first_name'  => 'div strong',
     1601                        'last_name'   => 'div strong',
     1602                        'url'         => 'http://divdiv/div%20strongstrong/strong%20scriptoh%20noes/script',
     1603                        'description' => 'div <strong>strong</strong> oh noes',
     1604                        'nickname'    => 'div strong',
     1605                        'password'    => '<div>div</div> <strong>strong</strong> <script>oh noes</script>',
     1606                ) );
     1607        }
     1608
    13081609        public function test_delete_item() {
    13091610                $user_id = $this->factory->user->create( array( 'display_name' => 'Deleted User' ) );
    13101611