package mireka.transmission.immediate;
import static mireka.ExampleAddress.*;
import static org.junit.Assert.*;
import java.io.IOException;
import java.util.Arrays;
import mireka.ExampleMail;
import mireka.smtp.EnhancedStatus;
import mireka.smtp.SendException;
import mireka.smtp.client.MtaAddress;
import mireka.smtp.client.SmtpClient;
import mireka.transmission.Mail;
import mireka.transmission.immediate.host.MailToHostTransmitter;
import mireka.transmission.immediate.host.OutgoingConnectionsRegistry;
import mireka.transmission.queuing.LogIdFactory;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import mockit.Tested;
import mockit.Verifications;
import org.junit.Before;
import org.junit.Test;
import org.subethamail.smtp.client.SMTPClient;
import org.subethamail.smtp.client.SMTPException;
public class MailToHostTransmitterTest {
@Tested
private MailToHostTransmitter sender;
@Injectable
private LogIdFactory logIdFactory;
@Injectable
private OutgoingConnectionsRegistry outgoingConnectionsRegistry;
@Mocked
private SmtpClient client;
private static final PostponeException POSTPONE_EXCEPTION =
new PostponeException(
10,
EnhancedStatus.TRANSIENT_SYSTEM_NOT_ACCEPTING_NETWORK_MESSAGES,
"Test exception");
private static final SMTPException SMTP_EXCEPTION = new SMTPException(
new SMTPClient.Response(500, "Test error"));
private final Mail mail = ExampleMail.simple();
@Before
public void beforeTest() {
new NonStrictExpectations() {{
client.getMtaAddress();
result = new MtaAddress(HOST1_EXAMPLE_COM, IP1);
}};
}
@Test
public void testSend() throws SendException,
RecipientsWereRejectedException, IOException, PostponeException {
sender.transmit(mail, client);
new Verifications() {
{
client.from(anyString);
client.to(anyString);
client.dataEnd();
client.quit();
}
};
}
@Test
public void testSendAllAddressRejected() throws IllegalArgumentException,
SendException, SMTPException, IOException, PostponeException {
new NonStrictExpectations() {
{
client.to(anyString);
result = SMTP_EXCEPTION;
}
};
try {
sender.transmit(mail, client);
fail("Exception must have been thrown");
} catch (RecipientsWereRejectedException e) {
assertEquals(e.rejections.size(), 1);
assertEquals(e.rejections.get(0).recipient, JANE_AS_RECIPIENT);
}
new Verifications() {
{
client.dataStart();
times = 0;
}
};
}
@Test
public void testSendFirstAddressRejectedFromTwo()
throws IllegalArgumentException, SendException, SMTPException,
IOException, PostponeException {
new NonStrictExpectations() {
{
client.to(anyString);
result = SMTP_EXCEPTION;
result = null;
}
};
try {
mail.recipients =
Arrays.asList(JANE_AS_RECIPIENT, JOHN_AS_RECIPIENT);
sender.transmit(mail, client);
fail("Exception must have been thrown");
} catch (RecipientsWereRejectedException e) {
assertEquals(1, e.rejections.size());
assertEquals(JANE_AS_RECIPIENT, e.rejections.get(0).recipient);
}
new Verifications() {
{
client.dataStart();
}
};
}
@Test
public void testSendIoExceptionIsTransient() throws SMTPException,
IOException, RecipientsWereRejectedException, PostponeException {
new NonStrictExpectations() {
{
client.to(anyString);
result = new IOException();
}
};
try {
sender.transmit(mail, client);
fail("Exception must have been thrown");
} catch (SendException e) {
assertTrue(e.errorStatus().shouldRetry());
}
}
@Test(expected = RemoteMtaErrorResponseException.class)
public void testSendSmtpErrorResponse() throws SMTPException, IOException,
RecipientsWereRejectedException, SendException, PostponeException {
new NonStrictExpectations() {
{
client.dataEnd();
result = SMTP_EXCEPTION;
}
};
sender.transmit(mail, client);
}
@Test
public void testConnectionRegistryMaintenance() throws Exception {
new Expectations() {
{
outgoingConnectionsRegistry.openConnection(IP1);
outgoingConnectionsRegistry.releaseConnection(IP1);
}
};
sender.transmit(mail, client);
}
@Test(expected = PostponeException.class)
public void testPostponedConnection() throws Exception {
new Expectations() {
{
outgoingConnectionsRegistry.openConnection(IP1);
result = POSTPONE_EXCEPTION;
}
};
sender.transmit(mail, client);
}
}