Completed
Pull Request — master (#392)
by
unknown
01:28
created

MailContext::followLinkInMail()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 26
rs 8.439
cc 5
eloc 16
nc 5
nop 3
1
<?php
2
3
namespace Drupal\DrupalExtension\Context;
4
5
use Behat\Gherkin\Node\TableNode;
6
7
/**
8
 * Provides pre-built step definitions for interacting with mail.
9
 */
10
class MailContext extends RawMailContext {
11
12
  /**
13
   * By default, prevent mail from being actually sent out during tests.
14
   *
15
   * @BeforeScenario
16
   */
17
  public function disableMail() {
18
    $this->getMailManager()->disableMail();
19
    // Always reset mail count, in case the default mail manager is being used
20
    // which enables mail collecting automatically when mail is disabled, making
21
    //the use of the @mail tag optional in this case.
22
    $this->mailCount = [];
23
  }
24
25
  /**
26
   * Restore mail sending.
27
   *
28
   * @AfterScenario
29
   */
30
  public function enableMail() {
31
    $this->getMailManager()->enableMail();
32
  }
33
34
  /**
35
   * Allow opting in to actually sending mail out.
36
   *
37
   * @BeforeScenario @sendmail @sendemail
38
   */
39
  public function sendMail() {
40
    $this->getMailManager()->enableMail();
41
  }
42
43
  /**
44
   * Allow opting in to mail collection. When using the default mail manager 
45
   * service, it is not necessary to use this tag.
46
   *
47
   * @BeforeScenario @mail @email
48
   */
49
  public function collectMail() {
50
    $this->getMailManager()->startCollectingMail();
51
  }
52
53
  /**
54
   * Stop collecting mail at scenario end.
55
   *
56
   * @AfterScenario @mail @email
57
   */
58
  public function stopCollectingMail() {
59
    $this->getMailManager()->stopCollectingMail();
60
  }
61
62
  /**
63
   * This is mainly useful for testing this context.
64
   * 
65
   * @When Drupal sends a/an (e)mail:
66
   */
67
  public function DrupalSendsMail(TableNode $fields) {
68
    $mail = [
69
      'body' => $this->getRandom()->name(255),
70
      'subject' => $this->getRandom()->name(20),
71
      'to' => $this->getRandom()->name(10) . '@anonexample.com',
72
      'langcode' => '',
73
    ];
74
    foreach ($fields->getRowsHash() as $field => $value) {
75
      $mail[$field] = $value;
76
    }
77
    $this->getDriver()->sendMail($mail['body'], $mail['subject'], $mail['to'], $mail['langcode']);
0 ignored issues
show
Bug introduced by
The method sendMail() does not seem to exist on object<Drupal\Driver\DrupalDriver>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
78
  }
79
80
  /**
81
   * Check all mail sent during the scenario.
82
   * 
83
   * @Then (a )(an )(e)mail(s) has/have been sent:
84
   * @Then (a )(an )(e)mail(s) has/have been sent to :to:
85
   * @Then (a )(an )(e)mail(s) has/have been sent with the subject :subject:
86
   * @Then (a )(an )(e)mail(s) has/have been sent to :to with the subject :subject:
87
   */
88
  public function mailHasBeenSent(TableNode $expectedMailTable, $to = '', $subject = '') {
89
    $expectedMail = $expectedMailTable->getHash();
90
    $actualMail = $this->getMail(['to' => $to, 'subject' => $subject], FALSE);
91
    $this->compareMail($actualMail, $expectedMail);
92
  }
93
94
  /**
95
   * Check mail sent since the last step that checked mail.
96
   * 
97
   * @Then (a )(an )new (e)mail(s) is/are sent:
98
   * @Then (a )(an )new (e)mail(s) is/are sent to :to:
99
   * @Then (a )(an )new (e)mail(s) is/are sent with the subject :subject:
100
   * @Then (a )(an )new (e)mail(s) is/are sent to :to with the subject :subject:
101
   */
102
  public function newMailIsSent(TableNode $expectedMailTable, $to = '', $subject = '') {
103
    $expectedMail = $expectedMailTable->getHash();
104
    $actualMail = $this->getMail(['to' => $to, 'subject' => $subject], TRUE);
105
    $this->compareMail($actualMail, $expectedMail);
106
  }
107
108
  /**
109
   * Check all mail sent during the scenario.
110
   *
111
   * @Then :count (e)mail(s) has/have been sent
112
   * @Then :count (e)mail(s) has/have been sent to :to
113
   * @Then :count (e)mail(s) has/have been sent with the subject :subject
114
   * @Then :count (e)mail(s) has/have been sent to :to with the subject :subject
115
   */
116
  public function noMailHasBeenSent($count, $to = '', $subject = '') {
117
    $actualMail = $this->getMail(['to' => $to, 'subject' => $subject], FALSE);
118
    $count = $count === 'no' ? 0 : $count;
119
    $count = $count === 'a' ? NULL : $count;
120
    $count = $count === 'an' ? NULL : $count;
121
    $this->assertMailCount($actualMail, $count);
122
  }
123
124
  /**
125
   * Check mail sent since the last step that checked mail.
126
   *
127
   * @Then :count new (e)mail(s) is/are sent
128
   * @Then :count new (e)mail(s) is/are sent to :to
129
   * @Then :count new (e)mail(s) is/are sent with the subject :subject
130
   * @Then :count new (e)mail(s) is/are sent to :to with the subject :subject
131
   */
132
  public function noNewMailIsSent($count, $to = '', $subject = '') {
133
    $actualMail = $this->getMail(['to' => $to, 'subject' => $subject], TRUE);
134
    $count = $count === 'no' ? 0 : $count;
135
    $count = $count === 'a' ? 1 : $count;
136
    $count = $count === 'an' ? 1 : $count;
137
    $this->assertMailCount($actualMail, $count);
138
  }
139
  
140
  /**
141
   * @When I follow the link to :urlFragment from the (e)mail
142
   * @When I follow the link to :urlFragment from the (e)mail to :to
143
   * @When I follow the link to :urlFragment from the (e)mail with the subject :subject
144
   * @When I follow the link to :urlFragment from the (e)mail to :to with the subject :subject
145
   */
146
  public function followLinkInMail($urlFragment, $to = '', $subject = '') {
147
    // Get the mail
148
    $matches = ['to' => $to, 'subject' => $subject];
149
    $mail = $this->getMail($matches, FALSE, -1);
150
    if (count($mail) == 0) {
151
      throw new \Exception('No such mail found.');
152
    }
153
    $body = $mail['body'];
154
155
    // Find web URLs in the mail
156
    $urlPattern = '`.*?((http|https)://[\w#$&+,\/:;[email protected]]+)[^\w#$&+,\/:;[email protected]]*?`i';
157
    if (preg_match_all($urlPattern, $body, $urls)) {
158
      // Visit the first url that contains the desired fragment.
159
      foreach ($urls[1] as $url) {
160
        $match = (strpos(strtolower($url), strtolower($urlFragment)) !== FALSE);
161
        if ($match) {
162
          $this->getMinkContext()->visitPath($url);
163
          return;
164
        }
165
      }
166
      throw new \Exception(sprintf('No URL in mail body contained "%s".', $urlFragment));
167
    }
168
    else {
169
      throw new \Exception('No URL found in mail body.');
170
    }
171
  }
172
173
}
174