diff --git a/src/ProfileAccessControlHandler.php b/src/ProfileAccessControlHandler.php
index 570003b..2d253b1 100644
--- a/src/ProfileAccessControlHandler.php
+++ b/src/ProfileAccessControlHandler.php
@@ -19,15 +19,36 @@ class ProfileAccessControlHandler extends EntityAccessControlHandler {
   /**
    * {@inheritdoc}
    */
-  public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE) {
-    $account = $this->prepareUser($account);
+  public function access(EntityInterface $entity, $operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
+    $this->prepareUser($account);
 
-    if ($account->hasPermission('bypass profile access')) {
+    if ($account == null) {
+      var_dump($account);
+      var_dump(debug_backtrace());
+    }
+
+    if ($account->hasPermission("bypass {$this->entityTypeId} access")) {
       $result = AccessResult::allowed()->cachePerPermissions();
       return $return_as_object ? $result : $result->isAllowed();
     }
 
+    $result = parent::access($entity, $operation, $account, TRUE)->cachePerPermissions();
+    return $return_as_object ? $result : $result->isAllowed();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE) {
+    $this->prepareUser($account);
+    if ($account->hasPermission("bypass {$this->entityTypeId} access")) {
+      $result = AccessResult::allowed()->cachePerPermissions();
+      return $return_as_object ? $result : $result->isAllowed();
+    }
+
+    /** @var \Drupal\Core\Access\AccessResult $result */
     $result = parent::createAccess($entity_bundle, $account, $context, TRUE)->cachePerPermissions();
+
     return $return_as_object ? $result : $result->isAllowed();
   }
 
@@ -38,75 +59,78 @@ class ProfileAccessControlHandler extends EntityAccessControlHandler {
    * otherwise $entity is of type 'profile'.
    */
   protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
+    /** @var \Drupal\profile\Entity\ProfileInterface $entity */
     $account = $this->prepareUser($account);
 
-    $user_page = \Drupal::request()->attributes->get('user');
+    if ($account->hasPermission("bypass {$this->entityTypeId} access")) {
+      $result = AccessResult::allowed()->cachePerPermissions();
+      return $result;
+    }
+
+    $own_permission = "$operation own {$entity->bundle()} {$entity->getEntityTypeId()}";
+    $any_permission = "$operation any {$entity->bundle()} {$entity->getEntityTypeId()}";
 
     // Some times, operation edit is called update.
     // Use edit in any case.
     if ($operation == 'update') {
       $operation = 'edit';
     }
+    elseif ($operation == 'create') {
+      $operation = 'add';
+    }
+
+    /** @var \Drupal\Core\Access\AccessResult $result */
+    $result = parent::checkAccess($entity, $operation, $account);
 
-    // Check that if profile type has require roles, the user the profile is
-    // being added to has any of the required roles.
-    if ($entity->getEntityTypeId() == 'profile') {
-      $profile_roles = ProfileType::load($entity->bundle())->getRoles();
-      // Retrieve all user roles including locked roles.
-      $user_roles = $entity->getOwner()->getRoles();
-      if (!empty(array_filter($profile_roles)) && !array_intersect($user_roles, $profile_roles)) {
-        return AccessResult::forbidden();
+    if ($result->isNeutral()) {
+      if (($account->id() == $entity->getOwnerId())) {
+        $result = AccessResult::allowedIfHasPermission($account, $own_permission);
+        if ($result->isNeutral()) {
+          // Check if user has "any" permission, still.
+          // Users may provide only "any" permission not just "own".
+          $result = AccessResult::allowedIfHasPermission($account, $any_permission);
+        }
       }
-    }
-    elseif ($entity->getEntityTypeId() == 'profile_type') {
-      $profile_roles = $entity->getRoles();
-      // Retrieve all user roles including locked roles.
-      $user_roles = User::load($user_page->id())->getRoles();
-      if (!empty(array_filter($profile_roles)) && !array_intersect($user_roles, $profile_roles)) {
-        return AccessResult::forbidden();
+      else {
+        $result = AccessResult::allowedIfHasPermission($account, $any_permission);
       }
     }
 
-    if ($account->hasPermission('bypass profile access')) {
-      return AccessResult::allowed()->cachePerPermissions();
-    }
-    elseif (
-      (
-        $operation == 'add'
-        && (
-          (
-            $user_page->id() == $account->id()
-            && $account->hasPermission($operation . ' own ' . $entity->id() . ' profile')
-          )
-          || $account->hasPermission($operation . ' any ' . $entity->id() . ' profile')
-        )
-      ) || (
-        $operation != 'add'
-        && (
-          (
-            $entity->getOwnerId() == $account->id()
-            && $account->hasPermission($operation . ' own ' . $entity->getType() . ' profile')
-          )
-          || $account->hasPermission($operation . ' any ' . $entity->getType() . ' profile')
-        )
-      )
-    ){
-      return AccessResult::allowed()->cachePerPermissions();
-    }
-    else {
-      // No opinion.
-      return AccessResult::neutral()->cachePerPermissions();
+    // If access is allowed, check role restriction.
+    if ($result->isAllowed()) {
+      $bundle = ProfileType::load($entity->bundle());
+      if (!empty(array_filter($bundle->getRoles()))) {
+        $result = AccessResult::allowedIf(!empty(array_intersect($account->getRoles(), $bundle->getRoles())));
+      }
     }
+
+    $result->cachePerUser()->addCacheableDependency($entity);
+
+    return $result;
   }
 
   /**
    * {@inheritdoc}
    */
   protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
-    return AccessResult::allowedIfHasPermissions($account, [
-      'add any ' . $entity_bundle . ' profile',
-      'add own ' . $entity_bundle . ' profile',
-    ], 'OR');
+    $result = parent::checkCreateAccess($account, $context, $entity_bundle);
+
+    if ($result->isNeutral()) {
+      $result = AccessResult::allowedIfHasPermissions($account, [
+        'add any ' . $entity_bundle . ' ' . $this->entityTypeId,
+        'add own ' . $entity_bundle . ' ' . $this->entityTypeId,
+      ], 'OR');
+    }
+
+    // If access is allowed, check role restriction.
+    if ($result->isAllowed()) {
+      $bundle = ProfileType::load($entity_bundle);
+      if (!empty(array_filter($bundle->getRoles()))) {
+        $result = AccessResult::allowedIf(!empty(array_intersect($account->getRoles(), $bundle->getRoles())));
+      }
+    }
+
+    return $result;
   }
 
 }
diff --git a/src/Tests/ProfileRoleAccessTest.php b/src/Tests/ProfileRoleAccessTest.php
deleted file mode 100644
index 15b1a79..0000000
--- a/src/Tests/ProfileRoleAccessTest.php
+++ /dev/null
@@ -1,165 +0,0 @@
-<?php
-
-namespace Drupal\profile\Tests;
-
-use Drupal\Core\Session\AccountInterface;
-
-/**
- * Tests profile role access handling.
- *
- * @group profile
- */
-class ProfileRoleAccessTest extends ProfileTestBase {
-
-  /**
-   * Randomly generated profile type entity.
-   *
-   * Requires some, but not all roles.
-   *
-   * @var \Drupal\profile\Entity\ProfileType
-   */
-  protected $type2;
-
-  /**
-   * Randomly generated profile type entity.
-   *
-   * Requires all profile roles.
-   *
-   * @var \Drupal\profile\Entity\ProfileType
-   */
-  protected $type3;
-
-  /**
-   * Randomly generated user role entity.
-   *
-   * @var \Drupal\user\Entity\Role
-   */
-  protected $role1;
-
-  /**
-   * Randomly generated user role entity.
-   *
-   * @var \Drupal\user\Entity\Role
-   */
-  protected $role2;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->role1 = $this->drupalCreateRole([]);
-    $this->role2 = $this->drupalCreateRole([]);
-    $this->type2 = $this->createProfileType(NULL, NULL, FALSE, [$this->role2]);
-    $this->type3 = $this->createProfileType(NULL, NULL, FALSE, [$this->role1, $this->role2]);
-  }
-
-  /**
-   * Tests add profile form access for a profile type that does not require
-   * users to have a role.
-   */
-  public function testProfileWithNoRoles() {
-    // Create user with add own profile permissions.
-    $web_user1 = $this->drupalCreateUser(["add own {$this->type->id()} profile"]);
-    $this->drupalLogin($web_user1);
-
-    // Test user without role can access add profile form.
-    // Expected: User can access form.
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type->id()}");
-    $this->assertResponse(200);
-  }
-
-  public function testLockedRoles() {
-    $locked_role_type = $this->createProfileType(NULL, NULL, FALSE, [AccountInterface::AUTHENTICATED_ROLE]);
-
-    // Create user with add own profile permissions.
-    $web_user1 = $this->drupalCreateUser(["add own {$locked_role_type->id()} profile"]);
-    $this->drupalLogin($web_user1);
-
-    // Test user without role can access add profile form.
-    // Expected: User can access form.
-    $this->drupalGet("user/{$web_user1->id()}/{$locked_role_type->id()}");
-    $this->assertResponse(200);
-  }
-
-  /**
-   * Tests add profile form access for a profile type that requires users to
-   * have a single role.
-   */
-  public function testProfileWithSingleRole() {
-    // Create user with add own profile permissions.
-    $web_user1 = $this->drupalCreateUser(["add own {$this->type2->id()} profile"]);
-    $this->drupalLogin($web_user1);
-
-    // Test user without role can access add profile form.
-    // Expected: User cannot access form.
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type2->id()}");
-    $this->assertResponse(403);
-
-    // Test user with wrong role can access add profile form.
-    // Expected: User cannot access form.
-    $web_user1->addRole($this->role1);
-    $web_user1->save();
-
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type2->id()}");
-    $this->assertResponse(403);
-
-    // Test user with correct role can access add profile form.
-    // Expected: User can access form.
-    $web_user1->removeRole($this->role1);
-    $web_user1->addRole($this->role2);
-    $web_user1->save();
-
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type2->id()}");
-    $this->assertResponse(200);
-  }
-
-  /**
-   * Tests add profile form access for a profile type that requires users to
-   * have one of multiple roles.
-   */
-  public function testProfileWithAllRoles() {
-    // Create user with add own profile permissions.
-    $web_user1 = $this->drupalCreateUser(["add own {$this->type3->id()} profile"]);
-    $this->drupalLogin($web_user1);
-
-    // Test user without role can access add profile form.
-    // Expected: User cannot access form.
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type3->id()}");
-    $this->assertResponse(403);
-
-    // Test user with role 1 can access add profile form.
-    // Expected: User can access form.
-    $web_user1->addRole($this->role1);
-    $web_user1->save();
-
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type3->id()}");
-    $this->assertResponse(200);
-
-    // Test user with both roles can access add profile form.
-    // Expected: User can access form.
-    $web_user1->addRole($this->role2);
-    $web_user1->save();
-
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type3->id()}");
-    $this->assertResponse(200);
-
-    // Test user with role 2 can access add profile form.
-    // Expected: User can access form.
-    $web_user1->removeRole($this->role1);
-    $web_user1->save();
-
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type3->id()}");
-    $this->assertResponse(200);
-
-    // Test user without role can access add profile form.
-    // Expected: User cannot access form.
-    $web_user1->removeRole($this->role2);
-    $web_user1->save();
-
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type3->id()}");
-    $this->assertResponse(403);
-  }
-
-}
diff --git a/src/Tests/ProfileTabTest.php b/src/Tests/ProfileTabTest.php
deleted file mode 100644
index 637a179..0000000
--- a/src/Tests/ProfileTabTest.php
+++ /dev/null
@@ -1,135 +0,0 @@
-<?php
-
-namespace Drupal\profile\Tests;
-
-use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Core\Url;
-use Drupal\profile\Entity\Profile;
-use Drupal\profile\Entity\ProfileType;
-use Drupal\user\Entity\User;
-
-/**
- * Tests tab functionality of profiles.
- *
- * @group profile
- */
-class ProfileTabTest extends ProfileTestBase {
-
-  public static $modules = ['profile', 'field_ui', 'text', 'block'];
-
-  /**
-   * Testing demo user 1.
-   *
-   * @var \Drupal\user\UserInterface
-   */
-  public $user1;
-
-  /**
-   * Testing demo user 2.
-   *
-   * @var \Drupal\user\UserInterface;
-   */
-  public $user2;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->adminUser = $this->drupalCreateUser([
-      'access user profiles',
-      'administer profiles',
-      'administer profile types',
-      'bypass profile access',
-      'access administration pages',
-    ]);
-  }
-
-  /**
-   * Tests tabs in profile UI.
-   */
-  public function testProfileTabs() {
-    $types_data = [
-      'profile_type_0' => ['label' => $this->randomMachineName()],
-      'profile_type_1' => ['label' => $this->randomMachineName()],
-    ];
-
-    /** @var ProfileType[] $types */
-    $types = [];
-    foreach ($types_data as $id => $values) {
-      $types[$id] = ProfileType::create(['id' => $id] + $values);
-      $types[$id]->save();
-    }
-    $this->container->get('router.builder')->rebuild();
-
-    $this->user1 = User::create([
-      'name' => $this->randomMachineName(),
-      'mail' => $this->randomMachineName() . '@example.com',
-    ]);
-    $this->user1->save();
-    $this->user2 = User::create([
-      'name' => $this->randomMachineName(),
-      'mail' => $this->randomMachineName() . '@example.com',
-    ]);
-    $this->user2->save();
-
-    // Create new profiles.
-    $profile1 = Profile::create($expected = [
-      'type' => $types['profile_type_0']->id(),
-      'uid' => $this->user1->id(),
-    ]);
-    $profile1->save();
-    $profile2 = Profile::create($expected = [
-      'type' => $types['profile_type_1']->id(),
-      'uid' => $this->user2->id(),
-    ]);
-    $profile2->save();
-
-    $this->drupalLogin($this->adminUser);
-
-    $this->drupalGet('admin/config');
-    $this->clickLink('User profiles');
-    $this->assertResponse(200);
-    $this->assertUrl('admin/config/people/profiles');
-
-    $this->assertLink($profile1->label());
-    $this->assertLinkByHref($profile2->toUrl('canonical')->toString());
-
-    $tasks = [
-      ['entity.profile.collection', []],
-      ['entity.profile_type.collection', []],
-    ];
-
-    $this->assertLocalTasks($tasks, 0);
-  }
-
-  /**
-   * Asserts local tasks in the page output.
-   *
-   * @param array $routes
-   *   A list of expected local tasks, prepared as an array of route names and
-   *   their associated route parameters, to assert on the page (in the given
-   *   order).
-   * @param int $level
-   *   (optional) The local tasks level to assert; 0 for primary, 1 for
-   *   secondary. Defaults to 0.
-   */
-  protected function assertLocalTasks(array $routes, $level = 0) {
-    $elements = $this->xpath('//*[contains(@class, :class)]//a', array(
-      ':class' => $level == 0 ? 'tabs primary' : 'tabs secondary',
-    ));
-    $this->assertTrue(count($elements), 'Local tasks found.');
-    foreach ($routes as $index => $route_info) {
-      list($route_name, $route_parameters) = $route_info;
-      $expected = Url::fromRoute($route_name, $route_parameters)->toString();
-      $method = ($elements[$index]['href'] == $expected ? 'pass' : 'fail');
-      $this->{$method}(new FormattableMarkup('Task @number href @value equals @expected.', [
-        '@number' => $index + 1,
-        '@value' => (string) $elements[$index]['href'],
-        '@expected' => $expected,
-      ]));
-    }
-  }
-
-}
diff --git a/src/Tests/ProfileTestBase.php b/src/Tests/ProfileTestBase.php
deleted file mode 100644
index 3a91f99..0000000
--- a/src/Tests/ProfileTestBase.php
+++ /dev/null
@@ -1,139 +0,0 @@
-<?php
-
-namespace Drupal\profile\Tests;
-
-use Drupal\Core\Entity\Entity\EntityFormDisplay;
-use Drupal\Core\Entity\Entity\EntityViewDisplay;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\field\Entity\FieldConfig;
-use Drupal\field\Entity\FieldStorageConfig;
-use Drupal\profile\ProfileTestTrait;
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Tests profile access handling.
- */
-abstract class ProfileTestBase extends WebTestBase {
-
-  use ProfileTestTrait;
-
-  public static $modules = ['profile', 'field_ui', 'text', 'block'];
-
-  /**
-   * Testing profile type entity.
-   *
-   * @var \Drupal\profile\Entity\ProfileType
-   */
-  protected $type;
-
-  /**
-   * Testing profile type entity view display.
-   *
-   * @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
-   */
-  protected $display;
-
-  /**
-   * Testing profile type entity form display.
-   *
-   * @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form
-   */
-  protected $form;
-
-  /**
-   * Testing field on profile type.
-   *
-   * @var \Drupal\Core\Field\FieldConfigInterface
-   */
-  protected $field;
-
-  /**
-   * Testing admin user.
-   *
-   * @var \Drupal\user\Entity\User
-   */
-  protected $adminUser;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->drupalPlaceBlock('local_tasks_block');
-    $this->drupalPlaceBlock('local_actions_block');
-    $this->drupalPlaceBlock('page_title_block');
-
-    $this->type = $this->createProfileType('test', 'Test profile', TRUE);
-
-    $id = $this->type->id();
-
-    $field_storage = FieldStorageConfig::create([
-      'field_name' => 'profile_fullname',
-      'entity_type' => 'profile',
-      'type' => 'text',
-    ]);
-    $field_storage->save();
-
-    $this->field = FieldConfig::create([
-      'field_storage' => $field_storage,
-      'bundle' => $this->type->id(),
-      'label' => 'Full name',
-    ]);
-    $this->field->save();
-
-    // Configure the default display.
-    $this->display = EntityViewDisplay::load("profile.{$this->type->id()}.default");
-    if (!$this->display) {
-      $this->display = EntityViewDisplay::create([
-        'targetEntityType' => 'profile',
-        'bundle' => $this->type->id(),
-        'mode' => 'default',
-        'status' => TRUE,
-      ]);
-      $this->display->save();
-    }
-    $this->display
-      ->setComponent($this->field->getName(), ['type' => 'string'])
-      ->save();
-
-    // Configure rhe default form.
-    $this->form = EntityFormDisplay::load("profile.{$this->type->id()}.default");
-    if (!$this->form) {
-      $this->form = EntityFormDisplay::create([
-        'targetEntityType' => 'profile',
-        'bundle' => $this->type->id(),
-        'mode' => 'default',
-        'status' => TRUE,
-      ]);
-      $this->form->save();
-    }
-    $this->form
-      ->setComponent($this->field->getName(), [
-        'type' => 'string_textfield',
-      ])->save();
-
-    $this->checkPermissions([
-      'administer profile types',
-      "view own $id profile",
-      "view any $id profile",
-      "add own $id profile",
-      "add any $id profile",
-      "edit own $id profile",
-      "edit any $id profile",
-      "delete own $id profile",
-      "delete any $id profile",
-    ]);
-
-    user_role_grant_permissions(AccountInterface::AUTHENTICATED_ROLE, ['access user profiles']);
-    $this->adminUser = $this->drupalCreateUser([
-      'administer profile types',
-      'administer profiles',
-      "view any $id profile",
-      "add any $id profile",
-      "edit any $id profile",
-      "delete any $id profile",
-    ]);
-  }
-
-}
diff --git a/src/Tests/ProfileTypeCRUDTest.php b/src/Tests/ProfileTypeCRUDTest.php
deleted file mode 100644
index 3e40b4d..0000000
--- a/src/Tests/ProfileTypeCRUDTest.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-
-namespace Drupal\profile\Tests;
-
-use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Component\Utility\Unicode;
-
-/**
- * Tests basic CRUD functionality of profile types.
- *
- * @group profile
- */
-class ProfileTypeCRUDTest extends ProfileTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->adminUser = $this->drupalCreateUser([
-      'access user profiles',
-      'administer profile types',
-      'administer profile fields',
-      'administer profile display',
-      'bypass profile access',
-    ]);
-  }
-
-  /**
-   * Verify that routes are created for the profile type.
-   */
-  public function testRoutes() {
-    $this->drupalLogin($this->adminUser);
-    $type = $this->createProfileType($this->randomMachineName());
-    \Drupal::service('router.builder')->rebuildIfNeeded();
-    $this->drupalGet("user/{$this->adminUser->id()}/{$type->id()}");
-    $this->assertResponse(200);
-  }
-
-  /**
-   * Tests CRUD operations for profile types through the UI.
-   */
-  public function testCRUDUI() {
-    $this->drupalLogin($this->adminUser);
-
-    // Create a new profile type.
-    $this->drupalGet('admin/config/people/profiles/types');
-    $this->assertResponse(200);
-    $this->clickLink(t('Add profile type'));
-
-    $this->assertUrl('admin/config/people/profiles/types/add');
-    $id = Unicode::strtolower($this->randomMachineName());
-    $label = $this->randomString();
-    $edit = [
-      'id' => $id,
-      'label' => $label,
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Save'));
-    $this->assertUrl('admin/config/people/profiles/types');
-    $this->assertRaw(new FormattableMarkup('%label profile type has been created.', ['%label' => $label]));
-    $this->assertLinkByHref("admin/config/people/profiles/types/manage/$id");
-    $this->assertLinkByHref("admin/config/people/profiles/types/manage/$id/fields");
-    $this->assertLinkByHref("admin/config/people/profiles/types/manage/$id/display");
-    $this->assertLinkByHref("admin/config/people/profiles/types/manage/$id/delete");
-
-    // Edit the new profile type.
-    $this->drupalGet("admin/config/people/profiles/types/manage/$id");
-    $this->assertRaw(new FormattableMarkup('Edit %label profile type', ['%label' => $label]));
-    $edit = [
-      'registration' => 1,
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Save'));
-    $this->assertUrl('admin/config/people/profiles/types');
-    $this->assertRaw(new FormattableMarkup('%label profile type has been updated.', ['%label' => $label]));
-
-    \Drupal::service('entity_type.bundle.info')->clearCachedBundles();
-
-    // Add a field to the profile type.
-    $this->drupalGet("admin/config/people/profiles/types/manage/$id/fields/add-field");
-    $field_name = Unicode::strtolower($this->randomMachineName());
-    $field_label = $this->randomString();
-    $edit = [
-      'new_storage_type' => 'string',
-      'label' => $field_label,
-      'field_name' => $field_name,
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Save and continue'));
-    $this->drupalPostForm(NULL, [], t('Save field settings'));
-    $this->drupalPostForm(NULL, [], t('Save settings'));
-    $this->assertRaw(new FormattableMarkup('Saved %label configuration.', ['%label' => $field_label]));
-
-    // Verify that the field is still associated with it.
-    $this->drupalGet("admin/config/people/profiles/types/manage/$id/fields");
-    // @todo D8 core: This assertion fails for an unknown reason. Database
-    //   contains the right values, so field_attach_rename_bundle() works
-    //   correctly. The pre-existing field does not appear on the Manage
-    //   fields page of the renamed bundle. Not even flushing all caches
-    //   helps. Can be reproduced manually.
-    // $this->assertText(check_plain($field_label));
-  }
-
-}
diff --git a/src/Tests/ProfileTypeMultipleTest.php b/src/Tests/ProfileTypeMultipleTest.php
deleted file mode 100644
index c21a1d3..0000000
--- a/src/Tests/ProfileTypeMultipleTest.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-
-namespace Drupal\profile\Tests;
-
-use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Core\Cache\Cache;
-
-/**
- * Tests multiple enabled profile types.
- *
- * @group profile
- */
-class ProfileTypeMultipleTest extends ProfileTestBase {
-
-  /**
-   * Tests the flow of a profile type that has multiple enabled.
-   */
-  public function testMultipleProfileType() {
-    $this->drupalLogin($this->adminUser);
-
-    $edit = [
-      'multiple' => 1,
-    ];
-    $this->drupalPostForm("admin/config/people/profiles/types/manage/{$this->type->id()}", $edit, t('Save'));
-    $this->assertRaw(new FormattableMarkup('%type profile type has been updated.', [
-      '%type' => $this->type->label(),
-    ]));
-
-    $web_user1 = $this->drupalCreateUser(
-      [
-        "view own {$this->type->id()} profile",
-        "add own {$this->type->id()} profile",
-        "edit own {$this->type->id()} profile",
-      ]
-    );
-    $this->drupalLogin($web_user1);
-    $value = $this->randomMachineName();
-
-    $edit = [
-      "{$this->field->getName()}[0][value]" => $value,
-    ];
-    $this->drupalPostForm("user/{$web_user1->id()}/{$this->type->id()}", $edit, t('Save'));
-    $this->assertRaw(new FormattableMarkup('%type profile has been created.', [
-      '%type' => $this->type->label(),
-    ]));
-
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type->id()}");
-    $this->assertLinkByHref("user/{$web_user1->id()}/{$this->type->id()}/add");
-    $this->assertText($value);
-
-    $value2 = $this->randomMachineName();
-    $edit = [
-      "{$this->field->getName()}[0][value]" => $value2,
-    ];
-    $this->drupalPostForm("user/{$web_user1->id()}/{$this->type->id()}/add", $edit, t('Save'));
-    $this->assertRaw(new FormattableMarkup('%type profile has been created.', [
-      '%type' => $this->type->label(),
-    ]));
-
-    Cache::invalidateTags(['profile_view']);
-
-    $this->drupalGet("user/{$web_user1->id()}/{$this->type->id()}");
-    $this->assertText($value2);
-  }
-
-  /**
-   * Tests the non-multiple profile type create and edit flow.
-   */
-  public function testProfileNotMultipleFlow() {
-    $web_user1 = $this->createUser([
-      "add own {$this->type->id()} profile",
-      "edit own {$this->type->id()} profile",
-    ]);
-    $this->drupalLogin($web_user1);
-
-    // Create the profile.
-    $edit = [
-      "{$this->field->getName()}[0][value]" => $this->randomString(),
-    ];
-    $this->drupalPostForm("user/{$web_user1->id()}/{$this->type->id()}", $edit, 'Save and make default');
-    $this->assertRaw(new FormattableMarkup('%type profile has been created.', [
-      '%type' => $this->type->label(),
-    ]));
-
-    // Update the profile.
-    $edit = [
-      "{$this->field->getName()}[0][value]" => $this->randomString(),
-    ];
-    $this->drupalPostForm("user/{$web_user1->id()}/{$this->type->id()}", $edit, t('Save'));
-    $this->assertRaw(new FormattableMarkup('%type profile has been updated.', [
-      '%type' => $this->type->label(),
-    ]));
-  }
-
-}
diff --git a/tests/src/Functional/ProfileDefaultTest.php b/tests/src/Functional/ProfileDefaultTest.php
index 2596fb8..1cc55f4 100644
--- a/tests/src/Functional/ProfileDefaultTest.php
+++ b/tests/src/Functional/ProfileDefaultTest.php
@@ -98,8 +98,8 @@ class ProfileDefaultTest extends ProfileTestBase {
     $this->assertTrue($profile2->isDefault());
 
     $this->drupalLogin($admin_user);
-
-    $this->drupalPostForm("profile/{$profile1->id()}/edit", [], 'Save and make default');
+    $this->drupalGet($profile1->toUrl('edit-form')->toString());
+    $this->submitForm([], 'Save and make default');
 
     \Drupal::entityTypeManager()->getStorage('profile')->resetCache([$profile1->id(), $profile2->id()]);
     $this->assertTrue(Profile::load($profile1->id())->isDefault());
diff --git a/tests/src/Functional/ProfileTabTest.php b/tests/src/Functional/ProfileTabTest.php
new file mode 100644
index 0000000..688aac5
--- /dev/null
+++ b/tests/src/Functional/ProfileTabTest.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace Drupal\Tests\profile\Functional;
+
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Core\Url;
+use Drupal\profile\Entity\Profile;
+use Drupal\profile\Entity\ProfileType;
+use Drupal\user\Entity\User;
+
+/**
+ * Tests tab functionality of profiles.
+ *
+ * @group profile
+ */
+class ProfileTabTest extends ProfileTestBase {
+
+  public static $modules = ['profile', 'field_ui', 'text', 'block'];
+
+  /**
+   * Testing demo user 1.
+   *
+   * @var \Drupal\user\UserInterface
+   */
+  public $user1;
+
+  /**
+   * Testing demo user 2.
+   *
+   * @var \Drupal\user\UserInterface;
+   */
+  public $user2;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->adminUser = $this->drupalCreateUser([
+      'access user profiles',
+      'administer profiles',
+      'administer profile types',
+      'bypass profile access',
+      'access administration pages',
+    ]);
+  }
+
+  /**
+   * Tests tabs in profile UI.
+   */
+  public function testProfileTabs() {
+    $types_data = [
+      'profile_type_0' => ['label' => $this->randomMachineName()],
+      'profile_type_1' => ['label' => $this->randomMachineName()],
+    ];
+
+    /** @var ProfileType[] $types */
+    $types = [];
+    foreach ($types_data as $id => $values) {
+      $types[$id] = ProfileType::create(['id' => $id] + $values);
+      $types[$id]->save();
+    }
+    $this->container->get('router.builder')->rebuild();
+
+    $this->user1 = User::create([
+      'name' => $this->randomMachineName(),
+      'mail' => $this->randomMachineName() . '@example.com',
+    ]);
+    $this->user1->save();
+    $this->user2 = User::create([
+      'name' => $this->randomMachineName(),
+      'mail' => $this->randomMachineName() . '@example.com',
+    ]);
+    $this->user2->save();
+
+    // Create new profiles.
+    $profile1 = Profile::create($expected = [
+      'type' => $types['profile_type_0']->id(),
+      'uid' => $this->user1->id(),
+    ]);
+    $profile1->save();
+    $profile2 = Profile::create($expected = [
+      'type' => $types['profile_type_1']->id(),
+      'uid' => $this->user2->id(),
+    ]);
+    $profile2->save();
+
+    $this->drupalLogin($this->adminUser);
+
+    $this->drupalGet('admin/config');
+    $this->clickLink('User profiles');
+    $this->assertResponse(200);
+    $this->assertUrl('admin/config/people/profiles');
+
+    $this->assertLink($profile1->label());
+    $this->assertLinkByHref($profile2->toUrl('canonical')->toString());
+
+    $tasks = [
+      ['entity.profile.collection', []],
+      ['entity.profile_type.collection', []],
+    ];
+
+    $this->assertLocalTasks($tasks, 0);
+  }
+
+  /**
+   * Asserts local tasks in the page output.
+   *
+   * @param array $routes
+   *   A list of expected local tasks, prepared as an array of route names and
+   *   their associated route parameters, to assert on the page (in the given
+   *   order).
+   * @param int $level
+   *   (optional) The local tasks level to assert; 0 for primary, 1 for
+   *   secondary. Defaults to 0.
+   */
+  protected function assertLocalTasks(array $routes, $level = 0) {
+    $elements = $this->xpath('//*[contains(@class, :class)]//a', array(
+      ':class' => $level == 0 ? 'tabs primary' : 'tabs secondary',
+    ));
+    $this->assertTrue(count($elements), 'Local tasks found.');
+    foreach ($routes as $index => $route_info) {
+      list($route_name, $route_parameters) = $route_info;
+      $expected = Url::fromRoute($route_name, $route_parameters)->toString();
+      $method = ($elements[$index]['href'] == $expected ? 'pass' : 'fail');
+      $this->{$method}(new FormattableMarkup('Task @number href @value equals @expected.', [
+        '@number' => $index + 1,
+        '@value' => (string) $elements[$index]['href'],
+        '@expected' => $expected,
+      ]));
+    }
+  }
+
+}
diff --git a/tests/src/Functional/ProfileTypeCRUDTest.php b/tests/src/Functional/ProfileTypeCRUDTest.php
new file mode 100644
index 0000000..c5c3a6e
--- /dev/null
+++ b/tests/src/Functional/ProfileTypeCRUDTest.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Drupal\Tests\profile\Functional;
+
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Component\Utility\Unicode;
+
+/**
+ * Tests basic CRUD functionality of profile types.
+ *
+ * @group profile
+ */
+class ProfileTypeCRUDTest extends ProfileTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->adminUser = $this->drupalCreateUser([
+      'access user profiles',
+      'administer profile types',
+      'administer profile fields',
+      'administer profile display',
+      'bypass profile access',
+    ]);
+  }
+
+  /**
+   * Verify that routes are created for the profile type.
+   */
+  public function testRoutes() {
+    $this->drupalLogin($this->adminUser);
+    $type = $this->createProfileType($this->randomMachineName());
+    \Drupal::service('router.builder')->rebuildIfNeeded();
+    $this->drupalGet("user/{$this->adminUser->id()}/{$type->id()}");
+    $this->assertResponse(200);
+  }
+
+  /**
+   * Tests CRUD operations for profile types through the UI.
+   */
+  public function testCRUDUI() {
+    $this->drupalLogin($this->adminUser);
+
+    // Create a new profile type.
+    $this->drupalGet('admin/config/people/profiles/types');
+    $this->assertResponse(200);
+    $this->clickLink(t('Add profile type'));
+
+    $this->assertUrl('admin/config/people/profiles/types/add');
+    $id = Unicode::strtolower($this->randomMachineName());
+    $label = $this->randomString();
+    $edit = [
+      'id' => $id,
+      'label' => $label,
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save'));
+    $this->assertUrl('admin/config/people/profiles/types');
+    $this->assertRaw(new FormattableMarkup('%label profile type has been created.', ['%label' => $label]));
+    $this->assertLinkByHref("admin/config/people/profiles/types/manage/$id");
+    $this->assertLinkByHref("admin/config/people/profiles/types/manage/$id/fields");
+    $this->assertLinkByHref("admin/config/people/profiles/types/manage/$id/display");
+    $this->assertLinkByHref("admin/config/people/profiles/types/manage/$id/delete");
+
+    // Edit the new profile type.
+    $this->drupalGet("admin/config/people/profiles/types/manage/$id");
+    $this->assertRaw(new FormattableMarkup('Edit %label profile type', ['%label' => $label]));
+    $edit = [
+      'registration' => 1,
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save'));
+    $this->assertUrl('admin/config/people/profiles/types');
+    $this->assertRaw(new FormattableMarkup('%label profile type has been updated.', ['%label' => $label]));
+
+    \Drupal::service('entity_type.bundle.info')->clearCachedBundles();
+
+    // Add a field to the profile type.
+    $this->drupalGet("admin/config/people/profiles/types/manage/$id/fields/add-field");
+    $field_name = Unicode::strtolower($this->randomMachineName());
+    $field_label = $this->randomString();
+    $edit = [
+      'new_storage_type' => 'string',
+      'label' => $field_label,
+      'field_name' => $field_name,
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save and continue'));
+    $this->drupalPostForm(NULL, [], t('Save field settings'));
+    $this->drupalPostForm(NULL, [], t('Save settings'));
+    $this->assertRaw(new FormattableMarkup('Saved %label configuration.', ['%label' => $field_label]));
+
+    // Verify that the field is still associated with it.
+    $this->drupalGet("admin/config/people/profiles/types/manage/$id/fields");
+    // @todo D8 core: This assertion fails for an unknown reason. Database
+    //   contains the right values, so field_attach_rename_bundle() works
+    //   correctly. The pre-existing field does not appear on the Manage
+    //   fields page of the renamed bundle. Not even flushing all caches
+    //   helps. Can be reproduced manually.
+    // $this->assertText(check_plain($field_label));
+  }
+
+}
diff --git a/tests/src/Functional/ProfileTypeMultipleTest.php b/tests/src/Functional/ProfileTypeMultipleTest.php
new file mode 100644
index 0000000..4bd3c79
--- /dev/null
+++ b/tests/src/Functional/ProfileTypeMultipleTest.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace Drupal\Tests\profile\Functional;
+
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Core\Cache\Cache;
+
+/**
+ * Tests multiple enabled profile types.
+ *
+ * @group profile
+ */
+class ProfileTypeMultipleTest extends ProfileTestBase {
+
+  /**
+   * Tests the flow of a profile type that has multiple enabled.
+   */
+  public function testMultipleProfileType() {
+    $this->drupalLogin($this->adminUser);
+
+    $edit = [
+      'multiple' => 1,
+    ];
+    $this->drupalPostForm("admin/config/people/profiles/types/manage/{$this->type->id()}", $edit, t('Save'));
+    $this->assertRaw(new FormattableMarkup('%type profile type has been updated.', [
+      '%type' => $this->type->label(),
+    ]));
+
+    $web_user1 = $this->drupalCreateUser(
+      [
+        "view own {$this->type->id()} profile",
+        "add own {$this->type->id()} profile",
+        "edit own {$this->type->id()} profile",
+      ]
+    );
+    $this->drupalLogin($web_user1);
+    $value = $this->randomMachineName();
+
+    $edit = [
+      "{$this->field->getName()}[0][value]" => $value,
+    ];
+    $this->drupalPostForm("user/{$web_user1->id()}/{$this->type->id()}", $edit, t('Save'));
+    $this->assertRaw(new FormattableMarkup('%type profile has been created.', [
+      '%type' => $this->type->label(),
+    ]));
+
+    $this->drupalGet("user/{$web_user1->id()}/{$this->type->id()}");
+    $this->assertLinkByHref("user/{$web_user1->id()}/{$this->type->id()}/add");
+    $this->assertText($value);
+
+    $value2 = $this->randomMachineName();
+    $edit = [
+      "{$this->field->getName()}[0][value]" => $value2,
+    ];
+    $this->drupalPostForm("user/{$web_user1->id()}/{$this->type->id()}/add", $edit, t('Save'));
+    $this->assertRaw(new FormattableMarkup('%type profile has been created.', [
+      '%type' => $this->type->label(),
+    ]));
+
+    Cache::invalidateTags(['profile_view']);
+
+    $this->drupalGet("user/{$web_user1->id()}/{$this->type->id()}");
+    $this->assertText($value2);
+  }
+
+  /**
+   * Tests the non-multiple profile type create and edit flow.
+   */
+  public function testProfileNotMultipleFlow() {
+    $web_user1 = $this->createUser([
+      "add own {$this->type->id()} profile",
+      "edit own {$this->type->id()} profile",
+    ]);
+    $this->drupalLogin($web_user1);
+
+    // Create the profile.
+    $edit = [
+      "{$this->field->getName()}[0][value]" => $this->randomString(),
+    ];
+    $this->drupalPostForm("user/{$web_user1->id()}/{$this->type->id()}", $edit, 'Save and make default');
+    $this->assertRaw(new FormattableMarkup('%type profile has been created.', [
+      '%type' => $this->type->label(),
+    ]));
+
+    // Update the profile.
+    $edit = [
+      "{$this->field->getName()}[0][value]" => $this->randomString(),
+    ];
+    $this->drupalPostForm("user/{$web_user1->id()}/{$this->type->id()}", $edit, t('Save'));
+    $this->assertRaw(new FormattableMarkup('%type profile has been updated.', [
+      '%type' => $this->type->label(),
+    ]));
+  }
+
+}
diff --git a/tests/src/Kernel/ProfileAccessTest.php b/tests/src/Kernel/ProfileAccessTest.php
index c71476b..cd570a6 100644
--- a/tests/src/Kernel/ProfileAccessTest.php
+++ b/tests/src/Kernel/ProfileAccessTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\profile\Tests;
+namespace Drupal\Tests\profile\Kernel;
 
 use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
 use Drupal\profile\Entity\Profile;
@@ -158,18 +158,6 @@ class ProfileAccessTest extends EntityKernelTestBase {
     // Test user2 can view any profiles.
     $this->assertTrue($profile1->access('view', $web_user2));
     $this->assertTrue($profile2->access('view', $web_user2));
-
-    $user_view_builder = $this->container->get('entity_type.manager')->getViewBuilder('user');
-
-    $this->container->get('current_user')->setAccount($web_user1);
-    $user2_view = $user_view_builder->view($web_user2);
-    $this->render($user2_view);
-    $this->assertNoText($this->type->label());
-
-    $this->container->get('current_user')->setAccount($web_user2);
-    $user1_view = $user_view_builder->view($web_user1);
-    $this->render($user1_view);
-    $this->assertText($this->type->label());
   }
 
   /**
diff --git a/tests/src/Kernel/ProfileRoleAccessTest.php b/tests/src/Kernel/ProfileRoleAccessTest.php
new file mode 100644
index 0000000..6c5e46c
--- /dev/null
+++ b/tests/src/Kernel/ProfileRoleAccessTest.php
@@ -0,0 +1,192 @@
+<?php
+
+namespace Drupal\Tests\profile\Kernel;
+
+use Drupal\Core\Session\AccountInterface;
+use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
+use Drupal\profile\ProfileTestTrait;
+use Drupal\user\Entity\Role;
+
+/**
+ * Tests profile role access handling.
+ *
+ * @group profile
+ */
+class ProfileRoleAccessTest extends EntityKernelTestBase {
+
+  use ProfileTestTrait;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['user', 'system', 'field', 'text', 'profile', 'views'];
+
+  /**
+   * Randomly generated profile type entity.
+   *
+   * No roles.
+   *
+   * @var \Drupal\profile\Entity\ProfileType
+   */
+  protected $type1;
+
+  /**
+   * Randomly generated profile type entity.
+   *
+   * Requires some, but not all roles.
+   *
+   * @var \Drupal\profile\Entity\ProfileType
+   */
+  protected $type2;
+
+  /**
+   * Randomly generated profile type entity.
+   *
+   * Requires all profile roles.
+   *
+   * @var \Drupal\profile\Entity\ProfileType
+   */
+  protected $type3;
+
+  /**
+   * Randomly generated user role entity.
+   *
+   * @var \Drupal\user\Entity\Role
+   */
+  protected $role1;
+
+  /**
+   * Randomly generated user role entity.
+   *
+   * @var \Drupal\user\Entity\Role
+   */
+  protected $role2;
+
+  /**
+   * @var \Drupal\profile\ProfileAccessControlHandler
+   */
+  protected $accessHandler;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->role1 = Role::create([
+      'id' => strtolower($this->randomMachineName(8)),
+      'label' => $this->randomMachineName(8),
+    ]);
+    $this->role1->save();
+    $this->role2 = Role::create([
+      'id' => strtolower($this->randomMachineName(8)),
+      'label' => $this->randomMachineName(8),
+    ]);
+    $this->role2->save();
+    $this->type1 = $this->createProfileType(NULL, NULL, FALSE, []);
+    $this->type2 = $this->createProfileType(NULL, NULL, FALSE, [$this->role2->id()]);
+    $this->type3 = $this->createProfileType(NULL, NULL, FALSE, [$this->role1->id(), $this->role2->id()]);
+
+    $this->accessHandler = $this->container->get('entity_type.manager')->getAccessControlHandler('profile');
+
+    // Do not allow uid == 1 to skew tests.
+    $this->createUser();
+  }
+
+  /**
+   * Tests add profile form access for a profile type that does not require
+   * users to have a role.
+   */
+  public function testProfileWithNoRoles() {
+    // Create user with add own profile permissions.
+    $web_user1 = $this->createUser([], ["add own {$this->type1->id()} profile"]);
+    $this->assertTrue($this->accessHandler->createAccess($this->type1->id(), $web_user1));
+  }
+
+  public function testLockedRoles() {
+    $locked_role_type = $this->createProfileType(NULL, NULL, FALSE, [AccountInterface::AUTHENTICATED_ROLE]);
+    // Create user with add own profile permissions.
+    $web_user1 = $this->createUser([], ["add own {$locked_role_type->id()} profile"]);
+    $this->assertTrue($this->accessHandler->createAccess($locked_role_type->id(), $web_user1));
+  }
+
+  /**
+   * Tests add profile form access for a profile type that requires users to
+   * have a single role.
+   */
+  public function testProfileWithSingleRole() {
+    // Create user with add own profile permissions.
+    $web_user1 = $this->createUser([], ["add own {$this->type2->id()} profile"]);
+
+    // Test user without role can access add profile form.
+    // Expected: User cannot access form.
+    $this->assertFalse($this->accessHandler->createAccess($this->type2->id(), $web_user1));
+    $this->accessHandler->resetCache();
+
+    // Test user with wrong role can access add profile form.
+    // Expected: User cannot access form.
+    $web_user1->addRole($this->role1->id());
+    $web_user1->save();
+
+    $this->assertFalse($this->accessHandler->createAccess($this->type2->id(), $web_user1));
+    $this->accessHandler->resetCache();
+
+    // Test user with correct role can access add profile form.
+    // Expected: User can access form.
+    $web_user1->removeRole($this->role1->id());
+    $web_user1->addRole($this->role2->id());
+    $web_user1->save();
+    $this->reloadEntity($web_user1);
+
+    $this->assertTrue($this->accessHandler->createAccess($this->type2->id(), $web_user1));
+
+  }
+
+  /**
+   * Tests add profile form access for a profile type that requires users to
+   * have one of multiple roles.
+   */
+  public function testProfileWithAllRoles() {
+    // Create user with add own profile permissions.
+    $web_user1 = $this->createUser([], ["add own {$this->type3->id()} profile"]);
+
+    // Test user without role can access add profile form.
+    // Expected: User cannot access form.
+    $this->assertFalse($this->accessHandler->createAccess($this->type3->id(), $web_user1));
+    $this->accessHandler->resetCache();
+
+    // Test user with role 1 can access add profile form.
+    // Expected: User can access form.
+    $web_user1->addRole($this->role1->id());
+    $web_user1->save();
+
+    $this->assertTrue($this->accessHandler->createAccess($this->type3->id(), $web_user1));
+    $this->accessHandler->resetCache();
+
+    // Test user with both roles can access add profile form.
+    // Expected: User can access form.
+    $web_user1->addRole($this->role2->id());
+    $web_user1->save();
+
+    $this->assertTrue($this->accessHandler->createAccess($this->type3->id(), $web_user1));
+    $this->accessHandler->resetCache();
+
+    // Test user with role 2 can access add profile form.
+    // Expected: User can access form.
+    $web_user1->removeRole($this->role1->id());
+    $web_user1->save();
+
+    $this->assertTrue($this->accessHandler->createAccess($this->type3->id(), $web_user1));
+    $this->accessHandler->resetCache();
+
+    // Test user without role can access add profile form.
+    // Expected: User cannot access form.
+    $web_user1->removeRole($this->role2->id());
+    $web_user1->save();
+
+    $this->assertFalse($this->accessHandler->createAccess($this->type3->id(), $web_user1));
+  }
+
+}
