Completed
Push — master ( ff385a...5ac460 )
by Jonathan
32s queued 24s
created

Drupal/DrupalExtension/Context/DrupalContext.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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