/*
* Copyright (c) 2011 Lockheed Martin Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.eurekastreams.server.service.email;
import java.io.IOException;
import java.util.List;
import javax.mail.FetchProfile;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Store;
import org.eurekastreams.commons.exceptions.ValidationException;
import org.eurekastreams.server.service.actions.strategies.EmailerFactory;
import org.hamcrest.collection.IsArrayContaining;
import org.jmock.Expectations;
import org.jmock.api.Invocation;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.jmock.lib.action.CustomAction;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Before;
import org.junit.Test;
/**
* Tests ImapEmailIngester.
*/
@SuppressWarnings("unchecked")
public class ImapEmailIngesterTest
{
/** Test data. */
private static final String INPUT_FOLDER_NAME = "InputFolder";
/** Test data. */
private static final String ERROR_FOLDER_NAME = "ErrorFolder";
/** Test data. */
private static final String SUCCESS_FOLDER_NAME = "SuccessFolder";
/** Test data. */
private static final String DISCARD_FOLDER_NAME = "DiscardFolder";
/** Used for mocking objects. */
private final JUnit4Mockery mockery = new JUnit4Mockery()
{
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};
/** For getting a connection to the mail server. */
private final ImapStoreFactory storeFactory = mockery.mock(ImapStoreFactory.class);
/** For validating/authenticating messages. */
private final MessageProcessor messageProcessor = mockery.mock(MessageProcessor.class);
/** Fixture: store. */
private final Store store = mockery.mock(Store.class);
/** Fixture: input folder. */
private final Folder inputFolder = mockery.mock(Folder.class, "inputFolder");
/** Fixture: error folder. */
private final Folder errorFolder = mockery.mock(Folder.class, "errorFolder");
/** Fixture: success folder. */
private final Folder successFolder = mockery.mock(Folder.class, "successFolder");
/** Fixture: success folder. */
private final Folder discardFolder = mockery.mock(Folder.class, "discardFolder");
/** Fixture: message. */
private final Message message = mockery.mock(Message.class, "message");
/** Fixture: response message. */
private final Message responseMessage = mockery.mock(Message.class, "responseMessage");
/** For sending response emails. */
private final EmailerFactory emailerFactory = mockery.mock(EmailerFactory.class, "emailerFactory");
/** SUT. */
private ImapEmailIngester sut;
/**
* Setup before each test.
*/
@Before
public void setUp()
{
sut = new ImapEmailIngester(storeFactory, messageProcessor, emailerFactory, INPUT_FOLDER_NAME,
ERROR_FOLDER_NAME, SUCCESS_FOLDER_NAME, DISCARD_FOLDER_NAME);
}
/**
* Sets up expectations for a successful connection and retrieval of messages.
*
* @param msgs
* Messages to be fetched from inbox.
* @throws MessagingException
* Won't.
*/
private void expectSuccessfulFrame(final Message[] msgs) throws MessagingException
{
mockery.checking(new Expectations()
{
{
oneOf(storeFactory).getStore();
will(returnValue(store));
oneOf(store).getFolder(INPUT_FOLDER_NAME);
will(returnValue(inputFolder));
allowing(inputFolder).exists();
will(returnValue(true));
allowing(store).getFolder(SUCCESS_FOLDER_NAME);
will(returnValue(successFolder));
allowing(successFolder).exists();
will(returnValue(true));
allowing(store).getFolder(ERROR_FOLDER_NAME);
will(returnValue(errorFolder));
allowing(errorFolder).exists();
will(returnValue(true));
allowing(store).getFolder(DISCARD_FOLDER_NAME);
will(returnValue(discardFolder));
allowing(discardFolder).exists();
will(returnValue(true));
oneOf(inputFolder).open(Folder.READ_WRITE);
oneOf(inputFolder).getMessages();
will(returnValue(msgs));
oneOf(inputFolder).fetch(with(same(msgs)), with(any(FetchProfile.class)));
oneOf(inputFolder).close(true);
oneOf(store).close();
}
});
}
/**
* Test.
*
* @throws MessagingException
* Won't.
* @throws IOException
* Won't.
*/
@Test
public void testExecuteSuccess() throws MessagingException, IOException
{
expectSuccessfulFrame(new Message[] { message });
mockery.checking(new Expectations()
{
{
oneOf(messageProcessor).execute(with(same(message)), with(any(List.class)));
will(returnValue(true));
oneOf(inputFolder).copyMessages(with(IsArrayContaining.hasItemInArray(message)),
with(same(successFolder)));
oneOf(message).setFlag(Flag.DELETED, true);
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Test.
*
* @throws MessagingException
* Won't.
* @throws IOException
* Won't.
*/
@Test
public void testExecuteSuccessNoCopy() throws MessagingException, IOException
{
sut = new ImapEmailIngester(storeFactory, messageProcessor, emailerFactory, INPUT_FOLDER_NAME,
ERROR_FOLDER_NAME, null, null);
expectSuccessfulFrame(new Message[] { message });
mockery.checking(new Expectations()
{
{
oneOf(messageProcessor).execute(with(same(message)), with(any(List.class)));
will(returnValue(true));
oneOf(message).setFlag(Flag.DELETED, true);
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Test.
*
* @throws MessagingException
* Won't.
* @throws IOException
* Won't.
*/
@Test
public void testExecuteFailMsg() throws MessagingException, IOException
{
expectSuccessfulFrame(new Message[] { message });
mockery.checking(new Expectations()
{
{
oneOf(messageProcessor).execute(with(same(message)), with(any(List.class)));
will(new CustomAction("simulate error")
{
@Override
public Object invoke(final Invocation inInvocation) throws Throwable
{
((List<Message>) inInvocation.getParameter(1)).add(responseMessage);
throw new ValidationException();
}
});
oneOf(inputFolder).copyMessages(with(IsArrayContaining.hasItemInArray(message)),
with(same(errorFolder)));
oneOf(message).setFlag(Flag.DELETED, true);
oneOf(emailerFactory).sendMail(with(same(responseMessage)));
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Test.
*
* @throws MessagingException
* Won't.
* @throws IOException
* Won't.
*/
@Test
public void testExecuteFailMsgNoCopy() throws MessagingException, IOException
{
sut = new ImapEmailIngester(storeFactory, messageProcessor, emailerFactory, INPUT_FOLDER_NAME, "",
SUCCESS_FOLDER_NAME, " ");
expectSuccessfulFrame(new Message[] { message });
mockery.checking(new Expectations()
{
{
oneOf(messageProcessor).execute(with(same(message)), with(any(List.class)));
will(throwException(new MessagingException()));
oneOf(message).setFlag(Flag.DELETED, true);
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Test.
*
* @throws MessagingException
* Won't.
* @throws IOException
* Won't.
*/
@Test
public void testExecuteDiscard() throws MessagingException, IOException
{
expectSuccessfulFrame(new Message[] { message });
mockery.checking(new Expectations()
{
{
oneOf(messageProcessor).execute(with(same(message)), with(any(List.class)));
will(returnValue(false));
oneOf(inputFolder).copyMessages(with(IsArrayContaining.hasItemInArray(message)),
with(same(discardFolder)));
oneOf(message).setFlag(Flag.DELETED, true);
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Test.
*
* @throws MessagingException
* Won't.
* @throws IOException
* Won't.
*/
@Test
public void testExecuteDiscardNoCopy() throws MessagingException, IOException
{
sut = new ImapEmailIngester(storeFactory, messageProcessor, emailerFactory, INPUT_FOLDER_NAME, null, null,
null);
expectSuccessfulFrame(new Message[] { message });
mockery.checking(new Expectations()
{
{
oneOf(messageProcessor).execute(with(same(message)), with(any(List.class)));
will(returnValue(false));
oneOf(message).setFlag(Flag.DELETED, true);
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Test.
*
* @throws MessagingException
* Won't.
*/
@Test
public void testExecuteNoMessages() throws MessagingException
{
expectSuccessfulFrame(new Message[] {});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Tests error condition.
*
* @throws MessagingException
* Won't.
*/
@Test
public void testExecuteCannotOpenStore() throws MessagingException
{
mockery.checking(new Expectations()
{
{
oneOf(storeFactory).getStore();
will(throwException(new MessagingException()));
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Tests error condition.
*
* @throws MessagingException
* Won't.
*/
@Test
public void testExecuteBadInputFolder() throws MessagingException
{
mockery.checking(new Expectations()
{
{
oneOf(storeFactory).getStore();
will(returnValue(store));
oneOf(store).getFolder(INPUT_FOLDER_NAME);
will(returnValue(inputFolder));
oneOf(inputFolder).exists();
will(returnValue(false));
oneOf(store).close();
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Tests error condition.
*
* @throws MessagingException
* Won't.
*/
@Test
public void testExecuteBadDiscardFolder() throws MessagingException
{
mockery.checking(new Expectations()
{
{
oneOf(storeFactory).getStore();
will(returnValue(store));
oneOf(store).getFolder(INPUT_FOLDER_NAME);
will(returnValue(inputFolder));
allowing(inputFolder).exists();
will(returnValue(true));
oneOf(store).getFolder(SUCCESS_FOLDER_NAME);
will(returnValue(successFolder));
allowing(successFolder).exists();
will(returnValue(true));
allowing(store).getFolder(DISCARD_FOLDER_NAME);
will(returnValue(discardFolder));
allowing(discardFolder).exists();
will(returnValue(false));
oneOf(store).close();
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Tests error condition.
*
* @throws MessagingException
* Won't.
*/
@Test
public void testExecuteBadErrorFolder() throws MessagingException
{
mockery.checking(new Expectations()
{
{
oneOf(storeFactory).getStore();
will(returnValue(store));
oneOf(store).getFolder(INPUT_FOLDER_NAME);
will(returnValue(inputFolder));
allowing(inputFolder).exists();
will(returnValue(true));
oneOf(store).getFolder(SUCCESS_FOLDER_NAME);
will(returnValue(successFolder));
allowing(successFolder).exists();
will(returnValue(true));
oneOf(store).getFolder(ERROR_FOLDER_NAME);
will(returnValue(errorFolder));
allowing(errorFolder).exists();
will(returnValue(false));
allowing(store).getFolder(DISCARD_FOLDER_NAME);
will(returnValue(discardFolder));
allowing(discardFolder).exists();
will(returnValue(true));
oneOf(store).close();
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Tests error condition.
*
* @throws MessagingException
* Won't.
*/
@Test
public void testExecuteBadSuccessFolder() throws MessagingException
{
mockery.checking(new Expectations()
{
{
oneOf(storeFactory).getStore();
will(returnValue(store));
oneOf(store).getFolder(INPUT_FOLDER_NAME);
will(returnValue(inputFolder));
allowing(inputFolder).exists();
will(returnValue(true));
oneOf(store).getFolder(SUCCESS_FOLDER_NAME);
will(returnValue(successFolder));
allowing(successFolder).exists();
will(returnValue(false));
oneOf(store).close();
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Tests error condition.
*
* @throws MessagingException
* Won't.
*/
@Test
public void testExecuteException1() throws MessagingException
{
mockery.checking(new Expectations()
{
{
oneOf(storeFactory).getStore();
will(returnValue(store));
oneOf(store).getFolder(INPUT_FOLDER_NAME);
will(throwException(new MessagingException()));
oneOf(store).close();
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Tests error condition.
*
* @throws MessagingException
* Won't.
*/
@Test
public void testExecuteException2() throws MessagingException
{
mockery.checking(new Expectations()
{
{
oneOf(storeFactory).getStore();
will(returnValue(store));
oneOf(store).getFolder(INPUT_FOLDER_NAME);
will(throwException(new IllegalArgumentException()));
oneOf(store).close();
}
});
sut.execute();
mockery.assertIsSatisfied();
}
/**
* Tests error condition.
*
* @throws MessagingException
* Won't.
*/
@Test
public void testExecuteCloseException() throws MessagingException
{
mockery.checking(new Expectations()
{
{
oneOf(storeFactory).getStore();
will(returnValue(store));
oneOf(store).getFolder(INPUT_FOLDER_NAME);
will(throwException(new IllegalArgumentException()));
oneOf(store).close();
will(throwException(new MessagingException()));
}
});
sut.execute();
mockery.assertIsSatisfied();
}
}