Completed
Pull Request — 3.1 (#290)
by
unknown
09:17
created

DrupalContext::createLanguages()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 5
nc 2
nop 1
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 View Code Duplication
      foreach ($roles as $role) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
      foreach ($roles as $role) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 = 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
   * Attempts to find a link in a table row containing giving text. This is for
184
   * administrative pages such as the administer content types screen found at
185
   * `admin/structure/types`.
186
   *
187
   * @Given I click :link in the :rowText row
188
   * @Then I (should )see the :link in the :rowText row
189
   */
190
  public function assertClickInTableRow($link, $rowText) {
191
    $page = $this->getSession()->getPage();
192
    if ($link_element = $this->getTableRow($page, $rowText)->findLink($link)) {
193
      // Click the link and return.
194
      $link_element->click();
195
      return;
196
    }
197
    throw new \Exception(sprintf('Found a row containing "%s", but no "%s" link on the page %s', $rowText, $link, $this->getSession()->getCurrentUrl()));
198
  }
199
200
  /**
201
   * @Given the cache has been cleared
202
   */
203
  public function assertCacheClear() {
204
    $this->getDriver()->clearCache();
205
  }
206
207
  /**
208
   * @Given I run cron
209
   */
210
  public function assertCron() {
211
    $this->getDriver()->runCron();
212
  }
213
214
  /**
215
   * Creates content of the given type.
216
   *
217
   * @Given I am viewing a/an :type (content )with the title :title
218
   * @Given a/an :type (content )with the title :title
219
   */
220 View Code Duplication
  public function createNode($type, $title) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
221
    // @todo make this easily extensible.
222
    $node = (object) array(
223
      'title' => $title,
224
      'type' => $type,
225
      'body' => $this->getRandom()->string(255),
226
    );
227
    $saved = $this->nodeCreate($node);
228
    // Set internal page on the new node.
229
    $this->getSession()->visit($this->locatePath('/node/' . $saved->nid));
230
  }
231
232
  /**
233
   * Creates content authored by the current user.
234
   *
235
   * @Given I am viewing my :type (content )with the title :title
236
   */
237
  public function createMyNode($type, $title) {
238
    if (!isset($this->user->uid)) {
239
      throw new \Exception(sprintf('There is no current logged in user to create a node for.'));
240
    }
241
242
    $node = (object) array(
243
      'title' => $title,
244
      'type' => $type,
245
      'body' => $this->getRandom()->string(255),
246
      'uid' => $this->user->uid,
247
    );
248
    $saved = $this->nodeCreate($node);
249
250
    // Set internal page on the new node.
251
    $this->getSession()->visit($this->locatePath('/node/' . $saved->nid));
252
  }
253
254
  /**
255
   * Creates content of a given type provided in the form:
256
   * | title    | author     | status | created           |
257
   * | My title | Joe Editor | 1      | 2014-10-17 8:00am |
258
   * | ...      | ...        | ...    | ...               |
259
   *
260
   * @Given :type content:
261
   */
262
  public function createNodes($type, TableNode $nodesTable) {
263
    foreach ($nodesTable->getHash() as $nodeHash) {
264
      $node = (object) $nodeHash;
265
      $node->type = $type;
266
      $this->nodeCreate($node);
267
    }
268
  }
269
270
  /**
271
   * Creates content of the given type, provided in the form:
272
   * | title     | My node        |
273
   * | Field One | My field value |
274
   * | author    | Joe Editor     |
275
   * | status    | 1              |
276
   * | ...       | ...            |
277
   *
278
   * @Given I am viewing a/an :type( content):
279
   */
280
  public function assertViewingNode($type, TableNode $fields) {
281
    $node = (object) array(
282
      'type' => $type,
283
    );
284
    foreach ($fields->getRowsHash() as $field => $value) {
285
      $node->{$field} = $value;
286
    }
287
288
    $saved = $this->nodeCreate($node);
289
290
    // Set internal browser on the node.
291
    $this->getSession()->visit($this->locatePath('/node/' . $saved->nid));
292
  }
293
294
  /**
295
   * Asserts that a given content type is editable.
296
   *
297
   * @Then I should be able to edit a/an :type( content)
298
   */
299 View Code Duplication
  public function assertEditNodeOfType($type) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
300
    $node = (object) array('type' => $type);
301
    $saved = $this->nodeCreate($node);
302
303
    // Set internal browser on the node edit page.
304
    $this->getSession()->visit($this->locatePath('/node/' . $saved->nid . '/edit'));
305
306
    // Test status.
307
    $this->assertSession()->statusCodeEquals('200');
308
  }
309
310
311
  /**
312
   * Creates a term on an existing vocabulary.
313
   *
314
   * @Given I am viewing a/an :vocabulary term with the name :name
315
   * @Given a/an :vocabulary term with the name :name
316
   */
317 View Code Duplication
  public function createTerm($vocabulary, $name) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
318
    // @todo make this easily extensible.
319
    $term = (object) array(
320
      'name' => $name,
321
      'vocabulary_machine_name' => $vocabulary,
322
      'description' => $this->getRandom()->string(255),
323
    );
324
    $saved = $this->termCreate($term);
325
326
    // Set internal page on the term.
327
    $this->getSession()->visit($this->locatePath('/taxonomy/term/' . $saved->tid));
328
  }
329
330
  /**
331
   * Creates multiple users.
332
   *
333
   * Provide user data in the following format:
334
   *
335
   * | name     | mail         | roles        |
336
   * | user foo | [email protected]  | role1, role2 |
337
   *
338
   * @Given users:
339
   */
340
  public function createUsers(TableNode $usersTable) {
341
    foreach ($usersTable->getHash() as $userHash) {
342
343
      // Split out roles to process after user is created.
344
      $roles = array();
345
      if (isset($userHash['roles'])) {
346
        $roles = explode(',', $userHash['roles']);
347
        $roles = array_filter(array_map('trim', $roles));
348
        unset($userHash['roles']);
349
      }
350
351
      $user = (object) $userHash;
352
      // Set a password.
353
      if (!isset($user->pass)) {
354
        $user->pass = $this->getRandom()->name();
355
      }
356
      $this->userCreate($user);
357
358
      // Assign roles.
359
      foreach ($roles as $role) {
360
        $this->getDriver()->userAddRole($user, $role);
361
      }
362
    }
363
  }
364
365
  /**
366
   * Creates one or more terms on an existing vocabulary.
367
   *
368
   * @Given :vocabulary terms:
369
   */
370
  public function createTerms($vocabulary, TableNode $termsTable) {
371
    foreach ($termsTable->getHash() as $termsHash) {
372
      $term = (object) $termsHash;
373
      $term->vocabulary_machine_name = $vocabulary;
374
      $this->termCreate($term);
375
    }
376
  }
377
378
  /**
379
   * Creates one or more languages.
380
   *
381
   * @Given the/these (following )languages are available:
382
   *
383
   * Provide language data in the following format:
384
   *
385
   * | langcode |
386
   * | en       |
387
   * | fr       |
388
   *
389
   * @param TableNode $langcodesTable
390
   *   The table listing languages by their ISO code.
391
   */
392
  public function createLanguages(TableNode $langcodesTable) {
393
    foreach ($langcodesTable->getHash() as $row) {
394
      $language = (object) array(
395
        'langcode' => $row['languages'],
396
      );
397
      $this->languageCreate($language);
398
    }
399
  }
400
401
  /**
402
   * Pauses the scenario until the user presses a key. Useful when debugging a scenario.
403
   *
404
   * @Then (I )break
405
   */
406
    public function iPutABreakpoint()
407
    {
408
      fwrite(STDOUT, "\033[s \033[93m[Breakpoint] Press \033[1;93m[RETURN]\033[0;93m to continue...\033[0m");
409
      while (fgets(STDIN, 1024) == '') {}
410
      fwrite(STDOUT, "\033[u");
411
      return;
412
    }
413
414
}
415