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