1<?php
2
3namespace Drupal\KernelTests\Core\Render;
4
5use Drupal\KernelTests\KernelTestBase;
6use Drupal\Tests\user\Traits\UserCreationTrait;
7
8/**
9 * Tests the caching of render items via functional tests.
10 *
11 * @group Render
12 */
13class RenderCacheTest extends KernelTestBase {
14
15  use UserCreationTrait;
16
17  /**
18   * Modules to enable.
19   *
20   * @var array
21   */
22  public static $modules = ['user', 'system'];
23
24  /**
25   * {@inheritdoc}
26   */
27  protected function setUp() {
28    parent::setUp();
29    $this->installEntitySchema('user');
30    $this->installConfig(['user']);
31    $this->installSchema('system', ['sequences']);
32  }
33
34  /**
35   * Tests that user 1 has a different permission context with the same roles.
36   */
37  public function testUser1PermissionContext() {
38    $this->doTestUser1WithContexts(['user.permissions']);
39  }
40
41  /**
42   * Tests that user 1 has a different roles context with the same roles.
43   */
44  public function testUser1RolesContext() {
45    $this->doTestUser1WithContexts(['user.roles']);
46  }
47
48  /**
49   * Ensures that user 1 has a unique render cache for the given context.
50   *
51   * @param string[] $contexts
52   *   List of cache contexts to use.
53   */
54  protected function doTestUser1WithContexts($contexts) {
55    // Test that user 1 does not share the cache with other users who have the
56    // same roles, even when using a role-based cache context.
57    $user1 = $this->createUser();
58    $this->assertEqual($user1->id(), 1);
59    $first_authenticated_user = $this->createUser();
60    $second_authenticated_user = $this->createUser();
61    $admin_user = $this->createUser([], NULL, TRUE);
62
63    $this->assertEqual($user1->getRoles(), $first_authenticated_user->getRoles(), 'User 1 has the same roles as an authenticated user.');
64    // Impersonate user 1 and render content that only user 1 should have
65    // permission to see.
66    \Drupal::service('account_switcher')->switchTo($user1);
67    $test_element = [
68      '#cache' => [
69        'keys' => ['test'],
70        'contexts' => $contexts,
71      ],
72    ];
73    $element = $test_element;
74    $element['#markup'] = 'content for user 1';
75    $output = \Drupal::service('renderer')->renderRoot($element);
76    $this->assertEqual($output, 'content for user 1');
77
78    // Verify the cache is working by rendering the same element but with
79    // different markup passed in; the result should be the same.
80    $element = $test_element;
81    $element['#markup'] = 'should not be used';
82    $output = \Drupal::service('renderer')->renderRoot($element);
83    $this->assertEqual($output, 'content for user 1');
84    \Drupal::service('account_switcher')->switchBack();
85
86    // Verify that the first authenticated user does not see the same content
87    // as user 1.
88    \Drupal::service('account_switcher')->switchTo($first_authenticated_user);
89    $element = $test_element;
90    $element['#markup'] = 'content for authenticated users';
91    $output = \Drupal::service('renderer')->renderRoot($element);
92    $this->assertEqual($output, 'content for authenticated users');
93    \Drupal::service('account_switcher')->switchBack();
94
95    // Verify that the second authenticated user shares the cache with the
96    // first authenticated user.
97    \Drupal::service('account_switcher')->switchTo($second_authenticated_user);
98    $element = $test_element;
99    $element['#markup'] = 'should not be used';
100    $output = \Drupal::service('renderer')->renderRoot($element);
101    $this->assertEqual($output, 'content for authenticated users');
102    \Drupal::service('account_switcher')->switchBack();
103
104    // Verify that the admin user (who has an admin role without explicit
105    // permissions) does not share the same cache.
106    \Drupal::service('account_switcher')->switchTo($admin_user);
107    $element = $test_element;
108    $element['#markup'] = 'content for admin user';
109    $output = \Drupal::service('renderer')->renderRoot($element);
110    $this->assertEqual($output, 'content for admin user');
111    \Drupal::service('account_switcher')->switchBack();
112  }
113
114}
115