Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Fixes #13
Browse files Browse the repository at this point in the history
Fallback to / when creating folders in INBOX fails
  • Loading branch information
Sebastian Tom Gellweiler committed Dec 11, 2018
1 parent efcc898 commit 8099a89
Show file tree
Hide file tree
Showing 7 changed files with 319 additions and 142 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.dm.mail2blog</groupId>
<artifactId>mail2blog</artifactId>
<version>2.1</version>
<version>2.2-rc1</version>
<organization>
<name>dm-drogerie markt GmbH + Co. KG</name>
<url>https://www.dm.de/arbeiten-und-lernen/arbeiten-bei-uns/filiadata-c534052.html</url>
Expand Down
20 changes: 18 additions & 2 deletions src/main/java/de/dm/mail2blog/ImapMailboxFlagStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,33 @@ public class ImapMailboxFlagStrategy implements IMailboxFlagFeature
@NonNull private Mailbox mailbox;

/**
* Get/create a folder below the default folder.
* Get/create a folder below the inbox or the root folder.
*
* @param name The name of the folder to create.
* @return The created folder
* @throws MailboxException if communication with mailbox does not work as expected
*/
private Folder getOrCreateFolder(@NonNull String name) throws MailboxException {
Folder folder;
try {
folder = getOrCreateSubfolder(mailbox.getInbox(), name);
} catch (MailboxException inboxError) {
try {
log.info("failed to create folder '" + name + "' below INBOX, falling back to ROOT folder", inboxError);
folder = getOrCreateSubfolder(mailbox.getDefaultFolder(), name);
} catch (MailboxException rootError) {
throw new MailboxException("failed to get or create folder '" + name + '"', rootError);
}
}

return folder;
}

private Folder getOrCreateSubfolder(Folder parent, @NonNull String name) throws MailboxException {
Folder folder;

try {
folder = mailbox.getInbox().getFolder(name);
folder = parent.getFolder(name);
} catch (MessagingException me) {
throw new MailboxException("failed to get folder '" + name + "'", me);
}
Expand Down
39 changes: 37 additions & 2 deletions src/main/java/de/dm/mail2blog/Mailbox.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public class Mailbox implements IMailboxFlagFeature {
*/
private Folder inbox;

/**
* The default Folder (/).
*/
private Folder defaultFolder;

/**
* The Mailstore to use.
*/
Expand Down Expand Up @@ -149,7 +154,7 @@ public Folder getInbox() throws MailboxException {
// Get the INBOX folder.
inbox = getStore().getFolder("INBOX");

// We need to open it READ_WRITE.
// We need to open it READ_WRITE,
// because we want to move/delete messages we already handled.
inbox.open(Folder.READ_WRITE);
} catch (FolderNotFoundException fnfe) {
Expand All @@ -162,6 +167,28 @@ public Folder getInbox() throws MailboxException {
return inbox;
}

/**
* Get the default directory.
*/
public Folder getDefaultFolder() throws MailboxException {
if (defaultFolder == null || !defaultFolder.isOpen()) {
try {
// Get the defaultFolder.
defaultFolder = getStore().getDefaultFolder();

// We need to open it READ_WRITE (There is no write only),
// because we want to move/delete messages we already handled.
defaultFolder.open(Folder.READ_WRITE);
} catch (FolderNotFoundException fnfe) {
throw new MailboxException("could not find ROOT folder", fnfe);
} catch (MessagingException e) {
throw new MailboxException("could not open ROOT folder", e);
}
}

return defaultFolder;
}

/**
* Get all messages in the INBOX folder.
*/
Expand Down Expand Up @@ -189,7 +216,15 @@ public void close() throws MailboxException {
try {
inbox.close(true);
} catch (MessagingException e) {
throw new MailboxException("failed to close INBOX", e);
throw new MailboxException("failed to close INBOX folder", e);
}
}

if (defaultFolder != null && defaultFolder.isOpen()) {
try {
defaultFolder.close(true);
} catch (MessagingException e) {
throw new MailboxException("failed to close ROOT folder", e);
}
}

Expand Down
113 changes: 113 additions & 0 deletions src/test/java/ut/de/dm/mail2blog/ImapMailboxFlagStrategyTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package ut.de.dm.mail2blog;


import de.dm.mail2blog.ImapMailboxFlagStrategy;
import de.dm.mail2blog.Mailbox;
import de.dm.mail2blog.MailboxException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;

public class ImapMailboxFlagStrategyTest {

@Mock
Mailbox mailbox;
MailboxTestMockData mockData;
ImapMailboxFlagStrategy strategy;

@Before
public void setUp() throws Exception {
initMocks(this);

mockData = new MailboxTestMockData();
when(mailbox.getStore()).thenReturn(mockData.getStore());
when(mailbox.getInbox()).thenReturn(mockData.getInbox());
when(mailbox.getDefaultFolder()).thenReturn(mockData.getDefaultFolder());
strategy = new ImapMailboxFlagStrategy(mailbox);
}

private void verifyMsgsProcessed(Folder processed, Folder invalid) throws MessagingException {
verify(processed, times(1)).create(Folder.HOLDS_MESSAGES);
verify(invalid, times(0)).create(anyInt());
verify(processed, times(1)).open(Folder.READ_WRITE);
verify(invalid, times(1)).open(Folder.READ_WRITE);
verify(mockData.getInbox(), times(1)).copyMessages(new Message[]{mockData.getExampleMail1()}, processed);
verify(mockData.getInbox(), times(0)).copyMessages(new Message[]{mockData.getExampleMail1()}, invalid);
verify(mockData.getInbox(), times(1)).copyMessages(new Message[]{mockData.getExampleMail2()}, invalid);
verify(mockData.getInbox(), times(0)).copyMessages(new Message[]{mockData.getExampleMail2()}, processed);
}

@Test
public void testFlaggingImapInbox() throws Exception {
Folder processed = mock(Folder.class);
Folder invalid = mock(Folder.class);

when(mockData.getInbox().getFolder("Processed")).thenReturn(processed);
when(mockData.getInbox().getFolder("Invalid")).thenReturn(invalid);

when(processed.exists()).thenReturn(false);
when(invalid.exists()).thenReturn(true);
when(processed.create(Folder.HOLDS_MESSAGES)).thenReturn(true);

processed.open(Folder.READ_ONLY);
invalid.open(Folder.READ_ONLY);

// Flag messages.
strategy.flagAsProcessed(mockData.getExampleMail1());
strategy.flagAsInvalid(mockData.getExampleMail2());

verifyMsgsProcessed(processed, invalid);
}

@Test
public void testFlaggingImapDefaultFolder() throws Exception {
Folder inboxProcessed = mock(Folder.class);
Folder inboxInvalid = mock(Folder.class);
Folder defaultProcessed = mock(Folder.class);
Folder defaultInvalid = mock(Folder.class);

when(mockData.getInbox().getFolder("Processed")).thenReturn(inboxProcessed);
when(mockData.getInbox().getFolder("Invalid")).thenReturn(inboxInvalid);
when(mockData.getDefaultFolder().getFolder("Processed")).thenReturn(defaultProcessed);
when(mockData.getDefaultFolder().getFolder("Invalid")).thenReturn(defaultInvalid);

when(inboxProcessed.exists()).thenReturn(false);
when(inboxInvalid.exists()).thenReturn(false);
given(inboxProcessed.create(Folder.HOLDS_MESSAGES)).willAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
throw new MailboxException("failed");
}
});
given(inboxInvalid.create(Folder.HOLDS_MESSAGES)).willAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
throw new MailboxException("failed");
}
});

when(defaultProcessed.exists()).thenReturn(false);
when(defaultInvalid.exists()).thenReturn(true);
when(defaultProcessed.create(Folder.HOLDS_MESSAGES)).thenReturn(true);

// Flag messages.
strategy.flagAsProcessed(mockData.getExampleMail1());
strategy.flagAsInvalid(mockData.getExampleMail2());

verifyMsgsProcessed(defaultProcessed, defaultInvalid);
}
}
Loading

0 comments on commit 8099a89

Please sign in to comment.