7d460dea48403deb7093f651b911e28991b5fe02
[yaffs-website] / web / core / modules / content_moderation / tests / src / Unit / LatestRevisionCheckTest.php
1 <?php
2
3 namespace Drupal\Tests\content_moderation\Unit;
4
5 use Drupal\block_content\Entity\BlockContent;
6 use Drupal\Core\Access\AccessResultAllowed;
7 use Drupal\Core\Access\AccessResultForbidden;
8 use Drupal\Core\Access\AccessResultNeutral;
9 use Drupal\Core\Cache\Context\CacheContextsManager;
10 use Drupal\Core\Routing\RouteMatch;
11 use Drupal\Core\Session\AccountInterface;
12 use Drupal\node\Entity\Node;
13 use Drupal\content_moderation\Access\LatestRevisionCheck;
14 use Drupal\content_moderation\ModerationInformation;
15 use Drupal\user\EntityOwnerInterface;
16 use Prophecy\Argument;
17 use Symfony\Component\DependencyInjection\ContainerBuilder;
18 use Symfony\Component\Routing\Route;
19
20 /**
21  * @coversDefaultClass \Drupal\content_moderation\Access\LatestRevisionCheck
22  * @group content_moderation
23  */
24 class LatestRevisionCheckTest extends \PHPUnit_Framework_TestCase {
25
26   /**
27    * {@inheritdoc}
28    */
29   protected function setUp() {
30     parent::setUp();
31
32     // Initialize Drupal container since the cache context manager is needed.
33     $contexts_manager = $this->prophesize(CacheContextsManager::class);
34     $contexts_manager->assertValidTokens(Argument::any())->willReturn(TRUE);
35     $builder = new ContainerBuilder();
36     $builder->set('cache_contexts_manager', $contexts_manager->reveal());
37     \Drupal::setContainer($builder);
38   }
39
40   /**
41    * Test the access check of the LatestRevisionCheck service.
42    *
43    * @param string $entity_class
44    *   The class of the entity to mock.
45    * @param string $entity_type
46    *   The machine name of the entity to mock.
47    * @param bool $has_forward
48    *   Whether this entity should have a forward revision in the system.
49    * @param array $account_permissions
50    *   An array of permissions the account has.
51    * @param bool $is_owner
52    *   Indicates if the user should be the owner of the entity.
53    * @param string $result_class
54    *   The AccessResult class that should result. One of AccessResultAllowed,
55    *   AccessResultForbidden, AccessResultNeutral.
56    *
57    * @dataProvider accessSituationProvider
58    */
59   public function testLatestAccessPermissions($entity_class, $entity_type, $has_forward, array $account_permissions, $is_owner, $result_class) {
60
61     /** @var \Drupal\Core\Session\AccountInterface $account */
62     $account = $this->prophesize(AccountInterface::class);
63     $possible_permissions = [
64       'view latest version',
65       'view any unpublished content',
66       'view own unpublished content',
67     ];
68     foreach ($possible_permissions as $permission) {
69       $account->hasPermission($permission)->willReturn(in_array($permission, $account_permissions));
70     }
71     $account->id()->willReturn(42);
72
73     /** @var \Drupal\Core\Entity\EntityInterface $entity */
74     $entity = $this->prophesize($entity_class);
75     $entity->getCacheContexts()->willReturn([]);
76     $entity->getCacheTags()->willReturn([]);
77     $entity->getCacheMaxAge()->willReturn(0);
78     if (is_subclass_of($entity_class, EntityOwnerInterface::class)) {
79       $entity->getOwnerId()->willReturn($is_owner ? 42 : 3);
80     }
81
82     /** @var \Drupal\content_moderation\ModerationInformation $mod_info */
83     $mod_info = $this->prophesize(ModerationInformation::class);
84     $mod_info->hasForwardRevision($entity->reveal())->willReturn($has_forward);
85
86     $route = $this->prophesize(Route::class);
87
88     $route->getOption('_content_moderation_entity_type')->willReturn($entity_type);
89
90     $route_match = $this->prophesize(RouteMatch::class);
91     $route_match->getParameter($entity_type)->willReturn($entity->reveal());
92
93     $lrc = new LatestRevisionCheck($mod_info->reveal());
94
95     /** @var \Drupal\Core\Access\AccessResult $result */
96     $result = $lrc->access($route->reveal(), $route_match->reveal(), $account->reveal());
97
98     $this->assertInstanceOf($result_class, $result);
99
100   }
101
102   /**
103    * Data provider for testLastAccessPermissions().
104    */
105   public function accessSituationProvider() {
106     return [
107       // Node with global permissions and latest version.
108       [Node::class, 'node', TRUE, ['view latest version', 'view any unpublished content'], FALSE, AccessResultAllowed::class],
109       // Node with global permissions and no latest version.
110       [Node::class, 'node', FALSE, ['view latest version', 'view any unpublished content'], FALSE, AccessResultForbidden::class],
111       // Node with own content permissions and latest version.
112       [Node::class, 'node', TRUE, ['view latest version', 'view own unpublished content'], TRUE, AccessResultAllowed::class],
113       // Node with own content permissions and no latest version.
114       [Node::class, 'node', FALSE, ['view latest version', 'view own unpublished content'], FALSE, AccessResultForbidden::class],
115       // Node with own content permissions and latest version, but no perms to
116       // view latest version.
117       [Node::class, 'node', TRUE, ['view own unpublished content'], TRUE, AccessResultNeutral::class],
118       // Node with own content permissions and no latest version, but no perms
119       // to view latest version.
120       [Node::class, 'node', TRUE, ['view own unpublished content'], FALSE, AccessResultNeutral::class],
121       // Block with forward revision, and permissions to view any.
122       [BlockContent::class, 'block_content', TRUE, ['view latest version', 'view any unpublished content'], FALSE, AccessResultAllowed::class],
123       // Block with no forward revision.
124       [BlockContent::class, 'block_content', FALSE, ['view latest version', 'view any unpublished content'], FALSE, AccessResultForbidden::class],
125       // Block with forward revision, but no permission to view any.
126       [BlockContent::class, 'block_content', TRUE, ['view latest version', 'view own unpublished content'], FALSE, AccessResultNeutral::class],
127       // Block with no forward revision.
128       [BlockContent::class, 'block_content', FALSE, ['view latest version', 'view own unpublished content'], FALSE, AccessResultForbidden::class],
129     ];
130   }
131
132 }