Index: src/wp-admin/includes/user.php
===================================================================
--- src/wp-admin/includes/user.php	(revision 37060)
+++ src/wp-admin/includes/user.php	(working copy)
@@ -37,11 +37,9 @@
 		$user->user_login = wp_slash( $userdata->user_login );
 	} else {
 		$update = false;
+		$user->user_login = isset( $_POST['user_login'] ) ? sanitize_user( $_POST['user_login'], true ) : '';
 	}
 
-	if ( !$update && isset( $_POST['user_login'] ) )
-		$user->user_login = sanitize_user($_POST['user_login'], true);
-
 	$pass1 = $pass2 = '';
 	if ( isset( $_POST['pass1'] ) )
 		$pass1 = $_POST['pass1'];
Index: tests/phpunit/tests/user.php
===================================================================
--- tests/phpunit/tests/user.php	(revision 37060)
+++ tests/phpunit/tests/user.php	(working copy)
@@ -1199,4 +1199,87 @@
 	function action_check_passwords_blank_pw( $user_login, &$pass1 ) {
 		$pass1 = '';
 	}
+
+	/**
+	 * Checks that calling edit_user() with no user_login returns a WP error without PHP Notices.
+	 *
+	 * @ticket 36303
+	 */
+	function test_edit_user_blank_user_login() {
+		$_POST = $_GET = $_REQUEST = array();
+		$_POST['role'] = 'subscriber';
+		$_POST['email'] = 'user1@example.com';
+		// Leave unset $_POST['user_login']
+		$_POST['first_name'] = 'first_name1';
+		$_POST['last_name'] = 'last_name1';
+		$_POST['nickname'] = 'nickname1';
+		$_POST['display_name'] = 'display_name1';
+		$_POST['pass1'] = $_POST['pass2'] = 'password';
+
+		// Check new user with unset user_login.
+		$response = edit_user();
+
+		$this->assertInstanceOf( 'WP_Error', $response );
+		$this->assertEquals( array( 'user_login' ), $response->get_error_codes() );
+
+		// Check new user with blank user_login.
+		$_POST['user_login'] = '';
+		$response = edit_user();
+
+		$this->assertInstanceOf( 'WP_Error', $response );
+		$this->assertEquals( array( 'user_login' ), $response->get_error_codes() );
+
+		// Check new user with zero user_login.
+		$_POST['user_login'] = '0';
+		$response = edit_user();
+
+		$this->assertInstanceOf( 'WP_Error', $response );
+		$this->assertEquals( array( 'user_login' ), $response->get_error_codes() );
+
+		// Add user.
+		$_POST['user_login'] = 'user_login1';
+		$user_id = edit_user();
+		$user = get_user_by( 'ID', $user_id );
+
+		$this->assertInternalType( 'int', $user_id );
+		$this->assertInstanceOf( 'WP_User', $user );
+		$this->assertEquals( 'user_login1', $user->user_login );
+		$this->assertEquals( 'nickname1', $user->nickname );
+
+		// Check can update user with unset user_login (ignored).
+		unset( $_POST['user_login'] );
+		$_POST['nickname'] = 'nickname_updated';
+
+		$user_id = edit_user( $user_id );
+		$user = get_user_by( 'ID', $user_id );
+
+		$this->assertInternalType( 'int', $user_id );
+		$this->assertInstanceOf( 'WP_User', $user );
+		$this->assertEquals( 'user_login1', $user->user_login );
+		$this->assertEquals( 'nickname_updated', $user->nickname );
+
+		// Check can update user with blank user_login (ignored).
+		$_POST['user_login'] = '';
+		$_POST['nickname'] = 'nickname_updated2';
+
+		$user_id = edit_user( $user_id );
+		$user = get_user_by( 'ID', $user_id );
+
+		$this->assertInternalType( 'int', $user_id );
+		$this->assertInstanceOf( 'WP_User', $user );
+		$this->assertEquals( 'user_login1', $user->user_login );
+		$this->assertEquals( 'nickname_updated2', $user->nickname );
+
+		// Check can update user with zero user_login (ignored).
+		$_POST['user_login'] = '0';
+		$_POST['nickname'] = 'nickname_updated3';
+
+		$user_id = edit_user( $user_id );
+		$user = get_user_by( 'ID', $user_id );
+
+		$this->assertInternalType( 'int', $user_id );
+		$this->assertInstanceOf( 'WP_User', $user );
+		$this->assertEquals( 'user_login1', $user->user_login );
+		$this->assertEquals( 'nickname_updated3', $user->nickname );
+	}
 }
Index: tests/qunit/fixtures/quicktags.js
===================================================================
Index: tests/qunit/wp-includes/js/quicktags.js
===================================================================
