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

MailContext::mailHasBeenSent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 4
nc 1
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($event) {
18
    $tags = array_merge($event->getFeature()->getTags(), $event->getScenario()->getTags());
19
    if (!in_array('sendmail', $tags) && !in_array('sendemail', $tags)) {
20
      $this->getMailManager()->disableMail();
21
      // Always reset mail count, in case the default mail manager is being used
22
      // which enables mail collecting automatically when mail is disabled, making
23
      //the use of the @mail tag optional in this case.
24
      $this->mailCount = [];
25
    }
26
  }
27
28
  /**
29
   * Restore mail sending.
30
   *
31
   * @AfterScenario
32
   */
33
  public function enableMail($event) {
34
    $tags = array_merge($event->getFeature()->getTags(), $event->getScenario()->getTags());
35
    if (!in_array('sendmail', $tags) && !in_array('sendemail', $tags)) {
36
      $this->getMailManager()->enableMail();
37
    }
38
  }
39
40
  /**
41
   * Allow opting in to mail collection. When using the default mail manager 
42
   * service, it is not necessary to use this tag.
43
   *
44
   * @BeforeScenario @mail @email
45
   */
46
  public function collectMail() {
47
    $this->getMailManager()->startCollectingMail();
48
  }
49
50
  /**
51
   * Stop collecting mail at scenario end.
52
   *
53
   * @AfterScenario @mail @email
54
   */
55
  public function stopCollectingMail() {
56
    $this->getMailManager()->stopCollectingMail();
57
  }
58
59
  /**
60
   * This is mainly useful for testing this context.
61
   * 
62
   * @When Drupal sends a/an (e)mail:
63
   */
64
  public function DrupalSendsMail(TableNode $fields) {
65
    $mail = [
66
      'body' => $this->getRandom()->name(255),
67
      'subject' => $this->getRandom()->name(20),
68
      'to' => $this->getRandom()->name(10) . '@anonexample.com',
69
      'langcode' => '',
70
    ];
71
    foreach ($fields->getRowsHash() as $field => $value) {
72
      $mail[$field] = $value;
73
    }
74
    $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...
75
  }
76
77
  /**
78
   * Check all mail sent during the scenario.
79
   * 
80
   * @Then (a )(an )(e)mail(s) has/have been sent:
81
   * @Then (a )(an )(e)mail(s) has/have been sent to :to:
82
   * @Then (a )(an )(e)mail(s) has/have been sent with the subject :subject:
83
   * @Then (a )(an )(e)mail(s) has/have been sent to :to with the subject :subject:
84
   */
85
  public function mailHasBeenSent(TableNode $expectedMailTable, $to = '', $subject = '') {
86
    $expectedMail = $expectedMailTable->getHash();
87
    $actualMail = $this->getMail(['to' => $to, 'subject' => $subject], FALSE);
88
    $this->compareMail($actualMail, $expectedMail);
89
  }
90
91
  /**
92
   * Check mail sent since the last step that checked mail.
93
   * 
94
   * @Then (a )(an )new (e)mail(s) is/are sent:
95
   * @Then (a )(an )new (e)mail(s) is/are sent to :to:
96
   * @Then (a )(an )new (e)mail(s) is/are sent with the subject :subject:
97
   * @Then (a )(an )new (e)mail(s) is/are sent to :to with the subject :subject:
98
   */
99
  public function newMailIsSent(TableNode $expectedMailTable, $to = '', $subject = '') {
100
    $expectedMail = $expectedMailTable->getHash();
101
    $actualMail = $this->getMail(['to' => $to, 'subject' => $subject], TRUE);
102
    $this->compareMail($actualMail, $expectedMail);
103
  }
104
105
  /**
106
   * Check all mail sent during the scenario.
107
   *
108
   * @Then :count (e)mail(s) has/have been sent
109
   * @Then :count (e)mail(s) has/have been sent to :to
110
   * @Then :count (e)mail(s) has/have been sent with the subject :subject
111
   * @Then :count (e)mail(s) has/have been sent to :to with the subject :subject
112
   */
113
  public function noMailHasBeenSent($count, $to = '', $subject = '') {
114
    $actualMail = $this->getMail(['to' => $to, 'subject' => $subject], FALSE);
115
    $count = $count === 'no' ? 0 : $count;
116
    $count = $count === 'a' ? NULL : $count;
117
    $count = $count === 'an' ? NULL : $count;
118
    $this->assertMailCount($actualMail, $count);
119
  }
120
121
  /**
122
   * Check mail sent since the last step that checked mail.
123
   *
124
   * @Then :count new (e)mail(s) is/are sent
125
   * @Then :count new (e)mail(s) is/are sent to :to
126
   * @Then :count new (e)mail(s) is/are sent with the subject :subject
127
   * @Then :count new (e)mail(s) is/are sent to :to with the subject :subject
128
   */
129
  public function noNewMailIsSent($count, $to = '', $subject = '') {
130
    $actualMail = $this->getMail(['to' => $to, 'subject' => $subject], TRUE);
131
    $count = $count === 'no' ? 0 : $count;
132
    $count = $count === 'a' ? 1 : $count;
133
    $count = $count === 'an' ? 1 : $count;
134
    $this->assertMailCount($actualMail, $count);
135
  }
136
  
137
  /**
138
   * @When I follow the link to :urlFragment from the (e)mail
139
   * @When I follow the link to :urlFragment from the (e)mail to :to
140
   * @When I follow the link to :urlFragment from the (e)mail with the subject :subject
141
   * @When I follow the link to :urlFragment from the (e)mail to :to with the subject :subject
142
   */
143
  public function followLinkInMail($urlFragment, $to = '', $subject = '') {
144
    // Get the mail
145
    $matches = ['to' => $to, 'subject' => $subject];
146
    $mail = $this->getMail($matches, FALSE, -1);
147
    if (count($mail) == 0) {
148
      throw new \Exception('No such mail found.');
149
    }
150
    $body = $mail['body'];
151
152
    // Find web URLs in the mail
153
    $urlPattern = '`.*?((http|https)://[\w#$&+,\/:;[email protected]]+)[^\w#$&+,\/:;[email protected]]*?`i';
154
    if (preg_match_all($urlPattern, $body, $urls)) {
155
      // Visit the first url that contains the desired fragment.
156
      foreach ($urls[1] as $url) {
157
        $match = (strpos(strtolower($url), strtolower($urlFragment)) !== FALSE);
158
        if ($match) {
159
          $this->getMinkContext()->visitPath($url);
160
          return;
161
        }
162
      }
163
      throw new \Exception(sprintf('No URL in mail body contained "%s".', $urlFragment));
164
    }
165
    else {
166
      throw new \Exception('No URL found in mail body.');
167
    }
168
  }
169
170
}
171