Index: tests/xmlrpc/wp/editUserInfo.php
===================================================================
--- tests/xmlrpc/wp/editUserInfo.php	(revision 0)
+++ tests/xmlrpc/wp/editUserInfo.php	(working copy)
@@ -0,0 +1,69 @@
+<?php
+
+/**
+ * @group xmlrpc
+ * @group user
+ */
+class TestXMLRPCServer_wp_editUserInfo extends WP_XMLRPC_UnitTestCase {
+
+	function test_invalid_username_password() {
+		$result = $this->myxmlrpcserver->wp_editUserInfo( array( 1, 'username', 'password', array() ) );
+		$this->assertInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( 403, $result->code );
+	}
+
+    function test_subscriber_profile() {
+        $subscriber_id = $this->make_user_by_role( 'subscriber' );
+
+        $new_data = array(
+            'first_name' => rand_str(),
+            'last_name' => rand_str(),
+            'website' => 'http://www.example.org/subscriber',
+            'display_name' => rand_str(),
+            'nickname' => rand_str(),
+            'nicename' => rand_str(),
+            'bio' => rand_str(200)
+        );
+        $result = $this->myxmlrpcserver->wp_editUserInfo( array( 1, 'subscriber', 'subscriber', $new_data ) );
+        $this->assertNotInstanceOf( 'IXR_Error', $result );
+        $this->assertTrue( $result );
+
+        // verify that the new values were stored
+        $user_data = get_userdata( $subscriber_id );
+        $this->assertEquals( $new_data['first_name'], $user_data->first_name );
+        $this->assertEquals( $new_data['last_name'], $user_data->last_name );
+        $this->assertEquals( $new_data['website'], $user_data->user_url );
+        $this->assertEquals( $new_data['display_name'], $user_data->display_name );
+        $this->assertEquals( $new_data['nickname'], $user_data->nickname );
+        $this->assertEquals( $new_data['nicename'], $user_data->user_nicename );
+        $this->assertEquals( $new_data['bio'], $user_data->description );
+    }
+
+    function test_ignore_password_change() {
+        $this->make_user_by_role( 'author' );
+        $new_pass = rand_str();
+        $new_data = array( 'password' => $new_pass );
+
+        $result = $this->myxmlrpcserver->wp_editUserInfo( array( 1, 'author', 'author', $new_data ) );
+        $this->assertNotInstanceOf( 'IXR_Error', $result );
+        $this->assertTrue( $result );
+
+        $auth_old = wp_authenticate( 'author', 'author' );
+        $auth_new = wp_authenticate( 'author', $new_pass );
+        $this->assertInstanceOf( 'WP_User', $auth_old );
+        $this->assertTrue( is_wp_error( $auth_new ) );
+    }
+
+    function test_ignore_email_change() {
+        $editor_id = $this->make_user_by_role( 'editor' );
+        $new_email = rand_str() . '@example.com';
+        $new_data = array( 'email' => $new_email );
+
+        $result = $this->myxmlrpcserver->wp_editUserInfo( array( 1, 'editor', 'editor', $new_data ) );
+        $this->assertNotInstanceOf( 'IXR_Error', $result );
+        $this->assertTrue( $result );
+
+        $user_data = get_userdata( $editor_id );
+        $this->assertNotEquals( $new_email, $user_data->email );
+    }
+}
Index: tests/xmlrpc/wp/getUser.php
===================================================================
--- tests/xmlrpc/wp/getUser.php	(revision 0)
+++ tests/xmlrpc/wp/getUser.php	(working copy)
@@ -0,0 +1,137 @@
+<?php
+
+/**
+ * @group xmlrpc
+ * @group user
+ */
+class TestXMLRPCServer_wp_getUser extends WP_XMLRPC_UnitTestCase {
+
+	function test_invalid_username_password() {
+		$result = $this->myxmlrpcserver->wp_getUser( array( 1, 'username', 'password', 1 ) );
+		$this->assertInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( 403, $result->code );
+	}
+
+	function test_invalid_user() {
+		$this->make_user_by_role( 'administrator' );
+
+		$result = $this->myxmlrpcserver->wp_getUser( array( 1, 'administrator', 'administrator', 34902348908234 ) );
+		$this->assertInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( 404, $result->code );
+	}
+
+	function test_incapable_user() {
+		$this->make_user_by_role( 'subscriber' );
+		$editor_id = $this->make_user_by_role( 'editor' );
+
+		$result = $this->myxmlrpcserver->wp_getUser( array( 1, 'subscriber', 'subscriber', $editor_id ) );
+		$this->assertInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( 401, $result->code );
+	}
+
+	function test_subscriber_self() {
+		$subscriber_id = $this->make_user_by_role( 'subscriber' );
+
+		$result = $this->myxmlrpcserver->wp_getUser( array( 1, 'subscriber', 'subscriber', $subscriber_id ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( $subscriber_id, $result['user_id'] );
+	}
+
+	function test_valid_user() {
+		$this->make_user_by_role( 'administrator' );
+
+		$registered_date = strtotime( '-1 day' );
+		$user_data = array(
+			'user_login' => 'getusertestuser',
+			'user_pass' => rand_str(),
+			'first_name' => rand_str(),
+			'last_name' => rand_str(),
+			'description' => rand_str( 100 ),
+			'user_email' => 'getUserTestUser@example.com',
+			'nickname' => rand_str(),
+			'user_nicename' => rand_str(),
+			'display_name' => rand_str(),
+			'user_url' => 'http://www.example.com/testuser',
+			'role' => 'author',
+			'aim' => rand_str(),
+			'user_registered' => strftime( "%Y-%m-%d %H:%M:%S", $registered_date )
+		);
+		$user_id = wp_insert_user( $user_data );
+
+		$result = $this->myxmlrpcserver->wp_getUser( array( 1, 'administrator', 'administrator', $user_id ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $result );
+
+		// check data types
+		$this->assertInternalType( 'string', $result['user_id'] );
+		$this->assertStringMatchesFormat( '%d', $result['user_id'] );
+		$this->assertInternalType( 'string', $result['username'] );
+		$this->assertInternalType( 'string', $result['first_name'] );
+		$this->assertInternalType( 'string', $result['last_name'] );
+		$this->assertInstanceOf( 'IXR_Date', $result['registered'] );
+		$this->assertInternalType( 'string', $result['bio'] );
+		$this->assertInternalType( 'string', $result['email'] );
+		$this->assertInternalType( 'string', $result['nickname'] );
+		$this->assertInternalType( 'string', $result['nicename'] );
+		$this->assertInternalType( 'string', $result['url'] );
+		$this->assertInternalType( 'string', $result['display_name'] );
+		$this->assertInternalType( 'array', $result['capabilities'] );
+		$this->assertInternalType( 'array', $result['roles'] );
+
+		// check expected values
+		$this->assertEquals( $user_id, $result['user_id'] );
+		$this->assertEquals( $user_data['user_login'], $result['username'] );
+		$this->assertEquals( $user_data['first_name'], $result['first_name'] );
+		$this->assertEquals( $user_data['last_name'], $result['last_name'] );
+		$this->assertEquals( $registered_date, $result['registered']->getTimestamp() );
+		$this->assertEquals( $user_data['description'], $result['bio'] );
+		$this->assertEquals( $user_data['user_email'], $result['email'] );
+		$this->assertEquals( $user_data['nickname'], $result['nickname'] );
+		$this->assertEquals( $user_data['user_nicename'], $result['nicename'] );
+		$this->assertEquals( $user_data['user_url'], $result['url'] );
+		$this->assertEquals( $user_data['display_name'], $result['display_name'] );
+		$this->assertArrayHasKey( $user_data['role'], $result['capabilities'] );
+		$this->assertEquals( 1, $result['capabilities'][$user_data['role']] );
+		$this->assertEquals( $user_data['user_login'], $result['username'] );
+		$this->assertContains( $user_data['role'], $result['roles'] );
+
+		wp_delete_user( $user_id );
+	}
+
+	function test_no_fields() {
+		$editor_id = $this->make_user_by_role( 'editor' );
+		$this->make_user_by_role( 'administrator' );
+
+		$result = $this->myxmlrpcserver->wp_getUser( array( 1, 'administrator', 'administrator', $editor_id, array() ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( $editor_id, $result['user_id'] );
+
+		$expected_fields = array( 'user_id' );
+		$this->assertEquals( $expected_fields, array_keys( $result ) );
+	}
+
+	function test_basic_fields() {
+		$editor_id = $this->make_user_by_role( 'editor' );
+		$this->make_user_by_role( 'administrator' );
+
+		$result = $this->myxmlrpcserver->wp_getUser( array( 1, 'administrator', 'administrator', $editor_id, array( 'basic' ) ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( $editor_id, $result['user_id'] );
+
+		$expected_fields = array( 'user_id', 'username', 'email', 'registered', 'display_name', 'nicename' );
+		$this->assertEquals( sort( $expected_fields ), sort( array_keys( $result ) ) );
+	}
+
+	function test_arbitrary_fields() {
+		$editor_id = $this->make_user_by_role( 'editor' );
+		$this->make_user_by_role( 'administrator' );
+
+		$fields = array( 'email', 'bio', 'user_contacts' );
+
+		$result = $this->myxmlrpcserver->wp_getUser( array( 1, 'administrator', 'administrator', $editor_id, $fields ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( $editor_id, $result['user_id'] );
+
+		$expected_fields = array_merge( array( 'user_id' ), $fields );
+		$this->assertEquals( sort( $expected_fields ), sort( array_keys( $result ) ) );
+	}
+}
Index: tests/xmlrpc/wp/getUserInfo.php
===================================================================
--- tests/xmlrpc/wp/getUserInfo.php	(revision 0)
+++ tests/xmlrpc/wp/getUserInfo.php	(working copy)
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @group xmlrpc
+ * @group user
+ */
+class TestXMLRPCServer_wp_getUserInfo extends WP_XMLRPC_UnitTestCase {
+
+	function test_invalid_username_password() {
+		$result = $this->myxmlrpcserver->wp_getUserInfo( array( 1, 'username', 'password' ) );
+		$this->assertInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( 403, $result->code );
+	}
+
+	function test_subscriber() {
+		$subscriber_id = $this->make_user_by_role( 'subscriber' );
+
+		$result = $this->myxmlrpcserver->wp_getUserInfo( array( 1, 'subscriber', 'subscriber' ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( $subscriber_id, $result['user_id'] );
+		$this->assertContains( 'subscriber', $result['roles'] );
+	}
+
+	function test_administrator() {
+		$administrator_id = $this->make_user_by_role( 'administrator' );
+
+		$result = $this->myxmlrpcserver->wp_getUserInfo( array( 1, 'administrator', 'administrator' ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( $administrator_id, $result['user_id'] );
+		$this->assertContains( 'administrator', $result['roles'] );
+	}
+
+	function test_arbitrary_fields() {
+		$editor_id = $this->make_user_by_role( 'editor' );
+
+		$fields = array( 'email', 'bio', 'user_contacts' );
+
+		$result = $this->myxmlrpcserver->wp_getUserInfo( array( 1, 'editor', 'editor', $fields ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $result );
+		$this->assertEquals( $editor_id, $result['user_id'] );
+
+		$expected_fields = array_merge( array( 'user_id' ), $fields );
+		$this->assertEquals( sort( $expected_fields ), sort( array_keys( $result ) ) );
+	}
+}
Index: tests/xmlrpc/wp/getUsers.php
===================================================================
--- tests/xmlrpc/wp/getUsers.php	(revision 0)
+++ tests/xmlrpc/wp/getUsers.php	(working copy)
@@ -0,0 +1,94 @@
+<?php
+
+/**
+ * @group xmlrpc
+ * @group user
+ */
+class TestXMLRPCServer_wp_getUsers extends WP_XMLRPC_UnitTestCase {
+
+	function test_invalid_username_password() {
+		$results = $this->myxmlrpcserver->wp_getUsers( array( 1, 'username', 'password' ) );
+		$this->assertInstanceOf( 'IXR_Error', $results );
+		$this->assertEquals( 403, $results->code );
+	}
+
+	function test_incapable_user() {
+		$this->make_user_by_role( 'subscriber' );
+
+		$results = $this->myxmlrpcserver->wp_getUsers( array( 1, 'subscriber', 'subscriber' ) );
+		$this->assertInstanceOf( 'IXR_Error', $results );
+		$this->assertEquals( 401, $results->code );
+	}
+
+	function test_capable_user() {
+		$this->make_user_by_role( 'administrator' );
+
+		$results = $this->myxmlrpcserver->wp_getUsers( array( 1, 'administrator', 'administrator' ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $results );
+	}
+
+	function test_invalid_role() {
+		$this->make_user_by_role( 'administrator' );
+
+		$filter = array( 'role' => rand_str() );
+		$results = $this->myxmlrpcserver->wp_getUsers( array( 1, 'administrator', 'administrator', $filter ) );
+		$this->assertInstanceOf( 'IXR_Error', $results );
+		$this->assertEquals( 403, $results->code );
+	}
+
+	function test_role_filter() {
+		$author_id = $this->make_user_by_role( 'author' );
+		$editor_id = $this->make_user_by_role( 'editor' );
+		$administrator_id = $this->make_user_by_role( 'administrator' );
+
+		// test a single role ('editor')
+		$filter = array( 'role' => 'editor' );
+		$results = $this->myxmlrpcserver->wp_getUsers( array( 1, 'administrator', 'administrator', $filter ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $results );
+		$this->assertCount( 1, $results );
+		$this->assertEquals( $editor_id, $results[0]['user_id'] );
+
+		// test 'authors', which should return all non-subscribers
+		// (see 'who' => 'authors' param to WP_User_Query)
+		$filter2 = array( 'role' => 'authors' );
+		$results2 = $this->myxmlrpcserver->wp_getUsers( array( 1, 'administrator', 'administrator', $filter2 ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $results2 );
+		$this->assertCount( 3, array_intersect( array( $author_id, $editor_id, $administrator_id ), wp_list_pluck( $results2, 'user_id' ) ) );
+	}
+
+	function test_paging_filters() {
+		$this->make_user_by_role( 'administrator' );
+		$this->factory->user->create_many( 13 );
+
+		$user_ids = get_users( array( 'fields' => 'ID' ) );
+
+		$users_found = array();
+		$page_size = floor( count( $user_ids ) / 3 );
+
+		$filter = array( 'number' => $page_size, 'offset' => 0 );
+		do {
+			$presults = $this->myxmlrpcserver->wp_getUsers( array( 1, 'administrator', 'administrator', $filter ) );
+			foreach ( $presults as $user ) {
+				$users_found[] = $user['user_id'];
+			}
+			$filter['offset'] += $page_size;
+		} while ( count( $presults ) > 0 );
+
+		// verify that $user_ids matches $users_found
+		$this->assertEquals( 0, count( array_diff( $user_ids, $users_found ) ) );
+	}
+
+	function test_order_filters() {
+		$this->make_user_by_role( 'administrator' );
+
+		$filter = array( 'orderby' => 'email', 'order' => 'ASC' );
+		$results = $this->myxmlrpcserver->wp_getUsers( array( 1, 'administrator', 'administrator', $filter ) );
+		$this->assertNotInstanceOf( 'IXR_Error', $results );
+
+		$last_email = '';
+		foreach ( $results as $user ) {
+			$this->assertLessThanOrEqual( 0, strcmp( $last_email, $user['email'] ) );
+			$last_email = $user['email'];
+		}
+	}
+}
