1010
1111namespace PhpImap ;
1212
13+ use Generator ;
1314use ParagonIE \HiddenString \HiddenString ;
1415use PHPUnit \Framework \TestCase ;
16+ use Throwable ;
1517
1618/**
1719 * @psalm-type MAILBOX_ARGS = array{
2123 * 3:string,
2224 * 4?:string
2325 * }
26+ * @psalm-type COMPOSE_ENVELOPE = array{
27+ * subject?:string
28+ * }
29+ * @psalm-type COMPOSE_BODY = list<array{
30+ * type?:int,
31+ * encoding?:int,
32+ * charset?:string,
33+ * subtype?:string,
34+ * description?:string,
35+ * disposition?:array{filename:string}
36+ * }>
2437 */
2538abstract class AbstractLiveMailboxTest extends TestCase
2639{
@@ -44,6 +57,138 @@ public function MailBoxProvider(): array
4457 return $ sets ;
4558 }
4659
60+ /**
61+ * @psalm-return Generator<int, array{0:COMPOSE_ENVELOPE, 1:COMPOSE_BODY, 2:string}, mixed, void>
62+ */
63+ public function ComposeProvider (): Generator
64+ {
65+ yield from [];
66+ }
67+
68+ /**
69+ * @psalm-return Generator<int, array{
70+ * 0:MAILBOX_ARGS,
71+ * 1:COMPOSE_ENVELOPE,
72+ * 2:COMPOSE_BODY,
73+ * 3:string,
74+ * 4:bool
75+ * }, mixed, void>
76+ */
77+ public function AppendProvider (): Generator
78+ {
79+ foreach ($ this ->MailBoxProvider () as $ mailbox_args ) {
80+ foreach ($ this ->ComposeProvider () as $ compose_args ) {
81+ [$ envelope , $ body , $ expected_compose_result ] = $ compose_args ;
82+
83+ yield [$ mailbox_args , $ envelope , $ body , $ expected_compose_result , false ];
84+ }
85+
86+ foreach ($ this ->ComposeProvider () as $ compose_args ) {
87+ [$ envelope , $ body , $ expected_compose_result ] = $ compose_args ;
88+
89+ yield [$ mailbox_args , $ envelope , $ body , $ expected_compose_result , true ];
90+ }
91+ }
92+ }
93+
94+ /**
95+ * @dataProvider AppendProvider
96+ *
97+ * @group live
98+ *
99+ * @depends testGetImapStream
100+ * @depends testMailCompose
101+ *
102+ * @psalm-param MAILBOX_ARGS $mailbox_args
103+ * @psalm-param COMPOSE_ENVELOPE $envelope
104+ * @psalm-param COMPOSE_BODY $body
105+ */
106+ public function testAppend (
107+ array $ mailbox_args ,
108+ array $ envelope ,
109+ array $ body ,
110+ string $ _expected_compose_result ,
111+ bool $ pre_compose
112+ ): void {
113+ if ($ this ->MaybeSkipAppendTest ($ envelope )) {
114+ return ;
115+ }
116+
117+ list ($ search_criteria ) = $ this ->SubjectSearchCriteriaAndSubject ($ envelope );
118+
119+ list ($ mailbox , $ remove_mailbox , $ path ) = $ this ->getMailboxFromArgs (
120+ $ mailbox_args
121+ );
122+
123+ /** @var Throwable|null */
124+ $ exception = null ;
125+
126+ $ mailboxDeleted = false ;
127+
128+ try {
129+ $ search = $ mailbox ->searchMailbox ($ search_criteria );
130+
131+ $ this ->assertCount (
132+ 0 ,
133+ $ search ,
134+ (
135+ 'If a subject was found, ' .
136+ ' then the message is insufficiently unique to assert that ' .
137+ ' a newly-appended message was actually created. '
138+ )
139+ );
140+
141+ $ message = [$ envelope , $ body ];
142+
143+ if ($ pre_compose ) {
144+ $ message = Imap::mail_compose ($ envelope , $ body );
145+ }
146+
147+ $ mailbox ->appendMessageToMailbox ($ message );
148+
149+ $ search = $ mailbox ->searchMailbox ($ search_criteria );
150+
151+ $ this ->assertCount (
152+ 1 ,
153+ $ search ,
154+ (
155+ 'If a subject was not found, ' .
156+ ' then Mailbox::appendMessageToMailbox() failed ' .
157+ ' despite not throwing an exception. '
158+ )
159+ );
160+
161+ $ mailbox ->deleteMail ($ search [0 ]);
162+
163+ $ mailbox ->expungeDeletedMails ();
164+
165+ $ mailbox ->switchMailbox ($ path ->getString ());
166+ $ mailbox ->deleteMailbox ($ remove_mailbox );
167+ $ mailboxDeleted = true ;
168+
169+ $ this ->assertCount (
170+ 0 ,
171+ $ mailbox ->searchMailbox ($ search_criteria ),
172+ (
173+ 'If a subject was found, ' .
174+ ' then the message is was not expunged as requested. '
175+ )
176+ );
177+ } catch (Throwable $ ex ) {
178+ $ exception = $ ex ;
179+ } finally {
180+ $ mailbox ->switchMailbox ($ path ->getString ());
181+ if (!$ mailboxDeleted ) {
182+ $ mailbox ->deleteMailbox ($ remove_mailbox );
183+ }
184+ $ mailbox ->disconnect ();
185+ }
186+
187+ if (null !== $ exception ) {
188+ throw $ exception ;
189+ }
190+ }
191+
47192 /**
48193 * Get instance of Mailbox, pre-set to a random mailbox.
49194 *
@@ -106,4 +251,17 @@ protected function SubjectSearchCriteriaAndSubject(array $envelope): array
106251 /** @psalm-var array{0:string, 1:string} */
107252 return [$ search_criteria , (string ) $ subject ];
108253 }
254+
255+ protected function MaybeSkipAppendTest (array $ envelope ): bool
256+ {
257+ if (!isset ($ envelope ['subject ' ])) {
258+ $ this ->markTestSkipped (
259+ 'Cannot search for message by subject, no subject specified! '
260+ );
261+
262+ return true ;
263+ }
264+
265+ return false ;
266+ }
109267}
0 commit comments