| 
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;  | 
 | 
88 | 89 | import org.springframework.util.MimeTypeUtils;  | 
89 | 90 | 
 
  | 
90 | 91 | import static org.assertj.core.api.Assertions.assertThat;  | 
 | 92 | +import static org.assertj.core.api.Assertions.assertThatThrownBy;  | 
91 | 93 | import static org.mockito.ArgumentMatchers.any;  | 
92 | 94 | import static org.mockito.ArgumentMatchers.anyString;  | 
93 | 95 | import static org.mockito.BDDMockito.given;  | 
@@ -299,6 +301,11 @@ public void receiveAndMarkAsReadDontDelete() throws Exception {  | 
299 | 301 | 
 
  | 
300 | 302 | 	private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailReceiver receiver, Message msg1,  | 
301 | 303 | 			Message msg2) throws NoSuchFieldException, IllegalAccessException, MessagingException {  | 
 | 304 | +		return receiveAndMarkAsReadDontDeleteGuts(receiver, msg1, msg2, true);  | 
 | 305 | +	}  | 
 | 306 | + | 
 | 307 | +	private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailReceiver receiver, Message msg1,  | 
 | 308 | +			Message msg2, boolean receive) throws NoSuchFieldException, IllegalAccessException, MessagingException {  | 
302 | 309 | 
 
  | 
303 | 310 | 		((ImapMailReceiver) receiver).setShouldMarkMessagesAsRead(true);  | 
304 | 311 | 		receiver = spy(receiver);  | 
@@ -326,7 +333,9 @@ private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailRece  | 
326 | 333 | 		willAnswer(invocation -> messages).given(folder).search(any(SearchTerm.class));  | 
327 | 334 | 
 
  | 
328 | 335 | 		willAnswer(invocation -> null).given(receiver).fetchMessages(messages);  | 
329 |  | -		receiver.receive();  | 
 | 336 | +		if (receive) {  | 
 | 337 | +			receiver.receive();  | 
 | 338 | +		}  | 
330 | 339 | 		return receiver;  | 
331 | 340 | 	}  | 
332 | 341 | 
 
  | 
@@ -980,6 +989,28 @@ private void setUpScheduler(ImapMailReceiver mailReceiver, ThreadPoolTaskSchedul  | 
980 | 989 | 		mailReceiver.setBeanFactory(bf);  | 
981 | 990 | 	}  | 
982 | 991 | 
 
  | 
 | 992 | +	@Test  | 
 | 993 | +	public void receiveAndMarkAsReadDontDeleteWithThrowingWhenCopying() throws Exception {  | 
 | 994 | +		AbstractMailReceiver receiver = new ImapMailReceiver();  | 
 | 995 | +		MimeMessage msg1 = GreenMailUtil.newMimeMessage("test1");  | 
 | 996 | +		MimeMessage greenMailMsg2 = GreenMailUtil.newMimeMessage("test2");  | 
 | 997 | +		TestThrowingMimeMessage msg2 = new TestThrowingMimeMessage(greenMailMsg2, 1);  | 
 | 998 | +		receiver = receiveAndMarkAsReadDontDeleteGuts(receiver, msg1, msg2, false);  | 
 | 999 | +		assertThatThrownBy(receiver::receive)  | 
 | 1000 | +				.isInstanceOf(MessagingException.class)  | 
 | 1001 | +				.hasMessage("IOException while copying message")  | 
 | 1002 | +				.cause()  | 
 | 1003 | +				.isInstanceOf(IOException.class)  | 
 | 1004 | +				.hasMessage("Simulated exception");  | 
 | 1005 | +		assertThat(msg1.getFlags().contains(Flag.SEEN)).isFalse();  | 
 | 1006 | +		assertThat(msg2.getFlags().contains(Flag.SEEN)).isFalse();  | 
 | 1007 | + | 
 | 1008 | +		receiver.receive();  | 
 | 1009 | +		assertThat(msg1.getFlags().contains(Flag.SEEN)).isTrue();  | 
 | 1010 | +		assertThat(msg2.getFlags().contains(Flag.SEEN)).isTrue();  | 
 | 1011 | +		verify(receiver, times(0)).deleteMessages(Mockito.any());  | 
 | 1012 | +	}  | 
 | 1013 | + | 
983 | 1014 | 	private static class ImapSearchLoggingHandler extends Handler {  | 
984 | 1015 | 
 
  | 
985 | 1016 | 		private final List<String> searches = new ArrayList<>();  | 
@@ -1015,4 +1046,22 @@ public void close() throws SecurityException {  | 
1015 | 1046 | 
 
  | 
1016 | 1047 | 	}  | 
1017 | 1048 | 
 
  | 
 | 1049 | +	private static class TestThrowingMimeMessage extends MimeMessage {  | 
 | 1050 | + | 
 | 1051 | +		protected final AtomicInteger exceptionsBeforeWrite;  | 
 | 1052 | + | 
 | 1053 | +		public TestThrowingMimeMessage(MimeMessage source, int exceptionsBeforeWrite) throws MessagingException {  | 
 | 1054 | +			super(source);  | 
 | 1055 | +			this.exceptionsBeforeWrite = new AtomicInteger(exceptionsBeforeWrite);  | 
 | 1056 | +		}  | 
 | 1057 | + | 
 | 1058 | +		@Override  | 
 | 1059 | +		public void writeTo(OutputStream os) throws IOException, MessagingException {  | 
 | 1060 | +			if (this.exceptionsBeforeWrite.decrementAndGet() >= 0) {  | 
 | 1061 | +				throw new IOException("Simulated exception");  | 
 | 1062 | +			}  | 
 | 1063 | +			super.writeTo(os);  | 
 | 1064 | +		}  | 
 | 1065 | +	}  | 
 | 1066 | + | 
1018 | 1067 | }  | 
0 commit comments