diff --git a/core/modules/user/tests/modules/user_access_test/user_access_test.module b/core/modules/user/tests/modules/user_access_test/user_access_test.module
index a5cdb4b3f5..31e5e6cffe 100644
--- a/core/modules/user/tests/modules/user_access_test/user_access_test.module
+++ b/core/modules/user/tests/modules/user_access_test/user_access_test.module
@@ -2,7 +2,9 @@
 
 /**
  * @file
- * Dummy module implementing hook_user_access() to test if entity access is respected.
+ * Dummy module implementing hook_user_access() to test.
+ *
+ * If entity access is respected.
  */
 
 use Drupal\Core\Access\AccessResult;
@@ -15,6 +17,10 @@
  * Implements hook_ENTITY_TYPE_access() for entity type "user".
  */
 function user_access_test_user_access(User $entity, $operation, $account) {
+  if ($entity->getUsername() == "no_view" && $operation == "view") {
+    // Deny view access.
+    return AccessResult::forbidden();
+  }
   if ($entity->getAccountName() == "no_edit" && $operation == "update") {
     // Deny edit access.
     return AccessResult::forbidden();
@@ -50,7 +56,8 @@ function user_access_test_entity_create_access(AccountInterface $account, array
 function user_access_test_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
   // Account with role sub-admin can view the status, init and mail fields for
   // user with no roles.
-  if ($field_definition->getTargetEntityTypeId() == 'user' && $operation === 'view' && in_array($field_definition->getName(), ['status', 'init', 'mail'])) {
+  if ($field_definition->getTargetEntityTypeId() == 'user' && $operation === 'view' &&
+  in_array($field_definition->getName(), ['status', 'init', 'mail'])) {
     if (($items == NULL) || (count($items->getEntity()->getRoles()) == 1)) {
       return AccessResult::allowedIfHasPermission($account, 'sub-admin');
     }
diff --git a/core/modules/user/tests/src/Functional/UserAdminListingTest.php b/core/modules/user/tests/src/Functional/UserAdminListingTest.php
index e5d92a6f58..104eb8f7dd 100644
--- a/core/modules/user/tests/src/Functional/UserAdminListingTest.php
+++ b/core/modules/user/tests/src/Functional/UserAdminListingTest.php
@@ -71,7 +71,7 @@ public function testUserListing() {
     $result_accounts = [];
     foreach ($result as $account) {
       $account_columns = $account->findAll('css', 'td');
-      $name = $account_columns[0]->find('css', 'a')->getText();
+      $name = strip_tags($account->td[0]->asXML());
       $roles = [];
       $account_roles = $account_columns[2]->findAll('css', 'td ul li');
       if (!empty($account_roles)) {
diff --git a/core/modules/user/tests/src/Functional/UserAdminTest.php b/core/modules/user/tests/src/Functional/UserAdminTest.php
index 8fedf64f7c..8788d7bf01 100644
--- a/core/modules/user/tests/src/Functional/UserAdminTest.php
+++ b/core/modules/user/tests/src/Functional/UserAdminTest.php
@@ -90,12 +90,12 @@ public function testUserAdmin() {
     $this->drupalGet('admin/people', ['query' => ['user' => $user_a->getAccountName()]]);
     $result = $this->xpath('//table/tbody/tr');
     $this->assertCount(1, $result, 'Filter by username returned the right amount.');
-    $this->assertEquals($user_a->getAccountName(), $result[0]->find('xpath', '/td[2]/a')->getText(), 'Filter by username returned the right user.');
+    $this->assertEqual($user_a->getUsername(), trim(strip_tags($result[0]->td[1]->asXML())), 'Filter by username returned the right user.');
 
     $this->drupalGet('admin/people', ['query' => ['user' => $user_a->getEmail()]]);
     $result = $this->xpath('//table/tbody/tr');
     $this->assertCount(1, $result, 'Filter by username returned the right amount.');
-    $this->assertEquals($user_a->getAccountName(), $result[0]->find('xpath', '/td[2]/a')->getText(), 'Filter by username returned the right user.');
+    $this->assertEqual($user_a->getUsername(), trim(strip_tags($result[0]->td[1]->asXML())), 'Filter by username returned the right user.');
 
     // Filter the users by permission 'administer taxonomy'.
     $this->drupalGet('admin/people', ['query' => ['permission' => 'administer taxonomy']]);
@@ -127,8 +127,8 @@ public function testUserAdmin() {
     $this->drupalGet('admin/people', [
     // Sort the table by username so that we know reliably which user will be
     // targeted with the blocking action.
-    'query' => ['order' => 'name', 'sort' => 'asc'],
-]);
+      'query' => ['order' => 'name', 'sort' => 'asc'],
+    ]);
     $this->submitForm($edit, 'Apply to selected items');
     $site_name = $this->config('system.site')->get('name');
     $this->assertMailString('body', 'Your account on ' . $site_name . ' has been blocked.', 1, 'Blocked message found in the mail sent to user C.');
@@ -136,28 +136,30 @@ public function testUserAdmin() {
     $account = $user_storage->load($user_c->id());
     $this->assertTrue($account->isBlocked(), 'User C blocked');
 
-    // Test filtering on admin page for blocked users
+    // Test filtering on admin page for blocked users.
     $this->drupalGet('admin/people', ['query' => ['status' => 2]]);
     $this->assertSession()->elementNotExists('xpath', static::getLinkSelectorForUser($user_a));
     $this->assertSession()->elementNotExists('xpath', static::getLinkSelectorForUser($user_b));
     $this->assertSession()->elementExists('xpath', static::getLinkSelectorForUser($user_c));
 
-    // Test unblocking of a user from /admin/people page and sending of activation mail
+    // Test unblocking of a user from /admin/people page.
+    // And sending of activation mail.
     $editunblock = [];
     $editunblock['action'] = 'user_unblock_user_action';
     $editunblock['user_bulk_form[4]'] = TRUE;
     $this->drupalGet('admin/people', [
     // Sort the table by username so that we know reliably which user will be
     // targeted with the blocking action.
-    'query' => ['order' => 'name', 'sort' => 'asc'],
-]);
+      'query' => ['order' => 'name', 'sort' => 'asc'],
+    ]);
     $this->submitForm($editunblock, 'Apply to selected items');
     $user_storage->resetCache([$user_c->id()]);
     $account = $user_storage->load($user_c->id());
     $this->assertTrue($account->isActive(), 'User C unblocked');
     $this->assertMail("to", $account->getEmail(), "Activation mail sent to user C");
 
-    // Test blocking and unblocking another user from /user/[uid]/edit form and sending of activation mail
+    // Test blocking and unblocking another user from /user/[uid]/edit form.
+    // And sending of activation mail.
     $user_d = $this->drupalCreateUser([]);
     $user_storage->resetCache([$user_d->id()]);
     $account1 = $user_storage->load($user_d->id());
diff --git a/core/modules/user/tests/src/Kernel/UserTemplateTest.php b/core/modules/user/tests/src/Kernel/UserTemplateTest.php
new file mode 100644
index 0000000000..4285ae72e5
--- /dev/null
+++ b/core/modules/user/tests/src/Kernel/UserTemplateTest.php
@@ -0,0 +1,117 @@
+<?php
+
+namespace Drupal\Tests\user\Kernel;
+
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\Core\Session\AnonymousUserSession;
+use Drupal\user\Entity\User;
+
+/**
+ * Tests template output for user module.
+ *
+ * @group user
+ */
+class UserTemplateTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['user', 'user_access_test'];
+
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * The current user service.
+   *
+   * @var \Drupal\Core\Session\AccountProxy
+   */
+  protected $currentUser;
+
+  /**
+   * A user for testing.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  protected $user;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->installEntitySchema('user');
+    $this->renderer = $this->container->get('renderer');
+    $this->currentUser = $this->container->get('current_user');
+    $this->user = User::create([
+      'uid' => 2,
+      'name' => $this->randomMachineName(),
+    ]);
+  }
+
+  /**
+   * Tests user can see a link to own profile.
+   */
+  public function testUsernameTemplateSelfUserLink() {
+    $this->user->save();
+    $this->currentUser->setAccount($this->user);
+    $url = $this->user->toUrl();
+
+    $build = [
+      '#theme' => 'username',
+      '#account' => $this->user,
+    ];
+    $this->setRawContent($this->renderer->renderRoot($build));
+
+    $element = $this->xpath('//a[@href=:url]', [':url' => $url->toString()]);
+    $this->assertTrue(!empty($element), 'Account can view link to its own profile.');
+  }
+
+  /**
+   * Tests user cannot see link to own profile when explicitly denied.
+   */
+  public function testUsernameTemplateSelfNoUserLink() {
+    $this->user
+      // 'no_view' username forces access denied.
+      ->setUsername('no_view')
+      ->save();
+
+    $this->currentUser->setAccount($this->user);
+    $url = $this->user->toUrl();
+
+    $build = [
+      '#theme' => 'username',
+      '#account' => $this->user,
+    ];
+    $this->setRawContent($this->renderer->renderRoot($build));
+
+    $element = $this->xpath('//a[@href=:url]', [':url' => $url->toString()]);
+    $this->assertTrue(empty($element), 'Account cannot view link to profile.');
+  }
+
+  /**
+   * Tests user cannot see link to if it has no permissions.
+   *
+   * Tests an account without the "View user information" permission.
+   */
+  public function testUsernameTemplateNoPermissionNoUserLink() {
+    $this->currentUser->setAccount(new AnonymousUserSession());
+
+    $this->user->save();
+    $url = $this->user->toUrl();
+
+    $build = [
+      '#theme' => 'username',
+      '#account' => $this->user,
+    ];
+    $this->setRawContent($this->renderer->renderRoot($build));
+
+    $element = $this->xpath('//a[@href=:url]', [':url' => $url->toString()]);
+    $this->assertTrue(empty($element), 'Account without permissions cannot view link to user profile.');
+  }
+
+}
