3 namespace Drupal\Tests\views\Kernel\Plugin;
5 use Drupal\Core\Session\AccountInterface;
6 use Drupal\node\Entity\Node;
7 use Drupal\node\Entity\NodeType;
8 use Drupal\node\NodeInterface;
9 use Drupal\simpletest\UserCreationTrait;
10 use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
11 use Drupal\views\Views;
14 * Tests row render caching.
18 class RowRenderCacheTest extends ViewsKernelTestBase {
20 use UserCreationTrait;
27 public static $modules = ['user', 'node'];
30 * Views used by this test.
34 public static $testViews = ['test_row_render_cache', 'test_row_render_cache_none'];
37 * An editor user account.
39 * @var \Drupal\user\UserInterface
41 protected $editorUser;
44 * A power user account.
46 * @var \Drupal\user\UserInterface
51 * A regular user account.
53 * @var \Drupal\user\UserInterface
55 protected $regularUser;
60 protected function setUpFixtures() {
61 parent::setUpFixtures();
63 $this->installEntitySchema('user');
64 $this->installEntitySchema('node');
65 $this->installSchema('node', 'node_access');
67 $type = NodeType::create(['type' => 'test']);
70 $this->editorUser = $this->createUser(['bypass node access']);
71 $this->powerUser = $this->createUser(['access content', 'create test content', 'edit own test content', 'delete own test content']);
72 $this->regularUser = $this->createUser(['access content']);
74 // Create some test entities.
75 for ($i = 0; $i < 5; $i++) {
76 Node::create(['title' => 'b' . $i . $this->randomMachineName(), 'type' => 'test'])->save();
79 // Create a power user node.
80 Node::create(['title' => 'z' . $this->randomMachineName(), 'uid' => $this->powerUser->id(), 'type' => 'test'])->save();
84 * Test complex field rewriting and uncacheable field handlers.
86 public function testAdvancedCaching() {
87 // Test that row field output is actually cached and with the proper cache
89 $this->doTestRenderedOutput($this->editorUser);
90 $this->doTestRenderedOutput($this->editorUser, TRUE);
91 $this->doTestRenderedOutput($this->powerUser);
92 $this->doTestRenderedOutput($this->powerUser, TRUE);
93 $this->doTestRenderedOutput($this->regularUser);
94 $this->doTestRenderedOutput($this->regularUser, TRUE);
96 // Alter the result set order and check that counter is still working
98 $this->doTestRenderedOutput($this->editorUser);
99 /** @var \Drupal\node\NodeInterface $node */
100 $node = Node::load(6);
101 $node->setTitle('a' . $this->randomMachineName());
103 $this->doTestRenderedOutput($this->editorUser);
107 * Test that rows are not cached when the none cache plugin is used.
109 public function testNoCaching() {
110 $this->setCurrentUser($this->regularUser);
111 $view = Views::getView('test_row_render_cache_none');
115 /** @var \Drupal\Core\Render\RenderCacheInterface $render_cache */
116 $render_cache = $this->container->get('render_cache');
118 /** @var \Drupal\views\Plugin\views\cache\CachePluginBase $cache_plugin */
119 $cache_plugin = $view->display_handler->getPlugin('cache');
121 foreach ($view->result as $row) {
122 $keys = $cache_plugin->getRowCacheKeys($row);
126 'contexts' => ['languages:language_interface', 'theme', 'user.permissions'],
129 $element = $render_cache->get($cache);
130 $this->assertFalse($element);
135 * Check whether the rendered output matches expectations.
137 * @param \Drupal\Core\Session\AccountInterface $account
138 * The user account to tests rendering with.
139 * @param bool $check_cache
140 * (optional) Whether explicitly test render cache entries.
142 protected function doTestRenderedOutput(AccountInterface $account, $check_cache = FALSE) {
143 $this->setCurrentUser($account);
144 $view = Views::getView('test_row_render_cache');
148 /** @var \Drupal\Core\Render\RenderCacheInterface $render_cache */
149 $render_cache = $this->container->get('render_cache');
151 /** @var \Drupal\views\Plugin\views\cache\CachePluginBase $cache_plugin */
152 $cache_plugin = $view->display_handler->getPlugin('cache');
154 // Retrieve nodes and sort them in alphabetical order to match view results.
155 $nodes = Node::loadMultiple();
156 usort($nodes, function (NodeInterface $a, NodeInterface $b) {
157 return strcmp($a->label(), $b->label());
161 foreach ($nodes as $node) {
163 $access = $node->access('update');
165 $counter = $index + 1;
166 $expected = "$nid: $counter (just in case: $nid)";
167 $counter_output = $view->style_plugin->getField($index, 'counter');
168 $this->assertEqual($counter_output, $expected);
170 $node_url = $node->url();
171 $expected = "<a href=\"$node_url\"><span class=\"da-title\">{$node->label()}</span> <span class=\"counter\">$counter_output</span></a>";
172 $output = $view->style_plugin->getField($index, 'title');
173 $this->assertEqual($output, $expected);
175 $expected = $access ? "<a href=\"$node_url/edit?destination=/\" hreflang=\"en\">edit</a>" : "";
176 $output = $view->style_plugin->getField($index, 'edit_node');
177 $this->assertEqual($output, $expected);
179 $expected = $access ? "<a href=\"$node_url/delete?destination=/\" hreflang=\"en\">delete</a>" : "";
180 $output = $view->style_plugin->getField($index, 'delete_node');
181 $this->assertEqual($output, $expected);
182 $expected = $access ? ' <div class="dropbutton-wrapper"><div class="dropbutton-widget"><ul class="dropbutton">' .
183 '<li><a href="' . $node_url . '/edit?destination=/" hreflang="en">Edit</a></li>' .
184 '<li><a href="' . $node_url . '/delete?destination=/" hreflang="en">Delete</a></li>' .
185 '</ul></div></div>' : '';
186 $output = $view->style_plugin->getField($index, 'operations');
187 $this->assertEqual($output, $expected);
190 $keys = $cache_plugin->getRowCacheKeys($view->result[$index]);
191 $user_context = !$account->hasPermission('edit any test content') ? 'user' : 'user.permissions';
195 'contexts' => ['languages:language_interface', 'theme', $user_context],
198 $element = $render_cache->get($cache);
199 $this->assertTrue($element);