-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Flag and maybe delete messages after messages have been copied #9546
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
package org.springframework.integration.mail; | ||
|
||
import java.io.IOException; | ||
import java.io.OutputStream; | ||
import java.lang.reflect.Field; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
|
@@ -88,6 +89,7 @@ | |
import org.springframework.util.MimeTypeUtils; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
import static org.mockito.ArgumentMatchers.any; | ||
import static org.mockito.ArgumentMatchers.anyString; | ||
import static org.mockito.BDDMockito.given; | ||
|
@@ -107,6 +109,7 @@ | |
* @author Artem Bilan | ||
* @author Alexander Pinske | ||
* @author Dominik Simmen | ||
* @author Filip Hrisafov | ||
*/ | ||
@SpringJUnitConfig | ||
@ContextConfiguration( | ||
|
@@ -299,6 +302,11 @@ public void receiveAndMarkAsReadDontDelete() throws Exception { | |
|
||
private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailReceiver receiver, Message msg1, | ||
Message msg2) throws NoSuchFieldException, IllegalAccessException, MessagingException { | ||
return receiveAndMarkAsReadDontDeleteGuts(receiver, msg1, msg2, true); | ||
} | ||
|
||
private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailReceiver receiver, Message msg1, | ||
Message msg2, boolean receive) throws NoSuchFieldException, IllegalAccessException, MessagingException { | ||
|
||
((ImapMailReceiver) receiver).setShouldMarkMessagesAsRead(true); | ||
receiver = spy(receiver); | ||
|
@@ -326,7 +334,9 @@ private AbstractMailReceiver receiveAndMarkAsReadDontDeleteGuts(AbstractMailRece | |
willAnswer(invocation -> messages).given(folder).search(any(SearchTerm.class)); | ||
|
||
willAnswer(invocation -> null).given(receiver).fetchMessages(messages); | ||
receiver.receive(); | ||
if (receive) { | ||
receiver.receive(); | ||
} | ||
return receiver; | ||
} | ||
|
||
|
@@ -980,6 +990,30 @@ private void setUpScheduler(ImapMailReceiver mailReceiver, ThreadPoolTaskSchedul | |
mailReceiver.setBeanFactory(bf); | ||
} | ||
|
||
@Test | ||
public void receiveAndMarkAsReadDontDeleteWithThrowingWhenCopying() throws Exception { | ||
AbstractMailReceiver receiver = new ImapMailReceiver(); | ||
MimeMessage msg1 = GreenMailUtil.newMimeMessage("test1"); | ||
MimeMessage greenMailMsg2 = GreenMailUtil.newMimeMessage("test2"); | ||
TestThrowingMimeMessage msg2 = new TestThrowingMimeMessage(greenMailMsg2, 1); | ||
receiver = receiveAndMarkAsReadDontDeleteGuts(receiver, msg1, msg2, false); | ||
assertThatThrownBy(receiver::receive) | ||
.isInstanceOf(MessagingException.class) | ||
.hasMessage("IOException while copying message") | ||
.cause() | ||
.isInstanceOf(IOException.class) | ||
.hasMessage("Simulated exception"); | ||
assertThat(msg1.getFlags().contains(Flag.SEEN)).isFalse(); | ||
assertThat(msg2.getFlags().contains(Flag.SEEN)).isFalse(); | ||
assertThat(msg2.getMyTestFlags().contains(Flag.SEEN)).isFalse(); | ||
|
||
receiver.receive(); | ||
assertThat(msg1.getFlags().contains(Flag.SEEN)).isTrue(); | ||
assertThat(msg2.getFlags().contains(Flag.SEEN)).isTrue(); | ||
assertThat(msg2.getMyTestFlags().contains(Flag.SEEN)).isTrue(); | ||
verify(receiver, times(0)).deleteMessages(Mockito.any()); | ||
} | ||
|
||
private static class ImapSearchLoggingHandler extends Handler { | ||
|
||
private final List<String> searches = new ArrayList<>(); | ||
|
@@ -1015,4 +1049,39 @@ public void close() throws SecurityException { | |
|
||
} | ||
|
||
private static class TestThrowingMimeMessage extends MimeMessage { | ||
|
||
protected final AtomicInteger exceptionsBeforeWrite; | ||
|
||
protected final Flags myTestFlags = new Flags(); | ||
|
||
private TestThrowingMimeMessage(MimeMessage source, int exceptionsBeforeWrite) throws MessagingException { | ||
super(source); | ||
this.exceptionsBeforeWrite = new AtomicInteger(exceptionsBeforeWrite); | ||
} | ||
|
||
@Override | ||
public void writeTo(OutputStream os) throws IOException, MessagingException { | ||
if (this.exceptionsBeforeWrite.decrementAndGet() >= 0) { | ||
throw new IOException("Simulated exception"); | ||
} | ||
super.writeTo(os); | ||
} | ||
|
||
@Override | ||
public synchronized void setFlags(Flags flag, boolean set) throws MessagingException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to override this if there is that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is to show that we are calling the flags = source.getFlags();
if (flags == null) // make sure flags is always set
flags = new Flags(); So if the source has There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't look like you validate somehow in the test if message was original or There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is assertThat(msg2.getMyTestFlags().contains(Flag.SEEN)).isTrue(); In the test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But looks like it is exactly the same as previous one:
That's why I believe that is really enough. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added this to validate that the assertThat(msg2.getFlags().contains(Flag.SEEN)).isTrue(); The test above passes as the assertThat(msg2.getMyTestFlags().contains(Flag.SEEN)).isTrue(); would fail as it has it's own flags. If you think it is too much, I can remove it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. You probably can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good point with the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've replaced that with a spy. Hope it is good now. |
||
super.setFlags(flag, set); | ||
if (set) { | ||
myTestFlags.add(flag); | ||
} | ||
else { | ||
myTestFlags.remove(flag); | ||
} | ||
} | ||
|
||
private Flags getMyTestFlags() { | ||
return myTestFlags; | ||
} | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like just
AtomicBoolean
will be enough without any extra ctor arg.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. I've adjusted it