13
13
14
14
use PHPUnit \Framework \TestCase ;
15
15
use Symfony \Component \Mailer \DelayedEnvelope ;
16
+ use Symfony \Component \Mailer \Envelope ;
16
17
use Symfony \Component \Mailer \Exception \TransportException ;
18
+ use Symfony \Component \Mailer \SentMessage ;
17
19
use Symfony \Component \Mailer \Transport \SendmailTransport ;
20
+ use Symfony \Component \Mailer \Transport \Smtp \Stream \ProcessStream ;
21
+ use Symfony \Component \Mailer \Transport \TransportInterface ;
18
22
use Symfony \Component \Mime \Address ;
19
23
use Symfony \Component \Mime \Email ;
24
+ use Symfony \Component \Mime \RawMessage ;
20
25
21
26
class SendmailTransportTest extends TestCase
22
27
{
23
28
private const FAKE_SENDMAIL = __DIR__ .'/Fixtures/fake-sendmail.php -t ' ;
24
29
private const FAKE_FAILING_SENDMAIL = __DIR__ .'/Fixtures/fake-failing-sendmail.php -t ' ;
30
+ private const FAKE_INTERACTIVE_SENDMAIL = __DIR__ .'/Fixtures/fake-failing-sendmail.php -bs ' ;
25
31
26
32
/**
27
33
* @var string
@@ -49,9 +55,7 @@ public function testToString()
49
55
50
56
public function testToIsUsedWhenRecipientsAreNotSet ()
51
57
{
52
- if ('\\' === \DIRECTORY_SEPARATOR ) {
53
- $ this ->markTestSkipped ('Windows does not support shebangs nor non-blocking standard streams ' );
54
- }
58
+ $ this ->skipOnWindows ();
55
59
56
60
$ mail = new Email ();
57
61
$ mail
@@ -71,20 +75,9 @@ public function testToIsUsedWhenRecipientsAreNotSet()
71
75
72
76
public function testRecipientsAreUsedWhenSet ()
73
77
{
74
- if ('\\' === \DIRECTORY_SEPARATOR ) {
75
- $ this ->markTestSkipped ('Windows does not support shebangs nor non-blocking standard streams ' );
76
- }
78
+ $ this ->skipOnWindows ();
77
79
78
- $ mail = new Email ();
79
- $ mail
80
- ->from ('from@mail.com ' )
81
- ->to ('to@mail.com ' )
82
- ->subject ('Subject ' )
83
- ->text ('Some text ' )
84
- ;
85
-
86
- $ envelope = new DelayedEnvelope ($ mail );
87
- $ envelope ->setRecipients ([new Address ('recipient@mail.com ' )]);
80
+ [$ mail , $ envelope ] = $ this ->defaultMailAndEnvelope ();
88
81
89
82
$ sendmailTransport = new SendmailTransport (self ::FAKE_SENDMAIL );
90
83
$ sendmailTransport ->send ($ mail , $ envelope );
@@ -93,11 +86,90 @@ public function testRecipientsAreUsedWhenSet()
93
86
}
94
87
95
88
public function testThrowsTransportExceptionOnFailure ()
89
+ {
90
+ $ this ->skipOnWindows ();
91
+
92
+ [$ mail , $ envelope ] = $ this ->defaultMailAndEnvelope ();
93
+
94
+ $ sendmailTransport = new SendmailTransport (self ::FAKE_FAILING_SENDMAIL );
95
+ $ this ->expectException (TransportException::class);
96
+ $ this ->expectExceptionMessage ('Process failed with exit code 42: Sending failed ' );
97
+ $ sendmailTransport ->send ($ mail , $ envelope );
98
+
99
+ $ streamProperty = new \ReflectionProperty (SendmailTransport::class, 'stream ' );
100
+ $ streamProperty ->setAccessible (true );
101
+ $ stream = $ streamProperty ->getValue ($ sendmailTransport );
102
+ $ this ->assertNull ($ stream ->stream );
103
+ }
104
+
105
+ public function testStreamIsClearedOnFailure ()
106
+ {
107
+ $ this ->skipOnWindows ();
108
+
109
+ [$ mail , $ envelope ] = $ this ->defaultMailAndEnvelope ();
110
+
111
+ $ sendmailTransport = new SendmailTransport (self ::FAKE_FAILING_SENDMAIL );
112
+ try {
113
+ $ sendmailTransport ->send ($ mail , $ envelope );
114
+ } catch (TransportException $ e ) {
115
+ }
116
+
117
+ $ streamProperty = new \ReflectionProperty (SendmailTransport::class, 'stream ' );
118
+ $ streamProperty ->setAccessible (true );
119
+ $ stream = $ streamProperty ->getValue ($ sendmailTransport );
120
+ $ innerStreamProperty = new \ReflectionProperty (ProcessStream::class, 'stream ' );
121
+ $ innerStreamProperty ->setAccessible (true );
122
+ $ this ->assertNull ($ innerStreamProperty ->getValue ($ stream ));
123
+ }
124
+
125
+ public function testDoesNotThrowWhenInteractive ()
126
+ {
127
+ $ this ->skipOnWindows ();
128
+
129
+ [$ mail , $ envelope ] = $ this ->defaultMailAndEnvelope ();
130
+
131
+ $ sendmailTransport = new SendmailTransport (self ::FAKE_INTERACTIVE_SENDMAIL );
132
+ $ transportProperty = new \ReflectionProperty (SendmailTransport::class, 'transport ' );
133
+ $ transportProperty ->setAccessible (true );
134
+
135
+ // Replace the transport with an anonymous consumer that trigger the stream methods
136
+ $ transportProperty ->setValue ($ sendmailTransport , new class ($ transportProperty ->getValue ($ sendmailTransport )->getStream ()) implements TransportInterface {
137
+ private $ stream ;
138
+
139
+ public function __construct (ProcessStream $ stream )
140
+ {
141
+ $ this ->stream = $ stream ;
142
+ }
143
+
144
+ public function send (RawMessage $ message , ?Envelope $ envelope = null ): ?SentMessage
145
+ {
146
+ $ this ->stream ->initialize ();
147
+ $ this ->stream ->write ('SMTP ' );
148
+ $ this ->stream ->terminate ();
149
+
150
+ return new SentMessage ($ message , $ envelope );
151
+ }
152
+
153
+ public function __toString (): string
154
+ {
155
+ return 'Interactive mode test ' ;
156
+ }
157
+ });
158
+
159
+ $ sendmailTransport ->send ($ mail , $ envelope );
160
+
161
+ $ this ->assertStringEqualsFile ($ this ->argsPath , __DIR__ .'/Fixtures/fake-failing-sendmail.php -bs ' );
162
+ }
163
+
164
+ private function skipOnWindows ()
96
165
{
97
166
if ('\\' === \DIRECTORY_SEPARATOR ) {
98
167
$ this ->markTestSkipped ('Windows does not support shebangs nor non-blocking standard streams ' );
99
168
}
169
+ }
100
170
171
+ private function defaultMailAndEnvelope (): array
172
+ {
101
173
$ mail = new Email ();
102
174
$ mail
103
175
->from ('from@mail.com ' )
@@ -109,9 +181,6 @@ public function testThrowsTransportExceptionOnFailure()
109
181
$ envelope = new DelayedEnvelope ($ mail );
110
182
$ envelope ->setRecipients ([new Address ('recipient@mail.com ' )]);
111
183
112
- $ sendmailTransport = new SendmailTransport (self ::FAKE_FAILING_SENDMAIL );
113
- $ this ->expectException (TransportException::class);
114
- $ this ->expectExceptionMessage ('Process failed with exit code 42: Sending failed ' );
115
- $ sendmailTransport ->send ($ mail , $ envelope );
184
+ return [$ mail , $ envelope ];
116
185
}
117
186
}
0 commit comments