3 namespace Drupal\Tests\views\Kernel\Handler;
5 use Drupal\Core\Render\RenderContext;
6 use Drupal\simpletest\ContentTypeCreationTrait;
7 use Drupal\simpletest\NodeCreationTrait;
8 use Drupal\simpletest\UserCreationTrait;
9 use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
10 use Drupal\views\Tests\ViewTestData;
11 use Drupal\views\Views;
14 * Tests the core Drupal\views\Plugin\views\field\Dropbutton handler.
18 class FieldDropbuttonTest extends ViewsKernelTestBase {
20 use ContentTypeCreationTrait;
21 use UserCreationTrait;
22 use NodeCreationTrait;
27 public static $testViews = ['test_dropbutton'];
32 public static $modules = [
45 * @var \Drupal\node\NodeInterface
52 * @var \Drupal\node\NodeInterface
59 * @var \Drupal\node\NodeInterface
66 * @var \Drupal\user\UserInterface
73 protected function setUp($import_test_views = TRUE) {
75 $this->installEntitySchema('node');
76 $this->installEntitySchema('user');
77 $this->installSchema('node', 'node_access');
78 $this->installConfig('node');
79 $this->installConfig('filter');
81 ViewTestData::createTestViews(get_class($this), ['views_test_config']);
82 // Create two node types.
83 $this->createContentType(['type' => 'foo']);
84 $this->createContentType(['type' => 'bar']);
87 $admin = $this->createUser();
90 $this->node1 = $this->createNode([
94 'uid' => $admin->id(),
95 'created' => REQUEST_TIME - 10,
97 $this->node2 = $this->createNode([
101 'uid' => $admin->id(),
102 'created' => REQUEST_TIME - 5,
104 $this->node3 = $this->createNode([
108 'uid' => $admin->id(),
109 'created' => REQUEST_TIME,
112 // Now create a user with the ability to edit bar but not foo.
113 $this->testUser = $this->createUser([
114 'access content overview',
116 'edit any bar content',
117 'delete any bar content',
119 // And switch to that user.
120 $this->container->get('account_switcher')->switchTo($this->testUser);
124 * Tests that dropbutton markup doesn't leak between rows.
126 public function testDropbuttonMarkupShouldNotLeakBetweenRows() {
127 $view = Views::getView('test_dropbutton');
129 $view->preExecute([]);
132 $renderer = $this->container->get('renderer');
133 $dropbutton_output = [];
135 // Render each row and field in turn - the dropbutton plugin relies on
136 // output being set in previous versions.
137 foreach ($view->result as $index => $row) {
138 foreach (array_keys($view->field) as $field) {
139 $output = $renderer->executeInRenderContext(new RenderContext(), function () use ($view, $row, $field) {
140 return $view->field[$field]->advancedRender($row);
142 if ($field === 'dropbutton') {
143 $dropbutton_output[] = $output;
148 // The first row should contain edit links to node 3, as the user has
150 $this->assertContains($this->node3->toUrl('edit-form')->toString(), (string) $dropbutton_output[0]);
151 $this->assertContains($this->node3->toUrl('delete-form')->toString(), (string) $dropbutton_output[0]);
153 // Second row should be not contain links to edit/delete any content as user
154 // has no edit/delete permissions.
155 // It most certainly should not contain links to node 3, as node 2 is the
156 // entity that forms this row.
157 $this->assertNotContains($this->node3->toUrl('edit-form')->toString(), (string) $dropbutton_output[1]);
158 $this->assertNotContains($this->node3->toUrl('delete-form')->toString(), (string) $dropbutton_output[1]);
159 $this->assertNotContains($this->node2->toUrl('edit-form')->toString(), (string) $dropbutton_output[1]);
160 $this->assertNotContains($this->node2->toUrl('delete-form')->toString(), (string) $dropbutton_output[1]);
162 // Third row should contain links for node 1.
163 $this->assertContains($this->node1->toUrl('edit-form')->toString(), (string) $dropbutton_output[2]);
164 $this->assertContains($this->node1->toUrl('delete-form')->toString(), (string) $dropbutton_output[2]);