You are here

public function WebformEntityAccessControlHandlerTest::testCheckAccess in Webform 6.x

Same name and namespace in other branches
  1. 8.5 tests/src/Unit/WebformEntityAccessControlHandlerTest.php \Drupal\Tests\webform\Unit\WebformEntityAccessControlHandlerTest::testCheckAccess()

Tests the access logic.

@dataProvider providerCheckAccess

Parameters

string $operation: Operation to request from ::checkAccess() method.

array $options: Array of extra options.

array $expected: Expected data from the tested class.

string $assert_message: Assertion message to use for this test case.

See also

WebformEntityAccessControlHandler::checkAccess()

File

tests/src/Unit/WebformEntityAccessControlHandlerTest.php, line 75

Class

WebformEntityAccessControlHandlerTest
Tests webform access handler.

Namespace

Drupal\Tests\webform\Unit

Code

public function testCheckAccess($operation, array $options, array $expected, $assert_message = '') {

  // Set $options default value.
  $options += [
    // What is the request path.
    'request_path' => '',
    // What is the request format.
    'request_format' => 'html',
    // Array of permissions to assign to a mocked account.
    'permissions' => [],
    // Array of access rules that should yield 'allowed' when the mocked
    // access rules manager is requested ::checkWebformAccess()
    // or ::checkWebformSubmissionAccess().
    'access_rules' => [],
    // Whether the mocked user should be owner of the webform.
    'account_is_webform_owner' => FALSE,
    // Whether the mocked webform should be a template.
    'webform_is_template' => FALSE,
    // Whether the mocked webform should be open.
    'webform_is_open' => TRUE,
    // Whether the mocked webform submission should successfully
    // load through token in query string. Defaults to FALSE.
    'submission_load_from_token' => FALSE,
  ];

  // Set $expected default value.
  $expected += [
    // Whether ::isAllowed() on the return should yield TRUE.
    'access_result_is_allowed' => TRUE,
    // Cache tags of the return.
    'access_result_cache_tags' => [],
    // Cache contexts of the return.
    'access_result_cache_contexts' => [],
  ];

  /**************************************************************************/
  $token = $this
    ->randomMachineName();

  // Mock entity type.
  $entity_type = new ConfigEntityType([
    'id' => 'webform',
  ]);

  // Mock request stack.
  $request_stack = $this
    ->getMockBuilder(RequestStack::class)
    ->disableOriginalConstructor()
    ->getMock();
  $request_stack
    ->method('getCurrentRequest')
    ->willReturn(new Request([
    'token' => $token,
  ], [], [
    '_format' => $options['request_format'],
  ]));

  // Mock webform submission storage.
  $webform_submission_storage = $this
    ->getMockBuilder(WebformSubmissionStorageInterface::class)
    ->getMock();

  // Mock entity type manager.
  $entity_type_manager = $this
    ->getMockBuilder(EntityTypeManagerInterface::class)
    ->getMock();
  $entity_type_manager
    ->method('getStorage')
    ->willReturnMap([
    [
      'webform_submission',
      $webform_submission_storage,
    ],
  ]);

  // Mock webform source entity manager.
  $webform_source_entity_manager = $this
    ->getMockBuilder(WebformSourceEntityManagerInterface::class)
    ->getMock();
  $webform_source_entity_manager
    ->method('getSourceEntity')
    ->willReturn(NULL);

  // Mock account.
  $permissions = $options['permissions'];
  $account_id = 2;
  $account = $this
    ->getMockBuilder(AccountInterface::class)
    ->getMock();
  $account
    ->method('hasPermission')
    ->willReturnCallback(function ($permission) use ($permissions) {
    return in_array($permission, $permissions);
  });
  $account
    ->method('id')
    ->willReturn($options['account_is_webform_owner'] ? $account_id : $account_id + 1);
  $account
    ->method('isAuthenticated')
    ->willReturn($account
    ->id() > 0);

  // Mock webform.
  $webform = $this
    ->getMockBuilder(WebformInterface::class)
    ->getMock();
  $webform
    ->method('getOwnerId')
    ->willReturn($account_id);
  $webform
    ->method('isTemplate')
    ->willReturn($options['webform_is_template']);
  $webform
    ->method('isOpen')
    ->willReturn($options['webform_is_open']);
  $webform
    ->method('access')
    ->willReturnMap([
    [
      'create',
      $account,
      TRUE,
      AccessResult::allowed(),
    ],
  ]);
  $webform
    ->method('getSetting')
    ->willReturnMap([
    [
      'page',
      FALSE,
      TRUE,
    ],
  ]);
  $webform
    ->method('getCacheMaxAge')
    ->willReturn(Cache::PERMANENT);
  $webform
    ->method('getCacheContexts')
    ->willReturn([
    'webform_cache_context',
  ]);
  $webform
    ->method('getCacheTags')
    ->willReturn([
    'webform_cache_tag',
  ]);

  // Mock webform submissions.
  $webform_submission = $this
    ->getMockBuilder(WebformSubmissionInterface::class)
    ->getMock();
  $webform_submission
    ->method('getCacheContexts')
    ->willReturn([
    'webform_submission_cache_context',
  ]);
  $webform_submission
    ->method('getCacheTags')
    ->willReturn([
    'webform_submission_cache_tag',
  ]);
  $webform_submission
    ->method('getCacheMaxAge')
    ->willReturn(Cache::PERMANENT);
  $webform_submission
    ->method('getWebform')
    ->willReturn($webform);
  $webform_submission_storage
    ->method('loadFromToken')
    ->willReturnMap([
    [
      $token,
      $webform,
      NULL,
      NULL,
      $options['submission_load_from_token'] ? $webform_submission : NULL,
    ],
  ]);

  // Mock access rules manager.
  $access_rules_manager = $this
    ->getMockBuilder(WebformAccessRulesManagerInterface::class)
    ->getMock();
  $access_rules_manager
    ->method('checkWebformAccess')
    ->will($this
    ->returnCallback(function ($operation, AccountInterface $account, WebformInterface $webform) use ($options) {
    $condition = in_array($operation, $options['access_rules']) || in_array($operation . '_any', $options['access_rules']);
    return AccessResult::allowedIf($condition)
      ->addCacheContexts([
      'access_rules_cache_context',
    ])
      ->addCacheTags([
      'access_rules_cache_tag',
    ]);
  }));

  // Build container.
  $container = new ContainerBuilder();
  $container
    ->set('request_stack', $request_stack);
  $container
    ->set('entity_type.manager', $entity_type_manager);
  $container
    ->set('plugin.manager.webform.source_entity', $webform_source_entity_manager);
  $container
    ->set('webform.access_rules_manager', $access_rules_manager);

  /**************************************************************************/

  // Create webform access control handler.
  $access_handler = WebformEntityAccessControlHandler::createInstance($container, $entity_type);

  // Check access.
  $access_result = $access_handler
    ->checkAccess($webform, $operation, $account);

  // Check expected results.
  $this
    ->assertEquals($expected['access_result_is_allowed'], $access_result
    ->isAllowed(), $assert_message);
  $this
    ->assertEquals(Cache::PERMANENT, $access_result
    ->getCacheMaxAge(), $assert_message . ': cache max age');
  $this
    ->assertArrayEquals($expected['access_result_cache_contexts'], $access_result
    ->getCacheContexts(), $assert_message . ': cache contexts');
  $this
    ->assertArrayEquals($expected['access_result_cache_tags'], $access_result
    ->getCacheTags(), $assert_message . ': cache tags');
}