diff --git a/core/modules/user/src/Tests/UserAdminLanguageTest.php b/core/modules/user/tests/src/Functional/UserAdminLanguageTest.php similarity index 78% rename from core/modules/user/src/Tests/UserAdminLanguageTest.php rename to core/modules/user/tests/src/Functional/UserAdminLanguageTest.php index cd6cc657bf..27432b7310 100644 --- a/core/modules/user/src/Tests/UserAdminLanguageTest.php +++ b/core/modules/user/tests/src/Functional/UserAdminLanguageTest.php @@ -1,16 +1,16 @@ adminUser->id() . '/edit'; $this->drupalGet($path); // Ensure administration pages language settings widget is not available. - $this->assertNoFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector not available.'); + self::assertFalse($this->getSession()->getPage()->findField('edit-preferred-admin-langcode')); } /** @@ -64,13 +64,13 @@ public function testUserAdminLanguageConfigurationAvailableWithAdminLanguageNego // Checks with user administration pages language negotiation disabled. $this->drupalGet($path); // Ensure administration pages language settings widget is not available. - $this->assertNoFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector not available.'); + self::assertFalse($this->getSession()->getPage()->findField( 'edit-preferred-admin-langcode')); // Checks with user administration pages language negotiation enabled. $this->setLanguageNegotiation(); $this->drupalGet($path); // Ensure administration pages language settings widget is available. - $this->assertFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector is available.'); + self::assertTrue($this->getSession()->getPage()->findField( 'edit-preferred-admin-langcode')); } /** @@ -91,19 +91,20 @@ public function testUserAdminLanguageConfigurationAvailableIfAdminLanguageNegoti $path = 'user/' . $this->adminUser->id() . '/edit'; $this->drupalGet($path); // Ensure administration pages language setting is visible for admin. - $this->assertFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector available for admins.'); + self::assertTrue($this->getSession()->getPage()->findField( 'edit-preferred-admin-langcode')); // Ensure administration pages language setting is hidden for non-admins. $this->drupalLogin($this->regularUser); $path = 'user/' . $this->regularUser->id() . '/edit'; $this->drupalGet($path); - $this->assertNoFieldByXPath($this->constructFieldXpath('id', 'edit-preferred-admin-langcode'), NULL, 'Administration pages language selector not available for regular user.'); + self::assertFalse($this->getSession()->getPage()->findField('edit-preferred-admin-langcode')); } /** * Tests the actual language negotiation. */ public function testActualNegotiation() { + $web_assert = $this->assertSession(); $this->drupalLogin($this->adminUser); $this->addCustomLanguage(); $this->setLanguageNegotiation(); @@ -112,9 +113,9 @@ public function testActualNegotiation() { // no preference set, negotiation will fall back further. $path = 'user/' . $this->adminUser->id() . '/edit'; $this->drupalGet($path); - $this->assertText('Language negotiation method: language-default'); + $web_assert->pageTextContains('Language negotiation method: language-default'); $this->drupalGet('xx/' . $path); - $this->assertText('Language negotiation method: language-url'); + $web_assert->pageTextContains('Language negotiation method: language-url'); // Set a preferred language code for the user. $edit = []; @@ -124,26 +125,26 @@ public function testActualNegotiation() { // Test negotiation with the URL method first. The admin method will only // be used if the URL method did not match. $this->drupalGet($path); - $this->assertText('Language negotiation method: language-user-admin'); + $web_assert->pageTextContains('Language negotiation method: language-user-admin'); $this->drupalGet('xx/' . $path); - $this->assertText('Language negotiation method: language-url'); + $web_assert->pageTextContains('Language negotiation method: language-url'); // Test negotiation with the admin language method first. The admin method // will be used at all times. $this->setLanguageNegotiation(TRUE); $this->drupalGet($path); - $this->assertText('Language negotiation method: language-user-admin'); + $web_assert->pageTextContains('Language negotiation method: language-user-admin'); $this->drupalGet('xx/' . $path); - $this->assertText('Language negotiation method: language-user-admin'); + $web_assert->pageTextContains('Language negotiation method: language-user-admin'); // Unset the preferred language code for the user. $edit = []; $edit['preferred_admin_langcode'] = ''; $this->drupalPostForm($path, $edit, t('Save')); $this->drupalGet($path); - $this->assertText('Language negotiation method: language-default'); + $web_assert->pageTextContains('Language negotiation method: language-default'); $this->drupalGet('xx/' . $path); - $this->assertText('Language negotiation method: language-url'); + $web_assert->pageTextContains('Language negotiation method: language-url'); } /** diff --git a/core/modules/user/src/Tests/UserBlocksTest.php b/core/modules/user/tests/src/Functional/UserBlocksTest.php similarity index 60% rename from core/modules/user/src/Tests/UserBlocksTest.php rename to core/modules/user/tests/src/Functional/UserBlocksTest.php index 0a4c619da6..1b9f553c40 100644 --- a/core/modules/user/src/Tests/UserBlocksTest.php +++ b/core/modules/user/tests/src/Functional/UserBlocksTest.php @@ -1,16 +1,17 @@ adminUser = $this->drupalCreateUser(['administer blocks']); $this->drupalLogin($this->adminUser); $this->drupalPlaceBlock('user_login_block'); - $this->drupalLogout($this->adminUser); + $this->drupalLogout(); } /** @@ -51,10 +52,10 @@ public function testUserLoginBlockVisibility() { $this->drupalGet($path); $elements = $this->xpath('//div[contains(@class,"block-user-login-block") and @role="form"]'); if ($expected_visibility) { - $this->assertTrue(!empty($elements), 'User login block in path "' . $path . '" should be visible'); + self::assertTrue(!empty($elements), 'User login block in path "' . $path . '" should be visible'); } else { - $this->assertTrue(empty($elements), 'User login block in path "' . $path . '" should not be visible'); + self::assertTrue(empty($elements), 'User login block in path "' . $path . '" should not be visible'); } } } @@ -63,6 +64,7 @@ public function testUserLoginBlockVisibility() { * Test the user login block. */ public function testUserLoginBlock() { + $web_assert = $this->assertSession(); // Create a user with some permission that anonymous users lack. $user = $this->drupalCreateUser(['administer permissions']); @@ -71,43 +73,43 @@ public function testUserLoginBlock() { $edit['name'] = $user->getUsername(); $edit['pass'] = $user->pass_raw; $this->drupalPostForm('admin/people/permissions', $edit, t('Log in')); - $this->assertNoText(t('User login'), 'Logged in.'); + $web_assert->pageTextNotContains(t('User login')); // Check that we are still on the same page. - $this->assertUrl(\Drupal::url('user.admin_permissions', [], ['absolute' => TRUE]), [], 'Still on the same page after login for access denied page'); + $web_assert->addressEquals(Url::fromRoute('user.admin_permissions')); // Now, log out and repeat with a non-403 page. $this->drupalLogout(); $this->drupalGet('filter/tips'); - $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); + self::assertEquals('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); $this->drupalPostForm(NULL, $edit, t('Log in')); - $this->assertNoText(t('User login'), 'Logged in.'); - $this->assertPattern('!!', 'Still on the same page after login for allowed page'); + $web_assert->pageTextNotContains(t('User login')); + $web_assert->responseMatches('!!'); // Log out again and repeat with a non-403 page including query arguments. $this->drupalLogout(); $this->drupalGet('filter/tips', ['query' => ['foo' => 'bar']]); - $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); + self::assertEquals('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); $this->drupalPostForm(NULL, $edit, t('Log in')); - $this->assertNoText(t('User login'), 'Logged in.'); - $this->assertPattern('!!', 'Still on the same page after login for allowed page'); - $this->assertTrue(strpos($this->getUrl(), '/filter/tips?foo=bar') !== FALSE, 'Correct query arguments are displayed after login'); + $web_assert->pageTextNotContains(t('User login')); + $web_assert->responseMatches('!!'); + self::assertTrue(strpos($this->getUrl(), '/filter/tips?foo=bar') !== FALSE, 'Correct query arguments are displayed after login'); // Repeat with different query arguments. $this->drupalLogout(); $this->drupalGet('filter/tips', ['query' => ['foo' => 'baz']]); - $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); + self::assertEquals('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER)); $this->drupalPostForm(NULL, $edit, t('Log in')); - $this->assertNoText(t('User login'), 'Logged in.'); - $this->assertPattern('!!', 'Still on the same page after login for allowed page'); - $this->assertTrue(strpos($this->getUrl(), '/filter/tips?foo=baz') !== FALSE, 'Correct query arguments are displayed after login'); + $web_assert->pageTextNotContains(t('User login')); + $web_assert->responseMatches('!!'); + self::assertTrue(strpos($this->getUrl(), '/filter/tips?foo=baz') !== FALSE); // Check that the user login block is not vulnerable to information // disclosure to third party sites. $this->drupalLogout(); $this->drupalPostForm('http://example.com/', $edit, t('Log in'), ['external' => FALSE]); // Check that we remain on the site after login. - $this->assertUrl($user->url('canonical', ['absolute' => TRUE]), [], 'Redirected to user profile page after login from the frontpage'); + $web_assert->addressEquals($user->url('canonical', ['absolute' => TRUE])); // Verify that form validation errors are displayed immediately for forms // in blocks and not on subsequent page requests. @@ -116,16 +118,16 @@ public function testUserLoginBlock() { $edit['name'] = 'foo'; $edit['pass'] = 'invalid password'; $this->drupalPostForm('filter/tips', $edit, t('Log in')); - $this->assertText(t('Unrecognized username or password. Forgot your password?')); + $web_assert->pageTextContains(t('Unrecognized username or password. Forgot your password?')); $this->drupalGet('filter/tips'); - $this->assertNoText(t('Unrecognized username or password. Forgot your password?')); + $web_assert->pageTextNotContains(t('Unrecognized username or password. Forgot your password?')); } /** * Test the Who's Online block. */ public function testWhosOnlineBlock() { - $block = $this->drupalPlaceBlock('views_block:who_s_online-who_s_online_block'); + $web_assert = $this->assertSession(); // Generate users. $user1 = $this->drupalCreateUser(['access user profiles']); @@ -144,13 +146,12 @@ public function testWhosOnlineBlock() { // Test block output. \Drupal::currentUser()->setAccount($user1); - $content = entity_view($block, 'block'); - $this->setRawContent(\Drupal::service('renderer')->renderRoot($content)); - $this->assertRaw(t('2 users'), 'Correct number of online users (2 users).'); - $this->assertText($user1->getUsername(), 'Active user 1 found in online list.'); - $this->assertText($user2->getUsername(), 'Active user 2 found in online list.'); - $this->assertNoText($user3->getUsername(), 'Inactive user not found in online list.'); - $this->assertTrue(strpos($this->getRawContent(), $user1->getUsername()) > strpos($this->getRawContent(), $user2->getUsername()), 'Online users are ordered correctly.'); + $this->drupalPlaceBlock('views_block:who_s_online-who_s_online_block'); + $web_assert->responseContains(t('2 users')); + $web_assert->pageTextContains($user1->getUsername()); + $web_assert->pageTextContains($user2->getUsername()); + $web_assert->pageTextNotContains($user3->getUsername()); + self::assertTrue(strpos($this->getSession()->getPage()->getContent(), $user1->getUsername()) > strpos($this->getSession()->getPage()->getContent(), $user2->getUsername()), 'Online users are ordered correctly.'); } /** diff --git a/core/modules/user/src/Tests/UserCreateTest.php b/core/modules/user/tests/src/Functional/UserCreateTest.php similarity index 66% rename from core/modules/user/src/Tests/UserCreateTest.php rename to core/modules/user/tests/src/Functional/UserCreateTest.php index 7b534435a0..afc2c26345 100644 --- a/core/modules/user/src/Tests/UserCreateTest.php +++ b/core/modules/user/tests/src/Functional/UserCreateTest.php @@ -1,18 +1,22 @@ assertSession(); $user = $this->drupalCreateUser(['administer users']); $this->drupalLogin($user); - $this->assertEqual($user->getCreatedTime(), REQUEST_TIME, 'Creating a user sets default "created" timestamp.'); - $this->assertEqual($user->getChangedTime(), REQUEST_TIME, 'Creating a user sets default "changed" timestamp.'); + self::assertEquals($user->getCreatedTime(), REQUEST_TIME, 'Creating a user sets default "created" timestamp.'); + self::assertEquals($user->getChangedTime(), REQUEST_TIME, 'Creating a user sets default "changed" timestamp.'); // Create a field. $field_name = 'test_field'; @@ -66,23 +71,23 @@ public function testUserAdd() { // Test user creation page for valid fields. $this->drupalGet('admin/people/create'); - $this->assertFieldbyId('edit-status-0', 0, 'The user status option Blocked exists.', 'User login'); - $this->assertFieldbyId('edit-status-1', 1, 'The user status option Active exists.', 'User login'); - $this->assertFieldByXPath('//input[@type="radio" and @id="edit-status-1" and @checked="checked"]', NULL, 'Default setting for user status is active.'); + $web_assert->fieldValueEquals('edit-status-0', 0); + $web_assert->fieldValueEquals('edit-status-1', 1); + self::assertTrue($this->xpath('//input[@type="radio" and @id="edit-status-1" and @checked="checked"]'), 'Default setting for user status is active.'); // Test that browser autocomplete behavior does not occur. - $this->assertNoRaw('data-user-info-from-browser', 'Ensure form attribute, data-user-info-from-browser, does not exist.'); + $web_assert->responseNotContains('data-user-info-from-browser'); // Test that the password strength indicator displays. $config = $this->config('user.settings'); $config->set('password_strength', TRUE)->save(); $this->drupalGet('admin/people/create'); - $this->assertRaw(t('Password strength:'), 'The password strength indicator is displayed.'); + $web_assert->pageTextContains(t('Password strength:')); $config->set('password_strength', FALSE)->save(); $this->drupalGet('admin/people/create'); - $this->assertNoRaw(t('Password strength:'), 'The password strength indicator is not displayed.'); + $web_assert->pageTextNotContains(t('Password strength:')); // We create two users, notifying one and not notifying the other, to // ensure that the tests work in both cases. @@ -98,18 +103,18 @@ public function testUserAdd() { $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); if ($notify) { - $this->assertText(t('A welcome message with further instructions has been emailed to the new user @name.', ['@name' => $edit['name']]), 'User created'); - $this->assertEqual(count($this->drupalGetMails()), 1, 'Notification email sent'); + $web_assert->pageTextContains(t('A welcome message with further instructions has been emailed to the new user @name.', ['@name' => $edit['name']])); + self::assertEquals(count($this->drupalGetMails()), 1, 'Notification email sent'); } else { - $this->assertText(t('Created a new user account for @name. No email has been sent.', ['@name' => $edit['name']]), 'User created'); - $this->assertEqual(count($this->drupalGetMails()), 0, 'Notification email not sent'); + $web_assert->pageTextContains(t('Created a new user account for @name. No email has been sent.', ['@name' => $edit['name']])); + self::assertEquals(count($this->drupalGetMails()), 0, 'Notification email not sent'); } $this->drupalGet('admin/people'); - $this->assertText($edit['name'], 'User found in list of users'); + $web_assert->pageTextContains($edit['name']); $user = user_load_by_name($name); - $this->assertEqual($user->isActive(), 'User is not blocked'); + self::assertEquals($user->isActive(), 'User is not blocked'); } // Test that the password '0' is considered a password. @@ -123,8 +128,8 @@ public function testUserAdd() { 'notify' => FALSE, ]; $this->drupalPostForm('admin/people/create', $edit, t('Create new account')); - $this->assertText("Created a new user account for $name. No email has been sent"); - $this->assertNoText('Password field is required'); + $web_assert->pageTextContains("Created a new user account for $name. No email has been sent"); + $web_assert->pageTextNotContains('Password field is required'); } } diff --git a/core/modules/user/src/Tests/UserPasswordResetTest.php b/core/modules/user/tests/src/Functional/UserPasswordResetTest.php similarity index 70% rename from core/modules/user/src/Tests/UserPasswordResetTest.php rename to core/modules/user/tests/src/Functional/UserPasswordResetTest.php index 528d38bc96..877eed9409 100644 --- a/core/modules/user/src/Tests/UserPasswordResetTest.php +++ b/core/modules/user/tests/src/Functional/UserPasswordResetTest.php @@ -1,11 +1,13 @@ login = REQUEST_TIME - mt_rand(10, 100000); + $account->login = \Drupal::time()->getRequestTime() - mt_rand(10, 100000); db_update('users_field_data') ->fields(['login' => $account->getLastLoginTime()]) ->condition('uid', $account->id()) @@ -70,10 +79,11 @@ protected function setUp() { * Tests password reset functionality. */ public function testUserPasswordReset() { + $web_assert = $this->assertSession(); // Verify that accessing the password reset form without having the session // variables set results in an access denied message. $this->drupalGet(Url::fromRoute('user.reset.form', ['uid' => $this->account->id()])); - $this->assertResponse(403); + $web_assert->statusCodeEquals(403); // Try to reset the password for an invalid account. $this->drupalGet('user/password'); @@ -81,11 +91,11 @@ public function testUserPasswordReset() { $edit = ['name' => $this->randomMachineName(32)]; $this->drupalPostForm(NULL, $edit, t('Submit')); - $this->assertText(t('@name is not recognized as a username or an email address.', ['@name' => $edit['name']]), 'Validation error message shown when trying to request password for invalid account.'); - $this->assertEqual(count($this->drupalGetMails(['id' => 'user_password_reset'])), 0, 'No email was sent when requesting a password for an invalid account.'); + $web_assert->pageTextContains(t('@name is not recognized as a username or an email address.', ['@name' => $edit['name']])); + self::assertEquals(count($this->drupalGetMails(['id' => 'user_password_reset'])),0,'No email was sent when requesting a password for an invalid account.'); // Reset the password by username via the password reset page. - $edit['name'] = $this->account->getUsername(); + $edit['name'] = $this->account->getDisplayName(); $this->drupalPostForm(NULL, $edit, t('Submit')); // Verify that the user was sent an email. @@ -98,21 +108,21 @@ public function testUserPasswordReset() { // Ensure that the current url does not contain the hash and timestamp. $this->assertUrl(Url::fromRoute('user.reset.form', ['uid' => $this->account->id()])); - $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache')); + self::assertFalse($this->drupalGetHeader('X-Drupal-Cache')); // Ensure the password reset URL is not cached. $this->drupalGet($resetURL); - $this->assertFalse($this->drupalGetHeader('X-Drupal-Cache')); + self::assertFalse($this->drupalGetHeader('X-Drupal-Cache')); // Check the one-time login page. - $this->assertText($this->account->getUsername(), 'One-time login page contains the correct username.'); - $this->assertText(t('This login can be used only once.'), 'Found warning about one-time login.'); - $this->assertTitle(t('Reset password | Drupal'), 'Page title is "Reset password".'); + $web_assert->pageTextContains($this->account->getDisplayName()); + $web_assert->pageTextContains(t('This login can be used only once.')); + $web_assert->pageTextContains(t('Reset password | Drupal')); // Check successful login. $this->drupalPostForm(NULL, NULL, t('Log in')); - $this->assertLink(t('Log out')); - $this->assertTitle(t('@name | @site', ['@name' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name')]), 'Logged in using password reset link.'); + $web_assert->linkExists(t('Log out')); + $web_assert->titleEquals($this->account->getDisplayName() . ' | ' . $this->config('system.site')->get('name')); // Make sure the ajax request from uploading a user picture does not // invalidate the reset token. @@ -120,23 +130,23 @@ public function testUserPasswordReset() { $edit = [ 'files[user_picture_0]' => drupal_realpath($image->uri), ]; - $this->drupalPostAjaxForm(NULL, $edit, 'user_picture_0_upload_button'); + $this->drupalPostForm(NULL, $edit, 'user_picture_0_upload_button'); // Change the forgotten password. $password = user_password(); $edit = ['pass[pass1]' => $password, 'pass[pass2]' => $password]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText(t('The changes have been saved.'), 'Forgotten password changed.'); + $web_assert->pageTextContains(t('The changes have been saved.')); // Verify that the password reset session has been destroyed. $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText(t('Your current password is missing or incorrect; it\'s required to change the Password.'), 'Password needed to make profile changes.'); + $web_assert->pageTextContains(t('Your current password is missing or incorrect; it\'s required to change the Password.')); // Log out, and try to log in again using the same one-time link. $this->drupalLogout(); $this->drupalGet($resetURL); $this->drupalPostForm(NULL, NULL, t('Log in')); - $this->assertText(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'One-time link is no longer valid.'); + $web_assert->pageTextContains(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.')); // Request a new password again, this time using the email address. $this->drupalGet('user/password'); @@ -144,7 +154,7 @@ public function testUserPasswordReset() { $before = count($this->drupalGetMails(['id' => 'user_password_reset'])); $edit = ['name' => $this->account->getEmail()]; $this->drupalPostForm(NULL, $edit, t('Submit')); - $this->assertTrue( count($this->drupalGetMails(['id' => 'user_password_reset'])) === $before + 1, 'Email sent when requesting password reset using email address.'); + self::assertTrue( count($this->drupalGetMails(['id' => 'user_password_reset'])) === $before + 1, 'Email sent when requesting password reset using email address.'); // Visit the user edit page without pass-reset-token and make sure it does // not cause an error. @@ -157,18 +167,18 @@ public function testUserPasswordReset() { // Create a password reset link as if the request time was 60 seconds older than the allowed limit. $timeout = $this->config('user.settings')->get('password_reset_timeout'); - $bogus_timestamp = REQUEST_TIME - $timeout - 60; + $bogus_timestamp = \Drupal::time()->getRequestTime() - $timeout - 60; $_uid = $this->account->id(); $this->drupalGet("user/reset/$_uid/$bogus_timestamp/" . user_pass_rehash($this->account, $bogus_timestamp)); $this->drupalPostForm(NULL, NULL, t('Log in')); - $this->assertText(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.'), 'Expired password reset request rejected.'); + $web_assert->pageTextContains(t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.')); // Create a user, block the account, and verify that a login link is denied. - $timestamp = REQUEST_TIME - 1; + $timestamp = \Drupal::time()->getRequestTime() - 1; $blocked_account = $this->drupalCreateUser()->block(); $blocked_account->save(); $this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account, $timestamp)); - $this->assertResponse(403); + $web_assert->statusCodeEquals(403); // Verify a blocked user can not request a new password. $this->drupalGet('user/password'); @@ -176,8 +186,8 @@ public function testUserPasswordReset() { $before = count($this->drupalGetMails(['id' => 'user_password_reset'])); $edit = ['name' => $blocked_account->getUsername()]; $this->drupalPostForm(NULL, $edit, t('Submit')); - $this->assertRaw(t('%name is blocked or has not been activated yet.', ['%name' => $blocked_account->getUsername()]), 'Notified user blocked accounts can not request a new password'); - $this->assertTrue(count($this->drupalGetMails(['id' => 'user_password_reset'])) === $before, 'No email was sent when requesting password reset for a blocked account'); + $web_assert->responseContains(t('%name is blocked or has not been activated yet.', ['%name' => $blocked_account->getUsername()])); + self::assertTrue(count($this->drupalGetMails(['id' => 'user_password_reset'])) === $before, 'No email was sent when requesting password reset for a blocked account'); // Verify a password reset link is invalidated when the user's email address changes. $this->drupalGet('user/password'); @@ -188,7 +198,7 @@ public function testUserPasswordReset() { $this->account->save(); $this->drupalGet($old_email_reset_link); $this->drupalPostForm(NULL, NULL, t('Log in')); - $this->assertText(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'), 'One-time link is no longer valid.'); + $web_assert->pageTextContains(t('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.')); // Verify a password reset link will automatically log a user when /login is // appended. @@ -197,21 +207,21 @@ public function testUserPasswordReset() { $this->drupalPostForm(NULL, $edit, t('Submit')); $reset_url = $this->getResetURL(); $this->drupalGet($reset_url . '/login'); - $this->assertLink(t('Log out')); - $this->assertTitle(t('@name | @site', ['@name' => $this->account->getUsername(), '@site' => $this->config('system.site')->get('name')]), 'Logged in using password reset link.'); + $web_assert->linkExists(t('Log out')); + $web_assert->titleEquals($this->account->getDisplayName() . ' | ' . $this->config('system.site')->get('name')); // Ensure blocked and deleted accounts can't access the user.reset.login // route. $this->drupalLogout(); - $timestamp = REQUEST_TIME - 1; + $timestamp = \Drupal::time()->getRequestTime() - 1; $blocked_account = $this->drupalCreateUser()->block(); $blocked_account->save(); $this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account, $timestamp) . '/login'); - $this->assertResponse(403); + $web_assert->statusCodeEquals(403); $blocked_account->delete(); $this->drupalGet("user/reset/" . $blocked_account->id() . "/$timestamp/" . user_pass_rehash($blocked_account, $timestamp) . '/login'); - $this->assertResponse(403); + $web_assert->statusCodeEquals(403); } /** @@ -231,6 +241,7 @@ public function getResetURL() { * Test user password reset while logged in. */ public function testUserPasswordResetLoggedIn() { + $web_assert = $this->assertSession(); $another_account = $this->drupalCreateUser(); $this->drupalLogin($another_account); $this->drupalGet('user/password'); @@ -241,14 +252,11 @@ public function testUserPasswordResetLoggedIn() { // Log in as a different user. $this->drupalLogin($this->account); $this->drupalGet($resetURL); - $this->assertRaw(new FormattableMarkup( - 'Another user (%other_user) is already logged into the site on this computer, but you tried to use a one-time link for user %resetting_user. Please log out and try using the link again.', - ['%other_user' => $this->account->getUsername(), '%resetting_user' => $another_account->getUsername(), ':logout' => Url::fromRoute('user.logout')->toString()] - )); + $web_assert->responseContains('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'); $another_account->delete(); $this->drupalGet($resetURL); - $this->assertText('The one-time login link you clicked is invalid.'); + $web_assert->pageTextContains('The one-time login link you clicked is invalid.'); // Log in. $this->drupalLogin($this->account); @@ -266,41 +274,43 @@ public function testUserPasswordResetLoggedIn() { $password = user_password(); $edit = ['pass[pass1]' => $password, 'pass[pass2]' => $password]; $this->drupalPostForm(NULL, $edit, t('Save')); - $this->assertText(t('The changes have been saved.'), 'Password changed.'); + $web_assert->pageTextContains(t('The changes have been saved.')); // Logged in users should not be able to access the user.reset.login or the // user.reset.form routes. - $timestamp = REQUEST_TIME - 1; + $timestamp = \Drupal::time()->getRequestTime() - 1; $this->drupalGet("user/reset/" . $this->account->id() . "/$timestamp/" . user_pass_rehash($this->account, $timestamp) . '/login'); - $this->assertResponse(403); + $web_assert->statusCodeEquals(403); $this->drupalGet("user/reset/" . $this->account->id()); - $this->assertResponse(403); + $web_assert->statusCodeEquals(403); } /** * Prefill the text box on incorrect login via link to password reset page. */ public function testUserResetPasswordTextboxFilled() { + $web_assert = $this->assertSession(); $this->drupalGet('user/login'); $edit = [ 'name' => $this->randomMachineName(), 'pass' => $this->randomMachineName(), ]; $this->drupalPostForm('user/login', $edit, t('Log in')); - $this->assertRaw(t('Unrecognized username or password. Forgot your password?', + $web_assert->responseContains(t('Unrecognized username or password. Forgot your password?', [':password' => \Drupal::url('user.pass', [], ['query' => ['name' => $edit['name']]])])); unset($edit['pass']); $this->drupalGet('user/password', ['query' => ['name' => $edit['name']]]); - $this->assertFieldByName('name', $edit['name'], 'User name found.'); + $web_assert->fieldValueEquals('name', $edit['name']); // Ensure the name field value is not cached. $this->drupalGet('user/password'); - $this->assertNoFieldByName('name', $edit['name'], 'User name not found.'); + $web_assert->fieldValueNotEquals('name', $edit['name']); } /** * Make sure that users cannot forge password reset URLs of other users. */ public function testResetImpersonation() { + $web_assert = $this->assertSession(); // Create two identical user accounts except for the user name. They must // have the same empty password, so we can't use $this->drupalCreateUser(). $edit = []; @@ -332,9 +342,9 @@ public function testResetImpersonation() { $attack_reset_url = str_replace("user/reset/{$user1->id()}", "user/reset/{$user2->id()}", $reset_url); $this->drupalGet($attack_reset_url); $this->drupalPostForm(NULL, NULL, t('Log in')); - $this->assertNoText($user2->getUsername(), 'The invalid password reset page does not show the user name.'); - $this->assertUrl('user/password', [], 'The user is redirected to the password reset request page.'); - $this->assertText('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'); + $web_assert->pageTextNotContains($user2->getUsername()); + $web_assert->addressEquals('user/password'); + $web_assert->pageTextContains('You have tried to use a one-time login link that has either been used or is no longer valid. Please request a new one using the form below.'); } } diff --git a/core/modules/user/src/Tests/UserRegistrationTest.php b/core/modules/user/tests/src/Functional/UserRegistrationTest.php similarity index 69% rename from core/modules/user/src/Tests/UserRegistrationTest.php rename to core/modules/user/tests/src/Functional/UserRegistrationTest.php index ca7a4f0c89..2e1ae4b24d 100644 --- a/core/modules/user/src/Tests/UserRegistrationTest.php +++ b/core/modules/user/tests/src/Functional/UserRegistrationTest.php @@ -1,20 +1,19 @@ assertSession(); $config = $this->config('user.settings'); // Require email verification. $config->set('verify_mail', TRUE)->save(); @@ -31,7 +31,7 @@ public function testRegistrationWithEmailVerification() { // Set registration to administrator only. $config->set('register', USER_REGISTER_ADMINISTRATORS_ONLY)->save(); $this->drupalGet('user/register'); - $this->assertResponse(403, 'Registration page is inaccessible when only administrators can create accounts.'); + $web_assert->statusCodeEquals(403); // Allow registration by site visitors without administrator approval. $config->set('register', USER_REGISTER_VISITORS)->save(); @@ -39,16 +39,16 @@ public function testRegistrationWithEmailVerification() { $edit['name'] = $name = $this->randomMachineName(); $edit['mail'] = $mail = $edit['name'] . '@example.com'; $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertText(t('A welcome message with further instructions has been sent to your email address.'), 'User registered successfully.'); + $web_assert->pageTextContains(t('A welcome message with further instructions has been sent to your email address.')); /** @var EntityStorageInterface $storage */ $storage = $this->container->get('entity_type.manager')->getStorage('user'); $accounts = $storage->loadByProperties(['name' => $name, 'mail' => $mail]); $new_user = reset($accounts); - $this->assertTrue($new_user->isActive(), 'New account is active after registration.'); + self::assertTrue($new_user->isActive(), 'New account is active after registration.'); $resetURL = user_pass_reset_url($new_user); $this->drupalGet($resetURL); - $this->assertTitle(t('Set password | Drupal'), 'Page title is "Set password".'); + $web_assert->titleEquals('Set password | Drupal'); // Allow registration by site visitors, but require administrator approval. $config->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(); @@ -59,10 +59,11 @@ public function testRegistrationWithEmailVerification() { $this->container->get('entity.manager')->getStorage('user')->resetCache(); $accounts = $storage->loadByProperties(['name' => $name, 'mail' => $mail]); $new_user = reset($accounts); - $this->assertFalse($new_user->isActive(), 'New account is blocked until approved by an administrator.'); + self::assertFalse($new_user->isActive(), 'New account is blocked until approved by an administrator.'); } public function testRegistrationWithoutEmailVerification() { + $web_assert = $this->assertSession(); $config = $this->config('user.settings'); // Don't require email verification and allow registration by site visitors // without administrator approval. @@ -79,7 +80,7 @@ public function testRegistrationWithoutEmailVerification() { $edit['pass[pass1]'] = '99999.0'; $edit['pass[pass2]'] = '99999'; $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertText(t('The specified passwords do not match.'), 'Typing mismatched passwords displays an error message.'); + $web_assert->pageTextContains(t('The specified passwords do not match.')); // Enter a correct password. $edit['pass[pass1]'] = $new_pass = $this->randomMachineName(); @@ -90,7 +91,7 @@ public function testRegistrationWithoutEmailVerification() { ->loadByProperties(['name' => $name, 'mail' => $mail]); $new_user = reset($accounts); $this->assertNotNull($new_user, 'New account successfully created with matching passwords.'); - $this->assertText(t('Registration successful. You are now logged in.'), 'Users are logged in after registering.'); + $web_assert->pageTextContains(t('Registration successful. You are now logged in.')); $this->drupalLogout(); // Allow registration by site visitors, but require administrator approval. @@ -101,7 +102,7 @@ public function testRegistrationWithoutEmailVerification() { $edit['pass[pass1]'] = $pass = $this->randomMachineName(); $edit['pass[pass2]'] = $pass; $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertText(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.'), 'Users are notified of pending approval'); + $web_assert->pageTextContains(t('Thank you for applying for an account. Your account is currently pending approval by the site administrator.')); // Try to log in before administrator approval. $auth = [ @@ -109,7 +110,7 @@ public function testRegistrationWithoutEmailVerification() { 'pass' => $pass, ]; $this->drupalPostForm('user/login', $auth, t('Log in')); - $this->assertText(t('The username @name has not been activated or is blocked.', ['@name' => $name]), 'User cannot log in yet.'); + $web_assert->pageTextContains(t('The username @name has not been activated or is blocked.', ['@name' => $name])); // Activate the new account. $accounts = $this->container->get('entity_type.manager')->getStorage('user') @@ -125,10 +126,11 @@ public function testRegistrationWithoutEmailVerification() { // Log in after administrator approval. $this->drupalPostForm('user/login', $auth, t('Log in')); - $this->assertText(t('Member for'), 'User can log in after administrator approval.'); + $web_assert->pageTextContains(t('Member for')); } public function testRegistrationEmailDuplicates() { + $web_assert = $this->assertSession(); // Don't require email verification and allow registration by site visitors // without administrator approval. $this->config('user.settings') @@ -145,13 +147,13 @@ public function testRegistrationEmailDuplicates() { // Attempt to create a new account using an existing email address. $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertText(t('The email address @email is already taken.', ['@email' => $duplicate_user->getEmail()]), 'Supplying an exact duplicate email address displays an error message'); + $web_assert->pageTextContains(t('The email address @email is already taken.', ['@email' => $duplicate_user->getEmail()])); // Attempt to bypass duplicate email registration validation by adding spaces. $edit['mail'] = ' ' . $duplicate_user->getEmail() . ' '; $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertText(t('The email address @email is already taken.', ['@email' => $duplicate_user->getEmail()]), 'Supplying a duplicate email address with added whitespace displays an error message'); + $web_assert->pageTextContains(t('The email address @email is already taken.', ['@email' => $duplicate_user->getEmail()])); } /** @@ -161,6 +163,7 @@ public function testRegistrationEmailDuplicates() { * that the form is not cached on GET requests. */ public function testUuidFormState() { + $web_assert = $this->assertSession(); \Drupal::service('module_installer')->install(['image']); \Drupal::service('router.builder')->rebuild(); @@ -205,11 +208,11 @@ public function testUuidFormState() { // Create one account. $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertResponse(200); + $web_assert->statusCodeEquals(200); $user_storage = \Drupal::entityManager()->getStorage('user'); - $this->assertTrue($user_storage->loadByProperties(['name' => $edit['name']])); + self::assertTrue($user_storage->loadByProperties(['name' => $edit['name']])); $this->drupalLogout(); // Create a second account. @@ -218,9 +221,9 @@ public function testUuidFormState() { $edit['pass[pass2]'] = $edit['pass[pass1]'] = $this->randomMachineName(); $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertResponse(200); + $web_assert->statusCodeEquals(200); - $this->assertTrue($user_storage->loadByProperties(['name' => $edit['name']])); + self::assertTrue($user_storage->loadByProperties(['name' => $edit['name']])); } public function testRegistrationDefaultValues() { @@ -239,7 +242,7 @@ public function testRegistrationDefaultValues() { // Check the presence of expected cache tags. $this->drupalGet('user/register'); - $this->assertCacheTag('config:user.settings'); + $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', 'config:user.settings'); $edit = []; $edit['name'] = $name = $this->randomMachineName(); @@ -252,14 +255,14 @@ public function testRegistrationDefaultValues() { $accounts = $this->container->get('entity_type.manager')->getStorage('user') ->loadByProperties(['name' => $name, 'mail' => $mail]); $new_user = reset($accounts); - $this->assertEqual($new_user->getUsername(), $name, 'Username matches.'); - $this->assertEqual($new_user->getEmail(), $mail, 'Email address matches.'); - $this->assertTrue(($new_user->getCreatedTime() > REQUEST_TIME - 20 ), 'Correct creation time.'); - $this->assertEqual($new_user->isActive(), $config_user_settings->get('register') == USER_REGISTER_VISITORS ? 1 : 0, 'Correct status field.'); - $this->assertEqual($new_user->getTimezone(), $config_system_date->get('timezone.default'), 'Correct time zone field.'); - $this->assertEqual($new_user->langcode->value, \Drupal::languageManager()->getDefaultLanguage()->getId(), 'Correct language field.'); - $this->assertEqual($new_user->preferred_langcode->value, \Drupal::languageManager()->getDefaultLanguage()->getId(), 'Correct preferred language field.'); - $this->assertEqual($new_user->init->value, $mail, 'Correct init field.'); + self::assertEquals($new_user->getUsername(), $name, 'Username matches.'); + self::assertEquals($new_user->getEmail(), $mail, 'Email address matches.'); + self::assertTrue(($new_user->getCreatedTime() > REQUEST_TIME - 20 ), 'Correct creation time.'); + self::assertEquals($new_user->isActive(), $config_user_settings->get('register') == USER_REGISTER_VISITORS ? 1 : 0, 'Correct status field.'); + self::assertEquals($new_user->getTimezone(), $config_system_date->get('timezone.default'), 'Correct time zone field.'); + self::assertEquals($new_user->langcode->value, \Drupal::languageManager()->getDefaultLanguage()->getId(), 'Correct language field.'); + self::assertEquals($new_user->preferred_langcode->value, \Drupal::languageManager()->getDefaultLanguage()->getId(), 'Correct preferred language field.'); + self::assertEquals($new_user->init->value, $mail, 'Correct init field.'); } /** @@ -269,21 +272,23 @@ public function testRegistrationDefaultValues() { * @see \Drupal\user\Plugin\Validation\Constraint\UserMailUnique */ public function testUniqueFields() { + $web_assert = $this->assertSession(); $account = $this->drupalCreateUser(); $edit = ['mail' => 'test@example.com', 'name' => $account->getUsername()]; $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertRaw(SafeMarkup::format('The username %value is already taken.', ['%value' => $account->getUsername()])); + $web_assert->responseContains(t('The username %value is already taken.', ['%value' => $account->getUsername()])); $edit = ['mail' => $account->getEmail(), 'name' => $this->randomString()]; $this->drupalPostForm('user/register', $edit, t('Create new account')); - $this->assertRaw(SafeMarkup::format('The email address %value is already taken.', ['%value' => $account->getEmail()])); + $web_assert->responseContains(t('The email address %value is already taken.', ['%value' => $account->getEmail()])); } /** * Tests Field API fields on user registration forms. */ public function testRegistrationWithUserFields() { + $web_assert = $this->assertSession(); // Create a field on 'user' entity type. $field_storage = FieldStorageConfig::create([ 'field_name' => 'test_user_field', @@ -307,17 +312,16 @@ public function testRegistrationWithUserFields() { // Check that the field does not appear on the registration form. $this->drupalGet('user/register'); - $this->assertNoText($field->label(), 'The field does not appear on user registration form'); - $this->assertCacheTag('config:core.entity_form_display.user.user.register'); - $this->assertCacheTag('config:user.settings'); - + $web_assert->pageTextNotContains($field->label()); + $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', 'config:core.entity_form_display.user.user.register'); + $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', 'config:user.settings'); // Have the field appear on the registration form. entity_get_form_display('user', 'user', 'register') ->setComponent('test_user_field', ['type' => 'test_field_widget']) ->save(); $this->drupalGet('user/register'); - $this->assertText($field->label(), 'The field appears on user registration form'); + $web_assert->pageTextContains($field->label()); $this->assertRegistrationFormCacheTagsWithUserFields(); // Check that validation errors are correctly reported. @@ -328,65 +332,57 @@ public function testRegistrationWithUserFields() { $edit['test_user_field[0][value]'] = ''; $this->drupalPostForm(NULL, $edit, t('Create new account')); $this->assertRegistrationFormCacheTagsWithUserFields(); - $this->assertRaw(t('@name field is required.', ['@name' => $field->label()]), 'Field validation error was correctly reported.'); + $web_assert->responseContains(t('@name field is required.', ['@name' => $field->label()])); // Invalid input. $edit['test_user_field[0][value]'] = '-1'; $this->drupalPostForm(NULL, $edit, t('Create new account')); $this->assertRegistrationFormCacheTagsWithUserFields(); - $this->assertRaw(t('%name does not accept the value -1.', ['%name' => $field->label()]), 'Field validation error was correctly reported.'); + $web_assert->responseContains(t('%name does not accept the value -1.', ['%name' => $field->label()])); // Submit with valid data. - $value = rand(1, 255); + $value = random_int(1, 255); $edit['test_user_field[0][value]'] = $value; $this->drupalPostForm(NULL, $edit, t('Create new account')); // Check user fields. $accounts = $this->container->get('entity_type.manager')->getStorage('user') ->loadByProperties(['name' => $name, 'mail' => $mail]); $new_user = reset($accounts); - $this->assertEqual($new_user->test_user_field->value, $value, 'The field value was correctly saved.'); + self::assertEquals($new_user->test_user_field->value, $value, 'The field value was correctly saved.'); // Check that the 'add more' button works. $field_storage->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED); $field_storage->save(); - foreach (['js', 'nojs'] as $js) { - $this->drupalGet('user/register'); - $this->assertRegistrationFormCacheTagsWithUserFields(); - // Add two inputs. - $value = rand(1, 255); - $edit = []; - $edit['test_user_field[0][value]'] = $value; - if ($js == 'js') { - $this->drupalPostAjaxForm(NULL, $edit, 'test_user_field_add_more'); - $this->drupalPostAjaxForm(NULL, $edit, 'test_user_field_add_more'); - } - else { - $this->drupalPostForm(NULL, $edit, t('Add another item')); - $this->drupalPostForm(NULL, $edit, t('Add another item')); - } - // Submit with three values. - $edit['test_user_field[1][value]'] = $value + 1; - $edit['test_user_field[2][value]'] = $value + 2; - $edit['name'] = $name = $this->randomMachineName(); - $edit['mail'] = $mail = $edit['name'] . '@example.com'; - $this->drupalPostForm(NULL, $edit, t('Create new account')); - // Check user fields. - $accounts = $this->container->get('entity_type.manager')->getStorage('user') - ->loadByProperties(['name' => $name, 'mail' => $mail]); - $new_user = reset($accounts); - $this->assertEqual($new_user->test_user_field[0]->value, $value, format_string('@js : The field value was correctly saved.', ['@js' => $js])); - $this->assertEqual($new_user->test_user_field[1]->value, $value + 1, format_string('@js : The field value was correctly saved.', ['@js' => $js])); - $this->assertEqual($new_user->test_user_field[2]->value, $value + 2, format_string('@js : The field value was correctly saved.', ['@js' => $js])); - } + $this->drupalGet('user/register'); + $this->assertRegistrationFormCacheTagsWithUserFields(); + // Add two inputs. + $value = random_int(1, 255); + $edit = []; + $edit['test_user_field[0][value]'] = $value; + $this->drupalPostForm(NULL, $edit, t('Add another item')); + $this->drupalPostForm(NULL, $edit, t('Add another item')); + // Submit with three values. + $edit['test_user_field[1][value]'] = $value + 1; + $edit['test_user_field[2][value]'] = $value + 2; + $edit['name'] = $name = $this->randomMachineName(); + $edit['mail'] = $mail = $edit['name'] . '@example.com'; + $this->drupalPostForm(NULL, $edit, t('Create new account')); + // Check user fields. + $accounts = $this->container->get('entity_type.manager')->getStorage('user') + ->loadByProperties(['name' => $name, 'mail' => $mail]); + $new_user = reset($accounts); + self::assertEquals($new_user->test_user_field[0]->value, $value, t('The field value was correctly saved.')); + self::assertEquals($new_user->test_user_field[1]->value, $value + 1, t('The field value was correctly saved.')); + self::assertEquals($new_user->test_user_field[2]->value, $value + 2, t('The field value was correctly saved.')); } /** * Asserts the presence of cache tags on registration form with user fields. */ protected function assertRegistrationFormCacheTagsWithUserFields() { - $this->assertCacheTag('config:core.entity_form_display.user.user.register'); - $this->assertCacheTag('config:field.field.user.user.test_user_field'); - $this->assertCacheTag('config:field.storage.user.test_user_field'); - $this->assertCacheTag('config:user.settings'); + $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', 'config:core.entity_form_display.user.user.register'); + $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', 'config:field.field.user.user.test_user_field'); + $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', 'config:field.storage.user.test_user_field'); + $this->assertSession()->responseHeaderContains('X-Drupal-Cache-Tags', 'config:user.settings'); } }