Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\contextual\Tests;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Component\Serialization\Json;
|
Chris@0
|
6 use Drupal\Core\Url;
|
Chris@0
|
7 use Drupal\language\Entity\ConfigurableLanguage;
|
Chris@0
|
8 use Drupal\simpletest\WebTestBase;
|
Chris@0
|
9 use Drupal\Core\Template\Attribute;
|
Chris@0
|
10
|
Chris@0
|
11 /**
|
Chris@0
|
12 * Tests if contextual links are showing on the front page depending on
|
Chris@0
|
13 * permissions.
|
Chris@0
|
14 *
|
Chris@0
|
15 * @group contextual
|
Chris@0
|
16 */
|
Chris@0
|
17 class ContextualDynamicContextTest extends WebTestBase {
|
Chris@0
|
18
|
Chris@0
|
19 /**
|
Chris@0
|
20 * A user with permission to access contextual links and edit content.
|
Chris@0
|
21 *
|
Chris@0
|
22 * @var \Drupal\user\UserInterface
|
Chris@0
|
23 */
|
Chris@0
|
24 protected $editorUser;
|
Chris@0
|
25
|
Chris@0
|
26 /**
|
Chris@0
|
27 * An authenticated user with permission to access contextual links.
|
Chris@0
|
28 *
|
Chris@0
|
29 * @var \Drupal\user\UserInterface
|
Chris@0
|
30 */
|
Chris@0
|
31 protected $authenticatedUser;
|
Chris@0
|
32
|
Chris@0
|
33 /**
|
Chris@0
|
34 * A simulated anonymous user with access only to node content.
|
Chris@0
|
35 *
|
Chris@0
|
36 * @var \Drupal\user\UserInterface
|
Chris@0
|
37 */
|
Chris@0
|
38 protected $anonymousUser;
|
Chris@0
|
39
|
Chris@0
|
40 /**
|
Chris@0
|
41 * Modules to enable.
|
Chris@0
|
42 *
|
Chris@0
|
43 * @var array
|
Chris@0
|
44 */
|
Chris@0
|
45 public static $modules = ['contextual', 'node', 'views', 'views_ui', 'language', 'menu_test'];
|
Chris@0
|
46
|
Chris@0
|
47 protected function setUp() {
|
Chris@0
|
48 parent::setUp();
|
Chris@0
|
49
|
Chris@0
|
50 $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
|
Chris@0
|
51 $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
|
Chris@0
|
52
|
Chris@0
|
53 ConfigurableLanguage::createFromLangcode('it')->save();
|
Chris@0
|
54 $this->rebuildContainer();
|
Chris@0
|
55
|
Chris@0
|
56 $this->editorUser = $this->drupalCreateUser(['access content', 'access contextual links', 'edit any article content']);
|
Chris@0
|
57 $this->authenticatedUser = $this->drupalCreateUser(['access content', 'access contextual links']);
|
Chris@0
|
58 $this->anonymousUser = $this->drupalCreateUser(['access content']);
|
Chris@0
|
59 }
|
Chris@0
|
60
|
Chris@0
|
61 /**
|
Chris@0
|
62 * Tests contextual links with different permissions.
|
Chris@0
|
63 *
|
Chris@0
|
64 * Ensures that contextual link placeholders always exist, even if the user is
|
Chris@0
|
65 * not allowed to use contextual links.
|
Chris@0
|
66 */
|
Chris@0
|
67 public function testDifferentPermissions() {
|
Chris@0
|
68 $this->drupalLogin($this->editorUser);
|
Chris@0
|
69
|
Chris@0
|
70 // Create three nodes in the following order:
|
Chris@0
|
71 // - An article, which should be user-editable.
|
Chris@0
|
72 // - A page, which should not be user-editable.
|
Chris@0
|
73 // - A second article, which should also be user-editable.
|
Chris@0
|
74 $node1 = $this->drupalCreateNode(['type' => 'article', 'promote' => 1]);
|
Chris@0
|
75 $node2 = $this->drupalCreateNode(['type' => 'page', 'promote' => 1]);
|
Chris@0
|
76 $node3 = $this->drupalCreateNode(['type' => 'article', 'promote' => 1]);
|
Chris@0
|
77
|
Chris@0
|
78 // Now, on the front page, all article nodes should have contextual links
|
Chris@0
|
79 // placeholders, as should the view that contains them.
|
Chris@0
|
80 $ids = [
|
Chris@0
|
81 'node:node=' . $node1->id() . ':changed=' . $node1->getChangedTime() . '&langcode=en',
|
Chris@0
|
82 'node:node=' . $node2->id() . ':changed=' . $node2->getChangedTime() . '&langcode=en',
|
Chris@0
|
83 'node:node=' . $node3->id() . ':changed=' . $node3->getChangedTime() . '&langcode=en',
|
Chris@0
|
84 'entity.view.edit_form:view=frontpage:location=page&name=frontpage&display_id=page_1&langcode=en',
|
Chris@0
|
85 ];
|
Chris@0
|
86
|
Chris@0
|
87 // Editor user: can access contextual links and can edit articles.
|
Chris@0
|
88 $this->drupalGet('node');
|
Chris@0
|
89 for ($i = 0; $i < count($ids); $i++) {
|
Chris@0
|
90 $this->assertContextualLinkPlaceHolder($ids[$i]);
|
Chris@0
|
91 }
|
Chris@0
|
92 $this->renderContextualLinks([], 'node');
|
Chris@0
|
93 $this->assertResponse(400);
|
Chris@0
|
94 $this->assertRaw('No contextual ids specified.');
|
Chris@0
|
95 $response = $this->renderContextualLinks($ids, 'node');
|
Chris@0
|
96 $this->assertResponse(200);
|
Chris@0
|
97 $json = Json::decode($response);
|
Chris@0
|
98 $this->assertIdentical($json[$ids[0]], '<ul class="contextual-links"><li class="entitynodeedit-form"><a href="' . base_path() . 'node/1/edit">Edit</a></li></ul>');
|
Chris@0
|
99 $this->assertIdentical($json[$ids[1]], '');
|
Chris@0
|
100 $this->assertIdentical($json[$ids[2]], '<ul class="contextual-links"><li class="entitynodeedit-form"><a href="' . base_path() . 'node/3/edit">Edit</a></li></ul>');
|
Chris@0
|
101 $this->assertIdentical($json[$ids[3]], '');
|
Chris@0
|
102
|
Chris@0
|
103 // Verify that link language is properly handled.
|
Chris@0
|
104 $node3->addTranslation('it')->set('title', $this->randomString())->save();
|
Chris@0
|
105 $id = 'node:node=' . $node3->id() . ':changed=' . $node3->getChangedTime() . '&langcode=it';
|
Chris@0
|
106 $this->drupalGet('node', ['language' => ConfigurableLanguage::createFromLangcode('it')]);
|
Chris@0
|
107 $this->assertContextualLinkPlaceHolder($id);
|
Chris@0
|
108
|
Chris@0
|
109 // Authenticated user: can access contextual links, cannot edit articles.
|
Chris@0
|
110 $this->drupalLogin($this->authenticatedUser);
|
Chris@0
|
111 $this->drupalGet('node');
|
Chris@0
|
112 for ($i = 0; $i < count($ids); $i++) {
|
Chris@0
|
113 $this->assertContextualLinkPlaceHolder($ids[$i]);
|
Chris@0
|
114 }
|
Chris@0
|
115 $this->renderContextualLinks([], 'node');
|
Chris@0
|
116 $this->assertResponse(400);
|
Chris@0
|
117 $this->assertRaw('No contextual ids specified.');
|
Chris@0
|
118 $response = $this->renderContextualLinks($ids, 'node');
|
Chris@0
|
119 $this->assertResponse(200);
|
Chris@0
|
120 $json = Json::decode($response);
|
Chris@0
|
121 $this->assertIdentical($json[$ids[0]], '');
|
Chris@0
|
122 $this->assertIdentical($json[$ids[1]], '');
|
Chris@0
|
123 $this->assertIdentical($json[$ids[2]], '');
|
Chris@0
|
124 $this->assertIdentical($json[$ids[3]], '');
|
Chris@0
|
125
|
Chris@0
|
126 // Anonymous user: cannot access contextual links.
|
Chris@0
|
127 $this->drupalLogin($this->anonymousUser);
|
Chris@0
|
128 $this->drupalGet('node');
|
Chris@0
|
129 for ($i = 0; $i < count($ids); $i++) {
|
Chris@0
|
130 $this->assertNoContextualLinkPlaceHolder($ids[$i]);
|
Chris@0
|
131 }
|
Chris@0
|
132 $this->renderContextualLinks([], 'node');
|
Chris@0
|
133 $this->assertResponse(403);
|
Chris@0
|
134 $this->renderContextualLinks($ids, 'node');
|
Chris@0
|
135 $this->assertResponse(403);
|
Chris@0
|
136
|
Chris@0
|
137 // Get a page where contextual links are directly rendered.
|
Chris@0
|
138 $this->drupalGet(Url::fromRoute('menu_test.contextual_test'));
|
Chris@0
|
139 $this->assertEscaped("<script>alert('Welcome to the jungle!')</script>");
|
Chris@0
|
140 $this->assertRaw('<li class="menu-testcontextual-hidden-manage-edit"><a href="' . base_path() . 'menu-test-contextual/1/edit" class="use-ajax" data-dialog-type="modal" data-is-something>Edit menu - contextual</a></li>');
|
Chris@0
|
141 }
|
Chris@0
|
142
|
Chris@0
|
143 /**
|
Chris@0
|
144 * Asserts that a contextual link placeholder with the given id exists.
|
Chris@0
|
145 *
|
Chris@0
|
146 * @param string $id
|
Chris@0
|
147 * A contextual link id.
|
Chris@0
|
148 *
|
Chris@0
|
149 * @return bool
|
Chris@0
|
150 * The result of the assertion.
|
Chris@0
|
151 */
|
Chris@0
|
152 protected function assertContextualLinkPlaceHolder($id) {
|
Chris@0
|
153 return $this->assertRaw('<div' . new Attribute(['data-contextual-id' => $id]) . '></div>', format_string('Contextual link placeholder with id @id exists.', ['@id' => $id]));
|
Chris@0
|
154 }
|
Chris@0
|
155
|
Chris@0
|
156 /**
|
Chris@0
|
157 * Asserts that a contextual link placeholder with the given id does not exist.
|
Chris@0
|
158 *
|
Chris@0
|
159 * @param string $id
|
Chris@0
|
160 * A contextual link id.
|
Chris@0
|
161 *
|
Chris@0
|
162 * @return bool
|
Chris@0
|
163 * The result of the assertion.
|
Chris@0
|
164 */
|
Chris@0
|
165 protected function assertNoContextualLinkPlaceHolder($id) {
|
Chris@0
|
166 return $this->assertNoRaw('<div' . new Attribute(['data-contextual-id' => $id]) . '></div>', format_string('Contextual link placeholder with id @id does not exist.', ['@id' => $id]));
|
Chris@0
|
167 }
|
Chris@0
|
168
|
Chris@0
|
169 /**
|
Chris@0
|
170 * Get server-rendered contextual links for the given contextual link ids.
|
Chris@0
|
171 *
|
Chris@0
|
172 * @param array $ids
|
Chris@0
|
173 * An array of contextual link ids.
|
Chris@0
|
174 * @param string $current_path
|
Chris@0
|
175 * The Drupal path for the page for which the contextual links are rendered.
|
Chris@0
|
176 *
|
Chris@0
|
177 * @return string
|
Chris@0
|
178 * The response body.
|
Chris@0
|
179 */
|
Chris@0
|
180 protected function renderContextualLinks($ids, $current_path) {
|
Chris@0
|
181 $post = [];
|
Chris@0
|
182 for ($i = 0; $i < count($ids); $i++) {
|
Chris@0
|
183 $post['ids[' . $i . ']'] = $ids[$i];
|
Chris@0
|
184 }
|
Chris@0
|
185 return $this->drupalPostWithFormat('contextual/render', 'json', $post, ['query' => ['destination' => $current_path]]);
|
Chris@0
|
186 }
|
Chris@0
|
187
|
Chris@0
|
188 }
|