diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php index ef9fc14ec0..8817e4ef35 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBase.php @@ -2,9 +2,13 @@ namespace Drupal\KernelTests\Core\Entity; +use Drupal\Core\Database\DatabaseExceptionWrapper; +use Drupal\Core\Database\SchemaObjectExistsException; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityStorageException; use Drupal\KernelTests\KernelTestBase; use Drupal\Tests\user\Traits\UserCreationTrait; +use Drupal\user\Entity\User; /** * Defines an abstract test base for entity kernel tests. @@ -18,7 +22,6 @@ abstract class EntityKernelTestBase extends KernelTestBase { createUser as drupalCreateUser; grantPermissions as drupalGrantPermissions; setCurrentUser as drupalSetCurrentUser; - setUpCurrentUser as drupalSetUpCurrentUser; } /** @@ -114,6 +117,87 @@ protected function createUser($values = [], $permissions = []) { return $this->drupalCreateUser($permissions ?: [], NULL, FALSE, $values ?: []); } + /** + * {@inheritdoc} + */ + protected function setUpCurrentUser(array $values = [], array $permissions = [], $admin = FALSE) { + $values += [ + 'name' => $this->randomMachineName(), + ]; + + // In many cases the anonymous user account is fine for testing purposes, + // however, if we need to create a user with a non-empty ID, we need also + // the "sequences" table. + if (!\Drupal::moduleHandler()->moduleExists('system')) { + $values['uid'] = 0; + } + if ($this instanceof KernelTestBase && (!isset($values['uid']) || $values['uid'])) { + try { + $this->installSchema('system', ['sequences']); + } + catch (SchemaObjectExistsException $e) { + } + } + + // Creating an administrator or assigning custom permissions would result in + // creating and assigning a new role to the user. This is not possible with + // the anonymous user account. + if (($admin || $permissions) && isset($values['uid']) && is_numeric($values['uid']) && $values['uid'] == 0) { + throw new \LogicException('The anonymous user account cannot have additional roles.'); + } + + $original_permissions = $permissions; + $original_values = $values; + $autocreate_user_1 = !isset($values['uid']) || $values['uid'] > 1; + + // No need to create user account 1 if it already exists. + try { + $autocreate_user_1 = $autocreate_user_1 && !User::load(1); + } + catch (DatabaseExceptionWrapper $e) { + // Missing schema, it will be created later on. + } + + // Save the user entity object and created its schema if needed. + try { + if ($autocreate_user_1) { + $permissions = []; + $values = []; + } + $user = $this->createUser($values, $permissions); + } + catch (EntityStorageException $e) { + if ($this instanceof KernelTestBase) { + $this->installEntitySchema('user'); + $user = $this->createUser($values, $permissions); + } + else { + throw $e; + } + } + + // Ensure the anonymous user account exists. + if (!User::load(0)) { + $values = [ + 'uid' => 0, + 'status' => 0, + 'name' => '', + ]; + User::create($values)->save(); + } + + // If we automatically created user account 1, we need to create a regular + // user account before setting up the current user service to avoid + // potential false positives caused by access control bypass. + if ($autocreate_user_1) { + $user = $this->createUser($original_values, $original_permissions); + } + + $this->setCurrentUser($user); + + return $user; + } + /** * Reloads the given entity from the storage and returns it. * diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBaseTest.php index 6b8898ef1b..14175e2ab9 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBaseTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityKernelTestBaseTest.php @@ -21,9 +21,10 @@ protected function setUp() { * Tests that the current user is set up correctly. */ public function testSetUpCurrentUser() { - $account = $this->setUpCurrentUser(); + $account = $this->setUpCurrentUser([], ['access content']); $current_user = \Drupal::currentUser(); $this->assertSame($account->id(), $current_user->id()); + $this->assertTrue($current_user->hasPermission('access content')); } }