|
17 | 17 | package org.springframework.integration.mail; |
18 | 18 |
|
19 | 19 | import java.io.IOException; |
| 20 | +import java.io.OutputStream; |
20 | 21 | import java.lang.reflect.Field; |
21 | 22 | import java.util.ArrayList; |
22 | 23 | import java.util.Arrays; |
23 | 24 | import java.util.List; |
24 | 25 | import java.util.Properties; |
25 | 26 | import java.util.concurrent.CountDownLatch; |
26 | 27 | import java.util.concurrent.TimeUnit; |
| 28 | +import java.util.concurrent.atomic.AtomicBoolean; |
27 | 29 | import java.util.concurrent.atomic.AtomicInteger; |
28 | 30 | import java.util.concurrent.atomic.AtomicReference; |
29 | 31 | import java.util.logging.Handler; |
|
88 | 90 | import org.springframework.util.MimeTypeUtils; |
89 | 91 |
|
90 | 92 | import static org.assertj.core.api.Assertions.assertThat; |
| 93 | +import static org.assertj.core.api.Assertions.assertThatThrownBy; |
91 | 94 | import static org.mockito.ArgumentMatchers.any; |
92 | 95 | import static org.mockito.ArgumentMatchers.anyString; |
93 | 96 | import static org.mockito.BDDMockito.given; |
|
107 | 110 | * @author Artem Bilan |
108 | 111 | * @author Alexander Pinske |
109 | 112 | * @author Dominik Simmen |
| 113 | + * @author Filip Hrisafov |
110 | 114 | */ |
111 | 115 | @SpringJUnitConfig |
112 | 116 | @ContextConfiguration( |
@@ -299,6 +303,11 @@ public void receiveAndMarkAsReadDontDelete() throws Exception { |
299 | 303 |
|
300 | 304 | private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailReceiver receiver, Message msg1, |
301 | 305 | Message msg2) throws NoSuchFieldException, IllegalAccessException, MessagingException { |
| 306 | + return receiveAndMarkAsReadDontDeleteGuts(receiver, msg1, msg2, true); |
| 307 | + } |
| 308 | + |
| 309 | + private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailReceiver receiver, Message msg1, |
| 310 | + Message msg2, boolean receive) throws NoSuchFieldException, IllegalAccessException, MessagingException { |
302 | 311 |
|
303 | 312 | ((ImapMailReceiver) receiver).setShouldMarkMessagesAsRead(true); |
304 | 313 | receiver = spy(receiver); |
@@ -326,7 +335,9 @@ private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailRece |
326 | 335 | willAnswer(invocation -> messages).given(folder).search(any(SearchTerm.class)); |
327 | 336 |
|
328 | 337 | willAnswer(invocation -> null).given(receiver).fetchMessages(messages); |
329 | | - receiver.receive(); |
| 338 | + if (receive) { |
| 339 | + receiver.receive(); |
| 340 | + } |
330 | 341 | return receiver; |
331 | 342 | } |
332 | 343 |
|
@@ -980,6 +991,31 @@ private void setUpScheduler(ImapMailReceiver mailReceiver, ThreadPoolTaskSchedul |
980 | 991 | mailReceiver.setBeanFactory(bf); |
981 | 992 | } |
982 | 993 |
|
| 994 | + @Test |
| 995 | + public void receiveAndMarkAsReadDontDeleteWithThrowingWhenCopying() throws Exception { |
| 996 | + AbstractMailReceiver receiver = new ImapMailReceiver(); |
| 997 | + MimeMessage msg1 = spy(GreenMailUtil.newMimeMessage("test1")); |
| 998 | + MimeMessage greenMailMsg2 = GreenMailUtil.newMimeMessage("test2"); |
| 999 | + TestThrowingMimeMessage msg2 = new TestThrowingMimeMessage(greenMailMsg2); |
| 1000 | + receiver = receiveAndMarkAsReadDontDeleteGuts(receiver, msg1, msg2, false); |
| 1001 | + assertThatThrownBy(receiver::receive) |
| 1002 | + .isInstanceOf(MessagingException.class) |
| 1003 | + .hasMessage("IOException while copying message") |
| 1004 | + .cause() |
| 1005 | + .isInstanceOf(IOException.class) |
| 1006 | + .hasMessage("Simulated exception"); |
| 1007 | + assertThat(msg1.getFlags().contains(Flag.SEEN)).isFalse(); |
| 1008 | + assertThat(msg2.getFlags().contains(Flag.SEEN)).isFalse(); |
| 1009 | + verify(msg1, times(0)).setFlags(Mockito.any(), Mockito.anyBoolean()); |
| 1010 | + |
| 1011 | + receiver.receive(); |
| 1012 | + assertThat(msg1.getFlags().contains(Flag.SEEN)).isTrue(); |
| 1013 | + assertThat(msg2.getFlags().contains(Flag.SEEN)).isTrue(); |
| 1014 | + // msg2 is marked with the user and seen flags |
| 1015 | + verify(msg1, times(2)).setFlags(Mockito.any(), Mockito.anyBoolean()); |
| 1016 | + verify(receiver, times(0)).deleteMessages(Mockito.any()); |
| 1017 | + } |
| 1018 | + |
983 | 1019 | private static class ImapSearchLoggingHandler extends Handler { |
984 | 1020 |
|
985 | 1021 | private final List<String> searches = new ArrayList<>(); |
@@ -1015,4 +1051,21 @@ public void close() throws SecurityException { |
1015 | 1051 |
|
1016 | 1052 | } |
1017 | 1053 |
|
| 1054 | + private static class TestThrowingMimeMessage extends MimeMessage { |
| 1055 | + |
| 1056 | + protected final AtomicBoolean throwExceptionBeforeWrite = new AtomicBoolean(true); |
| 1057 | + |
| 1058 | + private TestThrowingMimeMessage(MimeMessage source) throws MessagingException { |
| 1059 | + super(source); |
| 1060 | + } |
| 1061 | + |
| 1062 | + @Override |
| 1063 | + public void writeTo(OutputStream os) throws IOException, MessagingException { |
| 1064 | + if (this.throwExceptionBeforeWrite.getAndSet(false)) { |
| 1065 | + throw new IOException("Simulated exception"); |
| 1066 | + } |
| 1067 | + super.writeTo(os); |
| 1068 | + } |
| 1069 | + } |
| 1070 | + |
1018 | 1071 | } |
0 commit comments