Completed
Push — master ( 1aa097...88444f )
by Jimmy
02:15
created

MailTracking::seeEmailSubjectContains()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 8
rs 9.4285
cc 1
eloc 5
nc 1
nop 2
1
<?php
2
3
namespace Spinen\MailAssertions;
4
5
use Illuminate\Support\Facades\Mail;
6
use PHPUnit_Framework_TestCase;
7
use Swift_Message;
8
9
/**
10
 * Class MailTracking
11
 *
12
 * Trait to mixin to your test to allow for custom assertions when using PHPUnit with Laravel.
13
 *
14
 * This originally started out as a copy & paste from a video series that Jeffrey Way did on laracasts.com. If you do
15
 * not have an account on Laracasts, you should get one. It is an amazing resource to learn from. We used that
16
 * example & converted it to a package so that it would be easy to install. We have also expanded on the initial
17
 * assertions.
18
 *
19
 * I WANT IT CLEAR THAT THIS WOULD NOT HAVE HAPPENED WITHOUT THE INITIAL WORK OF JEFFREY WAY. WE ARE NOT CLAIMING TO
20
 * BE THE CREATORS OF THE CONCEPT.
21
 *
22
 * @package Spinen\MailAssertions
23
 * @see     https://gist.github.com/JeffreyWay/b501c53d958b07b8a332
24
 * @tutorial https://laracasts.com/series/phpunit-testing-in-laravel/episodes/12
25
 */
26
trait MailTracking
27
{
28
    // TODO: Add check for attachments (number of & name)
29
    // TODO: Add check for header
30
    // TODO: Add check for message type
31
    // TODO: Add check for Priority
32
    // TODO: Allow checking specific message not just most recent one
33
34
    /**
35
     * Delivered emails.
36
     *
37
     * @var array
38
     */
39
    protected $emails = [];
40
41
    /**
42
     * Register a listener for new emails.
43
     *
44
     * This calls my PHPUnit before each test it runs. It registers the MailRecorder "plugin" with Swift, so that we
45
     * can get a copy of each email that is sent during that test.
46
     *
47
     * @before
48
     */
49
    public function setUpMailTracking()
50
    {
51
        Mail::getSwiftMailer()
52
            ->registerPlugin(new MailRecorder($this));
53
    }
54
55
    /**
56
     * Retrieve the appropriate Swift message.
57
     *
58
     * @param Swift_Message|null $message
59
     *
60
     * @return Swift_Message
61
     */
62
    protected function getEmail(Swift_Message $message = null)
63
    {
64
        $this->seeEmailWasSent();
65
66
        return $message ?: $this->lastEmail();
67
    }
68
69
    /**
70
     * Retrieve the mostly recently sent Swift message.
71
     */
72
    protected function lastEmail()
73
    {
74
        return end($this->emails);
75
    }
76
77
    /**
78
     * Store a new Swift message.
79
     *
80
     * Collection of emails that were received by the MailRecorder plugin during a test.
81
     *
82
     * @param Swift_Message $email
83
     */
84
    public function recordMail(Swift_Message $email)
85
    {
86
        $this->emails[] = $email;
87
    }
88
89
    /**
90
     * Assert that the last email was bcc'ed to the given address.
91
     *
92
     * @param string             $bcc
93
     * @param Swift_Message|null $message
94
     *
95
     * @return PHPUnit_Framework_TestCase $this
96
     */
97
    protected function seeEmailBcc($bcc, Swift_Message $message = null)
98
    {
99
        $this->assertArrayHasKey($bcc, (array)$this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertArrayHasKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
100
                                                   ->getBcc(), "The last email sent was not bcc'ed to $bcc.");
101
102
        return $this;
103
    }
104
105
    /**
106
     * Assert that the last email was cc'ed to the given address.
107
     *
108
     * @param string             $cc
109
     * @param Swift_Message|null $message
110
     *
111
     * @return PHPUnit_Framework_TestCase $this
112
     */
113
    protected function seeEmailCc($cc, Swift_Message $message = null)
114
    {
115
        $this->assertArrayHasKey($cc, (array)$this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertArrayHasKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
116
                                                  ->getCc(), "The last email sent was not cc'ed to $cc.");
117
118
        return $this;
119
    }
120
121
    /**
122
     * Assert that the last email's body contains the given text.
123
     *
124
     * @param string             $excerpt
125
     * @param Swift_Message|null $message
126
     *
127
     * @return PHPUnit_Framework_TestCase $this
128
     */
129
    protected function seeEmailContains($excerpt, Swift_Message $message = null)
130
    {
131
        $this->assertContains($excerpt, $this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertContains() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
132
                                             ->getBody(), "The last email sent did not contain the provided body.");
133
134
        return $this;
135
    }
136
137
    /**
138
     * Assert that the last email's body does not contain the given text.
139
     *
140
     * @param string             $excerpt
141
     * @param Swift_Message|null $message
142
     *
143
     * @return PHPUnit_Framework_TestCase $this
144
     */
145
    protected function seeEmailDoesNotContain($excerpt, Swift_Message $message = null)
146
    {
147
        $this->assertNotContains($excerpt, $this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertNotContains() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
148
                                                ->getBody(),
149
                                 "The last email sent contained the provided text in its body.");
150
151
        return $this;
152
    }
153
154
    /**
155
     * Assert that the last email's body equals the given text.
156
     *
157
     * @param string             $body
158
     * @param Swift_Message|null $message
159
     *
160
     * @return PHPUnit_Framework_TestCase $this
161
     */
162
    protected function seeEmailEquals($body, Swift_Message $message = null)
163
    {
164
        $this->assertEquals($body, $this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertEquals() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
165
                                        ->getBody(), "The last email sent did not match the given email.");
166
167
        return $this;
168
    }
169
170
    /**
171
     * Assert that the last email was delivered by the given address.
172
     *
173
     * @param string             $sender
174
     * @param Swift_Message|null $message
175
     *
176
     * @return PHPUnit_Framework_TestCase $this
177
     */
178
    protected function seeEmailFrom($sender, Swift_Message $message = null)
179
    {
180
        // TODO: Allow from to be an array to check email & name
181
        $this->assertArrayHasKey($sender, (array)$this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertArrayHasKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
182
                                                      ->getFrom(), "The last email sent was not sent from $sender.");
183
184
        return $this;
185
    }
186
187
    /**
188
     * Assert that the last email was set to reply to the given address.
189
     *
190
     * @param string             $reply_to
191
     * @param Swift_Message|null $message
192
     *
193
     * @return PHPUnit_Framework_TestCase $this
194
     */
195
    protected function seeEmailReplyTo($reply_to, Swift_Message $message = null)
196
    {
197
        $this->assertArrayHasKey($reply_to, (array)$this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertArrayHasKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
198
                                                        ->getReplyTo(),
199
                                 "The last email sent was not set to reply to $reply_to.");
200
201
        return $this;
202
    }
203
204
    /**
205
     * Assert that the given number of emails were sent.
206
     *
207
     * @param integer $count
208
     *
209
     * @return PHPUnit_Framework_TestCase $this
210
     */
211
    protected function seeEmailsSent($count)
212
    {
213
        $emailsSent = count($this->emails);
214
215
        $this->assertCount($count, $this->emails, "Expected $count emails to have been sent, but $emailsSent were.");
0 ignored issues
show
Bug introduced by
It seems like assertCount() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
216
217
        return $this;
218
    }
219
220
    /**
221
     * Assert that the last email's subject matches the given string.
222
     *
223
     * @param string             $subject
224
     * @param Swift_Message|null $message
225
     *
226
     * @return PHPUnit_Framework_TestCase $this
227
     */
228
    protected function seeEmailSubject($subject, Swift_Message $message = null)
229
    {
230
        $this->assertEquals($subject, $this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertEquals() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
231
                                           ->getSubject(),
232
                            "The last email sent did not contain a subject of $subject.");
233
234
        return $this;
235
    }
236
237
    /**
238
     * Assert that the last email's subject contains the given string.
239
     *
240
     * @param string             $excerpt
241
     * @param Swift_Message|null $message
242
     *
243
     * @return PHPUnit_Framework_TestCase $this
244
     */
245
    protected function seeEmailSubjectContains($excerpt, Swift_Message $message = null)
246
    {
247
        $this->assertContains($excerpt, $this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertContains() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
248
                                             ->getSubject(),
249
                              "The last email sent did not contain the provided subject.");
250
251
        return $this;
252
    }
253
254
    /**
255
     * Assert that the last email's subject does not contain the given string.
256
     *
257
     * @param string             $excerpt
258
     * @param Swift_Message|null $message
259
     *
260
     * @return PHPUnit_Framework_TestCase $this
261
     */
262
    protected function seeEmailSubjectDoesNotContain($excerpt, Swift_Message $message = null)
263
    {
264
        $this->assertNotContains($excerpt, $this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertNotContains() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
265
                                                ->getSubject(),
266
                                 "The last email sent contained the provided text in its subject.");
267
268
        return $this;
269
    }
270
271
    /**
272
     * Assert that the last email was sent to the given recipient.
273
     *
274
     * @param string             $recipient
275
     * @param Swift_Message|null $message
276
     *
277
     * @return PHPUnit_Framework_TestCase $this
278
     */
279
    protected function seeEmailTo($recipient, Swift_Message $message = null)
280
    {
281
        $this->assertArrayHasKey($recipient, (array)$this->getEmail($message)
0 ignored issues
show
Bug introduced by
It seems like assertArrayHasKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
282
                                                         ->getTo(), "The last email sent was not sent to $recipient.");
283
284
        return $this;
285
    }
286
287
    /**
288
     * Assert that no emails were sent.
289
     *
290
     * @return PHPUnit_Framework_TestCase $this
291
     */
292
    protected function seeEmailWasNotSent()
293
    {
294
        $emailsSent = count($this->emails);
295
296
        $this->assertEmpty($this->emails, "Did not expect any emails to have been sent, but found $emailsSent");
0 ignored issues
show
Bug introduced by
It seems like assertEmpty() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
297
298
        return $this;
299
    }
300
301
    /**
302
     * Assert that at least one email was sent.
303
     *
304
     * @return PHPUnit_Framework_TestCase $this
305
     */
306
    protected function seeEmailWasSent()
307
    {
308
        $this->assertNotEmpty($this->emails, 'Expected at least one email to be sent, but found none.');
0 ignored issues
show
Bug introduced by
It seems like assertNotEmpty() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
309
310
        return $this;
311
    }
312
}
313