Security update for permissions_by_term
[yaffs-website] / vendor / drupal / drupal-extension / src / Drupal / DrupalExtension / Context / DrupalContext.php
1 <?php
2
3 namespace Drupal\DrupalExtension\Context;
4
5 use Behat\Behat\Context\TranslatableContext;
6 use Behat\Mink\Element\Element;
7
8 use Behat\Gherkin\Node\TableNode;
9
10 /**
11  * Provides pre-built step definitions for interacting with Drupal.
12  */
13 class DrupalContext extends RawDrupalContext implements TranslatableContext {
14
15   /**
16    * Returns list of definition translation resources paths.
17    *
18    * @return array
19    */
20   public static function getTranslationResources() {
21     return glob(__DIR__ . '/../../../../i18n/*.xliff');
22   }
23
24   /**
25    * @Given I am an anonymous user
26    * @Given I am not logged in
27    */
28   public function assertAnonymousUser() {
29     // Verify the user is logged out.
30     if ($this->loggedIn()) {
31       $this->logout();
32     }
33   }
34
35   /**
36    * Creates and authenticates a user with the given role(s).
37    *
38    * @Given I am logged in as a user with the :role role(s)
39    * @Given I am logged in as a/an :role
40    */
41   public function assertAuthenticatedByRole($role) {
42     // Check if a user with this role is already logged in.
43     if (!$this->loggedInWithRole($role)) {
44       // Create user (and project)
45       $user = (object) array(
46         'name' => $this->getRandom()->name(8),
47         'pass' => $this->getRandom()->name(16),
48         'role' => $role,
49       );
50       $user->mail = "{$user->name}@example.com";
51
52       $this->userCreate($user);
53
54       $roles = explode(',', $role);
55       $roles = array_map('trim', $roles);
56       foreach ($roles as $role) {
57         if (!in_array(strtolower($role), array('authenticated', 'authenticated user'))) {
58           // Only add roles other than 'authenticated user'.
59           $this->getDriver()->userAddRole($user, $role);
60         }
61       }
62
63       // Login.
64       $this->login();
65     }
66   }
67
68   /**
69    * Creates and authenticates a user with the given role(s) and given fields.
70    * | field_user_name     | John  |
71    * | field_user_surname  | Smith |
72    * | ...                 | ...   |
73    *
74    * @Given I am logged in as a user with the :role role(s) and I have the following fields:
75    */
76   public function assertAuthenticatedByRoleWithGivenFields($role, TableNode $fields) {
77     // Check if a user with this role is already logged in.
78     if (!$this->loggedInWithRole($role)) {
79       // Create user (and project)
80       $user = (object) array(
81         'name' => $this->getRandom()->name(8),
82         'pass' => $this->getRandom()->name(16),
83         'role' => $role,
84       );
85       $user->mail = "{$user->name}@example.com";
86
87       // Assign fields to user before creation.
88       foreach ($fields->getRowsHash() as $field => $value) {
89         $user->{$field} = $value;
90       }
91
92       $this->userCreate($user);
93
94       $roles = explode(',', $role);
95       $roles = array_map('trim', $roles);
96       foreach ($roles as $role) {
97         if (!in_array(strtolower($role), array('authenticated', 'authenticated user'))) {
98           // Only add roles other than 'authenticated user'.
99           $this->getDriver()->userAddRole($user, $role);
100         }
101       }
102
103       // Login.
104       $this->login();
105     }
106   }
107
108
109   /**
110    * @Given I am logged in as :name
111    */
112   public function assertLoggedInByName($name) {
113     if (!isset($this->users[$name])) {
114       throw new \Exception(sprintf('No user with %s name is registered with the driver.', $name));
115     }
116
117     // Change internal current user.
118     $this->user = $this->users[$name];
119
120     // Login.
121     $this->login();
122   }
123
124   /**
125    * @Given I am logged in as a user with the :permissions permission(s)
126    */
127   public function assertLoggedInWithPermissions($permissions) {
128     // Create user.
129     $user = (object) array(
130       'name' => $this->getRandom()->name(8),
131       'pass' => $this->getRandom()->name(16),
132     );
133     $user->mail = "{$user->name}@example.com";
134     $this->userCreate($user);
135
136     // Create and assign a temporary role with given permissions.
137     $permissions = array_map('trim', explode(',', $permissions));
138     $rid = $this->getDriver()->roleCreate($permissions);
139     $this->getDriver()->userAddRole($user, $rid);
140     $this->roles[] = $rid;
141
142     // Login.
143     $this->login();
144   }
145
146   /**
147    * Retrieve a table row containing specified text from a given element.
148    *
149    * @param \Behat\Mink\Element\Element
150    * @param string
151    *   The text to search for in the table row.
152    *
153    * @return \Behat\Mink\Element\NodeElement
154    *
155    * @throws \Exception
156    */
157   public function getTableRow(Element $element, $search) {
158     $rows = $element->findAll('css', 'tr');
159     if (empty($rows)) {
160       throw new \Exception(sprintf('No rows found on the page %s', $this->getSession()->getCurrentUrl()));
161     }
162     foreach ($rows as $row) {
163       if (strpos($row->getText(), $search) !== FALSE) {
164         return $row;
165       }
166     }
167     throw new \Exception(sprintf('Failed to find a row containing "%s" on the page %s', $search, $this->getSession()->getCurrentUrl()));
168   }
169
170   /**
171    * Find text in a table row containing given text.
172    *
173    * @Then I should see (the text ):text in the :rowText row
174    */
175   public function assertTextInTableRow($text, $rowText) {
176     $row = $this->getTableRow($this->getSession()->getPage(), $rowText);
177     if (strpos($row->getText(), $text) === FALSE) {
178       throw new \Exception(sprintf('Found a row containing "%s", but it did not contain the text "%s".', $rowText, $text));
179     }
180   }
181
182   /**
183    * Asset text not in a table row containing given text.
184    *
185    * @Then I should not see (the text ):text in the :rowText row
186    */
187   public function assertTextNotInTableRow($text, $rowText) {
188     $row = $this->getTableRow($this->getSession()->getPage(), $rowText);
189     if (strpos($row->getText(), $text) !== FALSE) {
190       throw new \Exception(sprintf('Found a row containing "%s", but it contained the text "%s".', $rowText, $text));
191     }
192   }
193
194   /**
195    * Attempts to find a link in a table row containing giving text. This is for
196    * administrative pages such as the administer content types screen found at
197    * `admin/structure/types`.
198    *
199    * @Given I click :link in the :rowText row
200    * @Then I (should )see the :link in the :rowText row
201    */
202   public function assertClickInTableRow($link, $rowText) {
203     $page = $this->getSession()->getPage();
204     if ($link_element = $this->getTableRow($page, $rowText)->findLink($link)) {
205       // Click the link and return.
206       $link_element->click();
207       return;
208     }
209     throw new \Exception(sprintf('Found a row containing "%s", but no "%s" link on the page %s', $rowText, $link, $this->getSession()->getCurrentUrl()));
210   }
211
212   /**
213    * @Given the cache has been cleared
214    */
215   public function assertCacheClear() {
216     $this->getDriver()->clearCache();
217   }
218
219   /**
220    * @Given I run cron
221    */
222   public function assertCron() {
223     $this->getDriver()->runCron();
224   }
225
226   /**
227    * Creates content of the given type.
228    *
229    * @Given I am viewing a/an :type (content )with the title :title
230    * @Given a/an :type (content )with the title :title
231    */
232   public function createNode($type, $title) {
233     // @todo make this easily extensible.
234     $node = (object) array(
235       'title' => $title,
236       'type' => $type,
237     );
238     $saved = $this->nodeCreate($node);
239     // Set internal page on the new node.
240     $this->getSession()->visit($this->locatePath('/node/' . $saved->nid));
241   }
242
243   /**
244    * Creates content authored by the current user.
245    *
246    * @Given I am viewing my :type (content )with the title :title
247    */
248   public function createMyNode($type, $title) {
249     if (!isset($this->user->uid)) {
250       throw new \Exception(sprintf('There is no current logged in user to create a node for.'));
251     }
252
253     $node = (object) array(
254       'title' => $title,
255       'type' => $type,
256       'body' => $this->getRandom()->name(255),
257       'uid' => $this->user->uid,
258     );
259     $saved = $this->nodeCreate($node);
260
261     // Set internal page on the new node.
262     $this->getSession()->visit($this->locatePath('/node/' . $saved->nid));
263   }
264
265   /**
266    * Creates content of a given type provided in the form:
267    * | title    | author     | status | created           |
268    * | My title | Joe Editor | 1      | 2014-10-17 8:00am |
269    * | ...      | ...        | ...    | ...               |
270    *
271    * @Given :type content:
272    */
273   public function createNodes($type, TableNode $nodesTable) {
274     foreach ($nodesTable->getHash() as $nodeHash) {
275       $node = (object) $nodeHash;
276       $node->type = $type;
277       $this->nodeCreate($node);
278     }
279   }
280
281   /**
282    * Creates content of the given type, provided in the form:
283    * | title     | My node        |
284    * | Field One | My field value |
285    * | author    | Joe Editor     |
286    * | status    | 1              |
287    * | ...       | ...            |
288    *
289    * @Given I am viewing a/an :type( content):
290    */
291   public function assertViewingNode($type, TableNode $fields) {
292     $node = (object) array(
293       'type' => $type,
294     );
295     foreach ($fields->getRowsHash() as $field => $value) {
296       $node->{$field} = $value;
297     }
298
299     $saved = $this->nodeCreate($node);
300
301     // Set internal browser on the node.
302     $this->getSession()->visit($this->locatePath('/node/' . $saved->nid));
303   }
304
305   /**
306    * Asserts that a given content type is editable.
307    *
308    * @Then I should be able to edit a/an :type( content)
309    */
310   public function assertEditNodeOfType($type) {
311     $node = (object) array(
312       'type' => $type,
313       'title' => "Test $type",
314     );
315     $saved = $this->nodeCreate($node);
316
317     // Set internal browser on the node edit page.
318     $this->getSession()->visit($this->locatePath('/node/' . $saved->nid . '/edit'));
319
320     // Test status.
321     $this->assertSession()->statusCodeEquals('200');
322   }
323
324
325   /**
326    * Creates a term on an existing vocabulary.
327    *
328    * @Given I am viewing a/an :vocabulary term with the name :name
329    * @Given a/an :vocabulary term with the name :name
330    */
331   public function createTerm($vocabulary, $name) {
332     // @todo make this easily extensible.
333     $term = (object) array(
334       'name' => $name,
335       'vocabulary_machine_name' => $vocabulary,
336       'description' => $this->getRandom()->name(255),
337     );
338     $saved = $this->termCreate($term);
339
340     // Set internal page on the term.
341     $this->getSession()->visit($this->locatePath('/taxonomy/term/' . $saved->tid));
342   }
343
344   /**
345    * Creates multiple users.
346    *
347    * Provide user data in the following format:
348    *
349    * | name     | mail         | roles        |
350    * | user foo | foo@bar.com  | role1, role2 |
351    *
352    * @Given users:
353    */
354   public function createUsers(TableNode $usersTable) {
355     foreach ($usersTable->getHash() as $userHash) {
356
357       // Split out roles to process after user is created.
358       $roles = array();
359       if (isset($userHash['roles'])) {
360         $roles = explode(',', $userHash['roles']);
361         $roles = array_filter(array_map('trim', $roles));
362         unset($userHash['roles']);
363       }
364
365       $user = (object) $userHash;
366       // Set a password.
367       if (!isset($user->pass)) {
368         $user->pass = $this->getRandom()->name();
369       }
370       $this->userCreate($user);
371
372       // Assign roles.
373       foreach ($roles as $role) {
374         $this->getDriver()->userAddRole($user, $role);
375       }
376     }
377   }
378
379   /**
380    * Creates one or more terms on an existing vocabulary.
381    *
382    * Provide term data in the following format:
383    *
384    * | name  | parent | description | weight | taxonomy_field_image |
385    * | Snook | Fish   | Marine fish | 10     | snook-123.jpg        |
386    * | ...   | ...    | ...         | ...    | ...                  |
387    *
388    * Only the 'name' field is required.
389    *
390    * @Given :vocabulary terms:
391    */
392   public function createTerms($vocabulary, TableNode $termsTable) {
393     foreach ($termsTable->getHash() as $termsHash) {
394       $term = (object) $termsHash;
395       $term->vocabulary_machine_name = $vocabulary;
396       $this->termCreate($term);
397     }
398   }
399
400   /**
401    * Creates one or more languages.
402    *
403    * @Given the/these (following )languages are available:
404    *
405    * Provide language data in the following format:
406    *
407    * | langcode |
408    * | en       |
409    * | fr       |
410    *
411    * @param TableNode $langcodesTable
412    *   The table listing languages by their ISO code.
413    */
414   public function createLanguages(TableNode $langcodesTable) {
415     foreach ($langcodesTable->getHash() as $row) {
416       $language = (object) array(
417         'langcode' => $row['languages'],
418       );
419       $this->languageCreate($language);
420     }
421   }
422
423   /**
424    * Pauses the scenario until the user presses a key. Useful when debugging a scenario.
425    *
426    * @Then (I )break
427    */
428     public function iPutABreakpoint()
429     {
430       fwrite(STDOUT, "\033[s \033[93m[Breakpoint] Press \033[1;93m[RETURN]\033[0;93m to continue, or 'q' to quit...\033[0m");
431       do {
432         $line = trim(fgets(STDIN, 1024));
433         //Note: this assumes ASCII encoding.  Should probably be revamped to
434         //handle other character sets.
435         $charCode = ord($line);
436         switch($charCode){
437           case 0: //CR
438           case 121: //y
439           case 89: //Y
440             break 2;
441           // case 78: //N
442           // case 110: //n
443           case 113: //q
444           case 81: //Q
445             throw new \Exception("Exiting test intentionally.");
446           default:
447             fwrite(STDOUT, sprintf("\nInvalid entry '%s'.  Please enter 'y', 'q', or the enter key.\n", $line));
448           break;
449         }
450       } while (true);
451       fwrite(STDOUT, "\033[u");
452     }
453
454 }