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