3 namespace Drupal\Tests\taxonomy\Functional;
5 use Drupal\Component\Utility\Unicode;
8 * Tests the taxonomy vocabulary permissions.
12 class VocabularyPermissionsTest extends TaxonomyTestBase {
19 public static $modules = ['help'];
21 protected function setUp() {
24 $this->drupalPlaceBlock('page_title_block');
25 $this->drupalPlaceBlock('local_actions_block');
26 $this->drupalPlaceBlock('help_block');
30 * Create, edit and delete a vocabulary via the user interface.
32 public function testVocabularyPermissionsVocabulary() {
33 // VocabularyTest.php already tests for user with "administer taxonomy"
36 // Test as user without proper permissions.
37 $authenticated_user = $this->drupalCreateUser([]);
38 $this->drupalLogin($authenticated_user);
40 $assert_session = $this->assertSession();
42 // Visit the main taxonomy administration page.
43 $this->drupalGet('admin/structure/taxonomy');
44 $assert_session->statusCodeEquals(403);
46 // Test as user with "access taxonomy overview" permissions.
47 $proper_user = $this->drupalCreateUser(['access taxonomy overview']);
48 $this->drupalLogin($proper_user);
50 // Visit the main taxonomy administration page.
51 $this->drupalGet('admin/structure/taxonomy');
52 $assert_session->statusCodeEquals(200);
53 $assert_session->pageTextContains('Vocabulary name');
54 $assert_session->linkNotExists('Add vocabulary');
58 * Test the vocabulary overview permission.
60 public function testTaxonomyVocabularyOverviewPermissions() {
61 // Create two vocabularies, one with two terms, the other without any term.
62 /** @var \Drupal\taxonomy\Entity\Vocabulary $vocabulary1 , $vocabulary2 */
63 $vocabulary1 = $this->createVocabulary();
64 $vocabulary2 = $this->createVocabulary();
65 $vocabulary1_id = $vocabulary1->id();
66 $vocabulary2_id = $vocabulary2->id();
67 $this->createTerm($vocabulary1);
68 $this->createTerm($vocabulary1);
70 // Assert expected help texts on first vocabulary.
71 $edit_help_text = t('You can reorganize the terms in @capital_name using their drag-and-drop handles, and group terms under a parent term by sliding them under and to the right of the parent.', ['@capital_name' => Unicode::ucfirst($vocabulary1->label())]);
72 $no_edit_help_text = t('@capital_name contains the following terms.', ['@capital_name' => Unicode::ucfirst($vocabulary1->label())]);
74 $assert_session = $this->assertSession();
76 // Logged in as admin user with 'administer taxonomy' permission.
77 $admin_user = $this->drupalCreateUser(['administer taxonomy']);
78 $this->drupalLogin($admin_user);
79 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary1_id . '/overview');
80 $assert_session->statusCodeEquals(200);
81 $assert_session->linkExists('Edit');
82 $assert_session->linkExists('Delete');
83 $assert_session->linkExists('Add term');
84 $assert_session->buttonExists('Save');
85 $assert_session->pageTextContains('Weight');
86 $assert_session->fieldExists('Weight');
87 $assert_session->pageTextContains($edit_help_text);
89 // Visit vocabulary overview without terms. 'Add term' should be shown.
90 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary2_id . '/overview');
91 $assert_session->statusCodeEquals(200);
92 $assert_session->pageTextContains('No terms available');
93 $assert_session->linkExists('Add term');
95 // Login as a user without any of the required permissions.
96 $no_permission_user = $this->drupalCreateUser();
97 $this->drupalLogin($no_permission_user);
98 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary1_id . '/overview');
99 $assert_session->statusCodeEquals(403);
100 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary2_id . '/overview');
101 $assert_session->statusCodeEquals(403);
103 // Log in as a user with only the overview permission, neither edit nor
104 // delete operations must be available and no Save button.
105 $overview_only_user = $this->drupalCreateUser(['access taxonomy overview']);
106 $this->drupalLogin($overview_only_user);
107 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary1_id . '/overview');
108 $assert_session->statusCodeEquals(200);
109 $assert_session->linkNotExists('Edit');
110 $assert_session->linkNotExists('Delete');
111 $assert_session->buttonNotExists('Save');
112 $assert_session->pageTextContains('Weight');
113 $assert_session->fieldNotExists('Weight');
114 $assert_session->linkNotExists('Add term');
115 $assert_session->pageTextContains($no_edit_help_text);
117 // Visit vocabulary overview without terms. 'Add term' should not be shown.
118 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary2_id . '/overview');
119 $assert_session->statusCodeEquals(200);
120 $assert_session->pageTextContains('No terms available');
121 $assert_session->linkNotExists('Add term');
123 // Login as a user with permission to edit terms, only edit link should be
125 $edit_user = $this->createUser([
126 'access taxonomy overview',
127 'edit terms in ' . $vocabulary1_id,
128 'edit terms in ' . $vocabulary2_id,
130 $this->drupalLogin($edit_user);
131 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary1_id . '/overview');
132 $assert_session->statusCodeEquals(200);
133 $assert_session->linkExists('Edit');
134 $assert_session->linkNotExists('Delete');
135 $assert_session->buttonExists('Save');
136 $assert_session->pageTextContains('Weight');
137 $assert_session->fieldExists('Weight');
138 $assert_session->linkNotExists('Add term');
139 $assert_session->pageTextContains($edit_help_text);
141 // Visit vocabulary overview without terms. 'Add term' should not be shown.
142 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary2_id . '/overview');
143 $assert_session->statusCodeEquals(200);
144 $assert_session->pageTextContains('No terms available');
145 $assert_session->linkNotExists('Add term');
147 // Login as a user with permission only to delete terms.
148 $edit_delete_user = $this->createUser([
149 'access taxonomy overview',
150 'delete terms in ' . $vocabulary1_id,
151 'delete terms in ' . $vocabulary2_id,
153 $this->drupalLogin($edit_delete_user);
154 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary1_id . '/overview');
155 $assert_session->statusCodeEquals(200);
156 $assert_session->linkNotExists('Edit');
157 $assert_session->linkExists('Delete');
158 $assert_session->linkNotExists('Add term');
159 $assert_session->buttonNotExists('Save');
160 $assert_session->pageTextContains('Weight');
161 $assert_session->fieldNotExists('Weight');
162 $assert_session->pageTextContains($no_edit_help_text);
164 // Visit vocabulary overview without terms. 'Add term' should not be shown.
165 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary2_id . '/overview');
166 $assert_session->statusCodeEquals(200);
167 $assert_session->pageTextContains('No terms available');
168 $assert_session->linkNotExists('Add term');
170 // Login as a user with permission to edit and delete terms.
171 $edit_delete_user = $this->createUser([
172 'access taxonomy overview',
173 'edit terms in ' . $vocabulary1_id,
174 'delete terms in ' . $vocabulary1_id,
175 'edit terms in ' . $vocabulary2_id,
176 'delete terms in ' . $vocabulary2_id,
178 $this->drupalLogin($edit_delete_user);
179 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary1_id . '/overview');
180 $assert_session->statusCodeEquals(200);
181 $assert_session->linkExists('Edit');
182 $assert_session->linkExists('Delete');
183 $assert_session->linkNotExists('Add term');
184 $assert_session->buttonExists('Save');
185 $assert_session->pageTextContains('Weight');
186 $assert_session->fieldExists('Weight');
187 $assert_session->pageTextContains($edit_help_text);
189 // Visit vocabulary overview without terms. 'Add term' should not be shown.
190 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary2_id . '/overview');
191 $assert_session->statusCodeEquals(200);
192 $assert_session->pageTextContains('No terms available');
193 $assert_session->linkNotExists('Add term');
195 // Login as a user with permission to create new terms, only add new term
196 // link should be visible.
197 $edit_user = $this->createUser([
198 'access taxonomy overview',
199 'create terms in ' . $vocabulary1_id,
200 'create terms in ' . $vocabulary2_id,
202 $this->drupalLogin($edit_user);
203 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary1_id . '/overview');
204 $assert_session->statusCodeEquals(200);
205 $assert_session->linkNotExists('Edit');
206 $assert_session->linkNotExists('Delete');
207 $assert_session->linkExists('Add term');
208 $assert_session->buttonNotExists('Save');
209 $assert_session->pageTextContains('Weight');
210 $assert_session->fieldNotExists('Weight');
211 $assert_session->pageTextContains($no_edit_help_text);
213 // Visit vocabulary overview without terms. 'Add term' should not be shown.
214 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary2_id . '/overview');
215 $assert_session->statusCodeEquals(200);
216 $assert_session->pageTextContains('No terms available');
217 $assert_session->linkExists('Add term');
221 * Create, edit and delete a taxonomy term via the user interface.
223 public function testVocabularyPermissionsTaxonomyTerm() {
224 // Vocabulary used for creating, removing and editing terms.
225 $vocabulary = $this->createVocabulary();
227 // Test as admin user.
228 $user = $this->drupalCreateUser(['administer taxonomy']);
229 $this->drupalLogin($user);
231 // Visit the main taxonomy administration page.
232 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/add');
233 $this->assertResponse(200);
234 $this->assertField('edit-name-0-value', 'Add taxonomy term form opened successfully.');
238 $edit['name[0][value]'] = $this->randomMachineName();
240 $this->drupalPostForm(NULL, $edit, t('Save'));
241 $this->assertText(t('Created new term @name.', ['@name' => $edit['name[0][value]']]), 'Term created successfully.');
243 // Verify that the creation message contains a link to a term.
244 $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'term/']);
245 $this->assert(isset($view_link), 'The message area contains a link to a term');
247 $terms = \Drupal::entityTypeManager()
248 ->getStorage('taxonomy_term')
249 ->loadByProperties(['name' => $edit['name[0][value]']]);
250 $term = reset($terms);
253 $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
254 $this->assertResponse(200);
255 $this->assertText($edit['name[0][value]'], 'Edit taxonomy term form opened successfully.');
257 $edit['name[0][value]'] = $this->randomMachineName();
258 $this->drupalPostForm(NULL, $edit, t('Save'));
259 $this->assertText(t('Updated term @name.', ['@name' => $edit['name[0][value]']]), 'Term updated successfully.');
261 // Delete the vocabulary.
262 $this->drupalGet('taxonomy/term/' . $term->id() . '/delete');
263 $this->assertRaw(t('Are you sure you want to delete the @entity-type %label?', ['@entity-type' => 'taxonomy term', '%label' => $edit['name[0][value]']]), 'Delete taxonomy term form opened successfully.');
266 $this->drupalPostForm(NULL, NULL, t('Delete'));
267 $this->assertRaw(t('Deleted term %name.', ['%name' => $edit['name[0][value]']]), 'Term deleted.');
269 // Test as user with "create" permissions.
270 $user = $this->drupalCreateUser(["create terms in {$vocabulary->id()}"]);
271 $this->drupalLogin($user);
273 $assert_session = $this->assertSession();
275 // Create a new term.
276 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/add');
277 $assert_session->statusCodeEquals(200);
278 $assert_session->fieldExists('name[0][value]');
282 $edit['name[0][value]'] = $this->randomMachineName();
284 $this->drupalPostForm(NULL, $edit, t('Save'));
285 $assert_session->pageTextContains(t('Created new term @name.', ['@name' => $edit['name[0][value]']]));
287 $terms = \Drupal::entityTypeManager()
288 ->getStorage('taxonomy_term')
289 ->loadByProperties(['name' => $edit['name[0][value]']]);
290 $term = reset($terms);
292 // Ensure that edit and delete access is denied.
293 $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
294 $assert_session->statusCodeEquals(403);
295 $this->drupalGet('taxonomy/term/' . $term->id() . '/delete');
296 $assert_session->statusCodeEquals(403);
298 // Test as user with "edit" permissions.
299 $user = $this->drupalCreateUser(["edit terms in {$vocabulary->id()}"]);
300 $this->drupalLogin($user);
302 // Visit the main taxonomy administration page.
303 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/add');
304 $this->assertResponse(403, 'Add taxonomy term form open failed.');
306 // Create a test term.
307 $term = $this->createTerm($vocabulary);
310 $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
311 $this->assertResponse(200);
312 $this->assertText($term->getName(), 'Edit taxonomy term form opened successfully.');
314 $edit['name[0][value]'] = $this->randomMachineName();
315 $this->drupalPostForm(NULL, $edit, t('Save'));
316 $this->assertText(t('Updated term @name.', ['@name' => $edit['name[0][value]']]), 'Term updated successfully.');
318 // Verify that the update message contains a link to a term.
319 $view_link = $this->xpath('//div[@class="messages"]//a[contains(@href, :href)]', [':href' => 'term/']);
320 $this->assert(isset($view_link), 'The message area contains a link to a term');
322 // Delete the vocabulary.
323 $this->drupalGet('taxonomy/term/' . $term->id() . '/delete');
324 $this->assertResponse(403, 'Delete taxonomy term form open failed.');
326 // Test as user with "delete" permissions.
327 $user = $this->drupalCreateUser(["delete terms in {$vocabulary->id()}"]);
328 $this->drupalLogin($user);
330 // Visit the main taxonomy administration page.
331 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/add');
332 $this->assertResponse(403, 'Add taxonomy term form open failed.');
334 // Create a test term.
335 $term = $this->createTerm($vocabulary);
338 $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
339 $this->assertResponse(403, 'Edit taxonomy term form open failed.');
341 // Delete the vocabulary.
342 $this->drupalGet('taxonomy/term/' . $term->id() . '/delete');
343 $this->assertRaw(t('Are you sure you want to delete the @entity-type %label?', ['@entity-type' => 'taxonomy term', '%label' => $term->getName()]), 'Delete taxonomy term form opened successfully.');
346 $this->drupalPostForm(NULL, NULL, t('Delete'));
347 $this->assertRaw(t('Deleted term %name.', ['%name' => $term->getName()]), 'Term deleted.');
349 // Test as user without proper permissions.
350 $user = $this->drupalCreateUser();
351 $this->drupalLogin($user);
353 // Visit the main taxonomy administration page.
354 $this->drupalGet('admin/structure/taxonomy/manage/' . $vocabulary->id() . '/add');
355 $this->assertResponse(403, 'Add taxonomy term form open failed.');
357 // Create a test term.
358 $term = $this->createTerm($vocabulary);
361 $this->drupalGet('taxonomy/term/' . $term->id() . '/edit');
362 $this->assertResponse(403, 'Edit taxonomy term form open failed.');
364 // Delete the vocabulary.
365 $this->drupalGet('taxonomy/term/' . $term->id() . '/delete');
366 $this->assertResponse(403, 'Delete taxonomy term form open failed.');