Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / workflows / tests / src / Kernel / WorkflowAccessControlHandlerTest.php
diff --git a/web/core/modules/workflows/tests/src/Kernel/WorkflowAccessControlHandlerTest.php b/web/core/modules/workflows/tests/src/Kernel/WorkflowAccessControlHandlerTest.php
new file mode 100644 (file)
index 0000000..cd4e7ce
--- /dev/null
@@ -0,0 +1,218 @@
+<?php
+
+namespace Drupal\Tests\workflows\Kernel;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Cache\Context\CacheContextsManager;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\simpletest\UserCreationTrait;
+use Drupal\workflows\Entity\Workflow;
+
+/**
+ * @coversDefaultClass \Drupal\workflows\WorkflowAccessControlHandler
+ * @group workflows
+ */
+class WorkflowAccessControlHandlerTest extends KernelTestBase {
+
+  use UserCreationTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'workflows',
+    'workflow_type_test',
+    'system',
+    'user',
+  ];
+
+  /**
+   * The workflow access control handler.
+   *
+   * @var \Drupal\workflows\WorkflowAccessControlHandler
+   */
+  protected $accessControlHandler;
+
+  /**
+   * A test admin user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $adminUser;
+
+  /**
+   * A non-privileged user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $user;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installEntitySchema('workflow');
+    $this->installEntitySchema('user');
+    $this->installSchema('system', ['sequences']);
+
+    $this->accessControlHandler = $this->container->get('entity_type.manager')->getAccessControlHandler('workflow');
+
+    // Create and discard user 1, which is special and bypasses all access
+    // checking.
+    $this->createUser([]);
+    $this->user = $this->createUser([]);
+    $this->adminUser = $this->createUser(['administer workflows']);
+  }
+
+  /**
+   * @covers ::checkCreateAccess
+   */
+  public function testCheckCreateAccess() {
+    // A user must have the correct permission to create a workflow.
+    $this->assertEquals(
+      AccessResult::neutral()
+        ->addCacheContexts(['user.permissions'])
+        ->setReason("The 'administer workflows' permission is required.")
+        ->addCacheTags(['workflow_type_plugins']),
+      $this->accessControlHandler->createAccess(NULL, $this->user, [], TRUE)
+    );
+    $this->assertEquals(
+      AccessResult::allowed()
+        ->addCacheContexts(['user.permissions'])
+        ->addCacheTags(['workflow_type_plugins']),
+      $this->accessControlHandler->createAccess(NULL, $this->adminUser, [], TRUE)
+    );
+
+    // Remove all plugin types and ensure not even the admin user is allowed to
+    // create a workflow.
+    workflow_type_test_set_definitions([]);
+    $this->accessControlHandler->resetCache();
+    $this->assertEquals(
+      AccessResult::neutral()
+        ->addCacheContexts(['user.permissions'])
+        ->addCacheTags(['workflow_type_plugins']),
+      $this->accessControlHandler->createAccess(NULL, $this->adminUser, [], TRUE)
+    );
+  }
+
+  /**
+   * @covers ::checkAccess
+   * @dataProvider checkAccessProvider
+   */
+  public function testCheckAccess($user, $operation, $result, $states_to_create = []) {
+    $workflow = Workflow::create([
+      'type' => 'workflow_type_test',
+      'id' => 'test_workflow',
+    ]);
+    $workflow->save();
+    $workflow_type = $workflow->getTypePlugin();
+    foreach ($states_to_create as $state_id => $is_required) {
+      $workflow_type->addState($state_id, $this->randomString());
+    }
+    \Drupal::state()->set('workflow_type_test.required_states', array_filter($states_to_create));
+    $this->assertEquals($result, $this->accessControlHandler->access($workflow, $operation, $this->{$user}, TRUE));
+  }
+
+  /**
+   * Data provider for ::testCheckAccess.
+   *
+   * @return array
+   */
+  public function checkAccessProvider() {
+    $container = new ContainerBuilder();
+    $cache_contexts_manager = $this->prophesize(CacheContextsManager::class);
+    $cache_contexts_manager->assertValidTokens()->willReturn(TRUE);
+    $cache_contexts_manager->reveal();
+    $container->set('cache_contexts_manager', $cache_contexts_manager);
+    \Drupal::setContainer($container);
+
+    return [
+      'Admin view' => [
+        'adminUser',
+        'view',
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+      ],
+      'Admin update' => [
+        'adminUser',
+        'update',
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+      ],
+      'Admin delete' => [
+        'adminUser',
+        'delete',
+        AccessResult::allowed()->addCacheContexts(['user.permissions']),
+      ],
+      'Admin delete only state' => [
+        'adminUser',
+        'delete-state:foo',
+        AccessResult::neutral()->addCacheTags(['config:workflows.workflow.test_workflow']),
+        ['foo' => FALSE],
+      ],
+      'Admin delete one of two states' => [
+        'adminUser',
+        'delete-state:foo',
+        AccessResult::allowed()
+          ->addCacheTags(['config:workflows.workflow.test_workflow'])
+          ->addCacheContexts(['user.permissions']),
+        ['foo' => FALSE, 'bar' => FALSE],
+      ],
+      'Admin delete required state when there are >1 states' => [
+        'adminUser',
+        'delete-state:foo',
+        AccessResult::allowed()
+          ->addCacheTags(['config:workflows.workflow.test_workflow'])
+          ->addCacheContexts(['user.permissions']),
+        ['foo' => TRUE, 'bar' => FALSE],
+      ],
+      'User view' => [
+        'user',
+        'view',
+        AccessResult::neutral()
+          ->addCacheContexts(['user.permissions'])
+          ->setReason("The 'administer workflows' permission is required."),
+      ],
+      'User update' => [
+        'user',
+        'update',
+        AccessResult::neutral()
+          ->addCacheContexts(['user.permissions'])
+          ->setReason("The 'administer workflows' permission is required."),
+      ],
+      'User delete' => [
+        'user',
+        'delete',
+        AccessResult::neutral()
+          ->addCacheContexts(['user.permissions'])
+          ->setReason("The 'administer workflows' permission is required."),
+      ],
+      'User delete only state' => [
+        'user',
+        'delete-state:foo',
+        AccessResult::neutral()->addCacheTags(['config:workflows.workflow.test_workflow']),
+        ['foo' => FALSE],
+      ],
+      'User delete one of two states' => [
+        'user',
+        'delete-state:foo',
+        AccessResult::neutral()
+          ->addCacheTags(['config:workflows.workflow.test_workflow'])
+          ->addCacheContexts(['user.permissions'])
+          ->setReason("The 'administer workflows' permission is required."),
+        ['foo' => FALSE, 'bar' => FALSE],
+      ],
+      'User delete required state when there are >1 states' => [
+        'user',
+        'delete-state:foo',
+        AccessResult::neutral()
+          ->addCacheTags(['config:workflows.workflow.test_workflow'])
+          ->addCacheContexts(['user.permissions'])
+          ->setReason("The 'administer workflows' permission is required."),
+        ['foo' => TRUE, 'bar' => FALSE],
+      ],
+    ];
+  }
+
+}