class PermissionsPerBundleTest

Same name and namespace in other branches
  1. 11.x core/tests/Drupal/KernelTests/Core/Recipe/PermissionsPerBundleTest.php \Drupal\KernelTests\Core\Recipe\PermissionsPerBundleTest

@covers \Drupal\Core\Config\Action\Plugin\ConfigAction\PermissionsPerBundle
@covers \Drupal\Core\Config\Action\Plugin\ConfigAction\Deriver\PermissionsPerBundleDeriver

@group Recipe

Hierarchy

Expanded class hierarchy of PermissionsPerBundleTest

File

core/tests/Drupal/KernelTests/Core/Recipe/PermissionsPerBundleTest.php, line 26

Namespace

Drupal\KernelTests\Core\Recipe
View source
class PermissionsPerBundleTest extends KernelTestBase {
  use ContentTypeCreationTrait;
  use MediaTypeCreationTrait;
  use RecipeTestTrait;
  use TaxonomyTestTrait;
  use UserCreationTrait;
  
  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'field',
    'media',
    'media_test_source',
    'node',
    'system',
    'taxonomy',
    'text',
    'user',
  ];
  
  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    $this->installConfig('node');
    $this->createRole([], 'super_editor');
    $this->createContentType([
      'type' => 'article',
    ]);
    $this->createContentType([
      'type' => 'blog',
    ]);
    $this->createContentType([
      'type' => 'landing_page',
    ]);
    $this->createMediaType('test', [
      'id' => 'beautiful',
    ]);
    $this->createMediaType('test', [
      'id' => 'controversial',
    ]);
    $this->createMediaType('test', [
      'id' => 'special',
    ]);
    $this->createVocabulary([
      'vid' => 'tags',
    ]);
    $this->createVocabulary([
      'vid' => 'categories',
    ]);
  }
  
  /**
   * Tests granting multiple bundle-specific permissions.
   */
  public function testGrantPermissionsPerBundle() : void {
    $recipe_data = <<<YAML
name: 'Multi permissions!'
config:
  actions:
    user.role.super_editor:
      grantPermissionsForEachNodeType:
        - create %bundle content
        - edit own %bundle content
      grantPermissionsForEachMediaType:
        permissions:
          - create %bundle media
          - edit own %bundle media
      grantPermissionsForEachTaxonomyVocabulary: create terms in %bundle
YAML;
    $this->applyRecipeFromString($recipe_data);
    $expected_permissions = [
      'create article content',
      'create blog content',
      'create landing_page content',
      'edit own article content',
      'edit own blog content',
      'edit own landing_page content',
      'create beautiful media',
      'create controversial media',
      'create special media',
      'edit own beautiful media',
      'edit own controversial media',
      'edit own special media',
      'create terms in tags',
      'create terms in categories',
    ];
    $role = Role::load('super_editor');
    assert($role instanceof RoleInterface);
    foreach ($expected_permissions as $permission) {
      $this->assertTrue($role->hasPermission($permission));
    }
  }
  
  /**
   * Tests that the permissions-per-bundle action can only be applied to roles.
   */
  public function testActionIsOnlyAvailableToUserRoles() : void {
    $recipe_data = <<<YAML
name: 'Only for roles...'
config:
  actions:
    field.storage.node.body:
      grantPermissionsForEachNodeType:
        - create %bundle content
        - edit own %bundle content
YAML;
    $this->expectException(PluginNotFoundException::class);
    $this->expectExceptionMessage('The "field_storage_config" entity does not support the "grantPermissionsForEachNodeType" config action.');
    $this->applyRecipeFromString($recipe_data);
  }
  
  /**
   * Tests granting permissions for one bundle, then all of them.
   */
  public function testGrantPermissionsOnOneBundleThenAll() : void {
    $recipe_data = <<<YAML
name: 'All bundles except one'
config:
  actions:
    user.role.super_editor:
      grantPermissions:
        - create beautiful media
        - edit own beautiful media
      grantPermissionsForEachMediaType:
        - create %bundle media
        - edit own %bundle media
YAML;
    $this->applyRecipeFromString($recipe_data);
    $role = Role::load('super_editor');
    $this->assertInstanceOf(Role::class, $role);
    $this->assertTrue($role->hasPermission('create beautiful media'));
    $this->assertTrue($role->hasPermission('edit own beautiful media'));
    $this->assertTrue($role->hasPermission('create controversial media'));
    $this->assertTrue($role->hasPermission('edit own beautiful media'));
  }
  
  /**
   * Tests granting permissions for all bundles except certain ones.
   */
  public function testGrantPermissionsToAllBundlesExceptSome() : void {
    $recipe_data = <<<YAML
name: 'Bundle specific permissions with some exceptions'
config:
  actions:
    user.role.super_editor:
      grantPermissionsForEachNodeType:
        permissions:
          - view %bundle revisions
        except:
          - article
          - blog
      grantPermissionsForEachMediaType:
        permissions: view any %bundle media revisions
        except:
          - controversial
      grantPermissionsForEachTaxonomyVocabulary:
        permissions:
          - view term revisions in %bundle
        except: tags
YAML;
    $this->applyRecipeFromString($recipe_data);
    $role = Role::load('super_editor');
    $this->assertInstanceOf(Role::class, $role);
    $this->assertTrue($role->hasPermission('view landing_page revisions'));
    $this->assertFalse($role->hasPermission('view article revisions'));
    $this->assertFalse($role->hasPermission('view blog revisions'));
    $this->assertTrue($role->hasPermission('view any beautiful media revisions'));
    $this->assertTrue($role->hasPermission('view any special media revisions'));
    $this->assertFalse($role->hasPermission('view any controversial media revisions'));
    $this->assertTrue($role->hasPermission('view term revisions in categories'));
    $this->assertFalse($role->hasPermission('view term revisions in tags'));
  }
  
  /**
   * Tests that there is an exception if the permission templates are invalid.
   *
   * @param mixed $value
   *   The permission template which should raise an error.
   *
   * @testWith [["a %Bundle permission"]]
   *   [""]
   *   [[]]
   */
  public function testInvalidValue(mixed $value) : void {
    $value = Json::encode($value);
    $recipe_data = <<<YAML
name: 'Bad permission value'
config:
  actions:
    user.role.super_editor:
      grantPermissionsForEachMediaType: {<span class="php-variable">$value</span>}
YAML;
    $this->expectException(ConfigActionException::class);
    $this->expectExceptionMessage(" must be an array of strings that contain '%bundle'.");
    $this->applyRecipeFromString($recipe_data);
  }
  
  /**
   * Given a string of `recipe.yml` contents, applies it to the site.
   *
   * @param string $recipe_data
   *   The contents of `recipe.yml`.
   */
  private function applyRecipeFromString(string $recipe_data) : void {
    $recipe = $this->createRecipe($recipe_data);
    RecipeRunner::processRecipe($recipe);
  }

}

Members

Title Sort descending Deprecated Modifiers Object type Summary
ConfigTestTrait::configImporter protected function Returns a ConfigImporter object to import test configuration.
ConfigTestTrait::copyConfig protected function Copies configuration objects from source storage to target storage.
ExtensionListTestTrait::getModulePath protected function Gets the path for the specified module.
ExtensionListTestTrait::getThemePath protected function Gets the path for the specified theme.
PermissionsPerBundleTest::$modules protected static property Modules to install.
PermissionsPerBundleTest::applyRecipeFromString private function Given a string of `recipe.yml` contents, applies it to the site.
PermissionsPerBundleTest::setUp protected function
PermissionsPerBundleTest::testActionIsOnlyAvailableToUserRoles public function Tests that the permissions-per-bundle action can only be applied to roles.
PermissionsPerBundleTest::testGrantPermissionsOnOneBundleThenAll public function Tests granting permissions for one bundle, then all of them.
PermissionsPerBundleTest::testGrantPermissionsPerBundle public function Tests granting multiple bundle-specific permissions.
PermissionsPerBundleTest::testGrantPermissionsToAllBundlesExceptSome public function Tests granting permissions for all bundles except certain ones.
PermissionsPerBundleTest::testInvalidValue public function Tests that there is an exception if the permission templates are invalid.
RandomGeneratorTrait::getRandomGenerator protected function Gets the random generator for the utility methods.
RandomGeneratorTrait::randomMachineName protected function Generates a unique random string containing letters and numbers.
RandomGeneratorTrait::randomObject public function Generates a random PHP object.
RandomGeneratorTrait::randomString public function Generates a pseudo-random string of ASCII characters of codes 32 to 126.
RandomGeneratorTrait::randomStringValidate Deprecated public function Callback for random string validation.
RecipeTestTrait::applyRecipe protected function Applies a recipe to the site.
RecipeTestTrait::createRecipe protected function Creates a recipe in a temporary directory.
StorageCopyTrait::replaceStorageContents protected static function Copy the configuration from one storage to another and remove stale items.
TestRequirementsTrait::checkModuleRequirements Deprecated private function Checks missing module requirements.
TestRequirementsTrait::checkRequirements Deprecated protected function Check module requirements for the Drupal use case.
TestRequirementsTrait::getDrupalRoot protected static function Returns the Drupal root directory.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.