Extract open() method, improve Pop3Connection testing and tidy up

This commit is contained in:
Philip Whitehouse 2018-01-12 00:14:16 +00:00
parent 3cf141553e
commit 7a648cb9ab
4 changed files with 294 additions and 98 deletions

View file

@ -39,6 +39,7 @@ import static com.fsck.k9.mail.store.pop3.Pop3Commands.*;
class Pop3Connection {
private final Pop3Settings settings;
private final TrustedSocketFactory trustedSocketFactory;
private Socket socket;
private BufferedInputStream in;
private BufferedOutputStream out;
@ -52,12 +53,17 @@ class Pop3Connection {
private boolean topNotAdvertised;
Pop3Connection(Pop3Settings settings,
TrustedSocketFactory trustedSocketFactory) throws MessagingException {
TrustedSocketFactory trustedSocketFactory) {
this.settings = settings;
this.trustedSocketFactory = trustedSocketFactory;
}
void open() throws MessagingException {
try {
this.settings = settings;
SocketAddress socketAddress = new InetSocketAddress(settings.getHost(), settings.getPort());
if (settings.getConnectionSecurity() == ConnectionSecurity.SSL_TLS_REQUIRED) {
socket = trustedSocketFactory.createSocket(null, settings.getHost(), settings.getPort(), settings.getClientCertificateAlias());
socket = trustedSocketFactory.createSocket(null, settings.getHost(),
settings.getPort(), settings.getClientCertificateAlias());
} else {
socket = new Socket();
}
@ -156,7 +162,7 @@ class Pop3Connection {
default:
throw new MessagingException(
"Unhandled authentication method found in the server settings (bug).");
"Unhandled authentication method: "+authType+" found in the server settings (bug).");
}
}

View file

@ -61,6 +61,7 @@ class Pop3Folder extends Folder<Pop3Message> {
}
connection = pop3Store.createConnection();
connection.open();
String response = connection.executeSimpleCommand(STAT_COMMAND);
String[] parts = response.split(" ");

View file

@ -5,6 +5,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
@ -23,7 +24,14 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@ -35,135 +43,316 @@ public class Pop3ConnectionTest {
private static String password = "password";
private static final String INITIAL_RESPONSE = "+OK POP3 server greeting\r\n";
private static final String AUTH = "AUTH\r\n";
private static final String AUTH_HANDLE_RESPONSE = "+OK Listing of supported mechanisms follows\r\n" +
private static final String AUTH_HANDLE_RESPONSE =
"+OK Listing of supported mechanisms follows\r\n" +
"PLAIN\r\n" +
"CRAM-MD5\r\n" +
"EXTERNAL\r\n" +
".\r\n";
private static final String AUTH_NO_AUTH_PLAIN_RESPONSE = "+OK Listing of supported mechanisms follows\r\n" +
"CRAM-MD5\r\n" +
"EXTERNAL\r\n" +
".\r\n";
private static final String CAPA = "CAPA\r\n";
private static final String CAPA_RESPONSE = "+OK Listing of supported mechanisms follows\r\n" +
private static final String CAPA =
"CAPA\r\n";
private static final String CAPA_RESPONSE =
"+OK Listing of supported mechanisms follows\r\n" +
"PLAIN\r\n" +
"CRAM-MD5\r\n" +
"EXTERNAL\r\n" +
".\r\n";
private static final String CAPA_NO_AUTH_PLAIN_RESPONSE = "+OK Listing of supported mechanisms follows\r\n" +
"CRAM-MD5\r\n" +
"EXTERNAL\r\n" +
".\r\n";
private static final String LOGIN_AUTHENTICATED_RESPONSE = "+OK\r\n" + "+OK\r\n";
private static final String LOGIN = "USER "+username+"\r\n" + "PASS "+password+"\r\n";
private static final String AUTH_PLAIN_WITH_LOGIN = "AUTH PLAIN\r\n" +
new String(Base64.encodeBase64(("\000"+username+"\000"+password).getBytes())) + "\r\n";
private static final String AUTH_PLAIN_AUTHENTICATED_RESPONSE = "+OK\r\n" + "+OK\r\n";
private static final String SUCCESSFUL_PLAIN_AUTH = AUTH + CAPA + AUTH_PLAIN_WITH_LOGIN;
private static final String SUCCESSFUL_PLAIN_AUTH_RESPONSE =
INITIAL_RESPONSE +
AUTH_HANDLE_RESPONSE +
CAPA_RESPONSE +
AUTH_PLAIN_AUTHENTICATED_RESPONSE;
/**
private static final String AUTH_PLAIN_FAILED_RESPONSE = "+OK\r\n" + "Plain authentication failure";
private static final String STAT = "STAT\r\n";
private static final String STAT_RESPONSE = "+OK 20 0\r\n";
private static final String UIDL_UNSUPPORTED_RESPONSE = "-ERR UIDL unsupported\r\n";
private static final String UIDL_SUPPORTED_RESPONSE = "+OK UIDL supported\r\n";
**/
private TrustedSocketFactory mockTrustedSocketFactory;
private Socket mockSocket;
private ByteArrayOutputStream outputStream;
private ByteArrayOutputStream outputStreamForMockSocket;
private SimplePop3Settings settings;
private TrustedSocketFactory socketFactory;
@Before
public void before() throws Exception {
createCommonSettings();
createMocks();
socketFactory = TestTrustedSocketFactory.newInstance();
}
private void createCommonSettings() {
settings = new SimplePop3Settings();
settings.setUsername(username);
settings.setPassword(password);
socketFactory = TestTrustedSocketFactory.newInstance();
mockTrustedSocketFactory = mock(TrustedSocketFactory.class); //TODO: Remove
mockSocket = mock(Socket.class); //TODO: Remove
outputStream = new ByteArrayOutputStream(); //TODO: Remove
when(mockTrustedSocketFactory.createSocket(null, "server", 12345, null)).thenReturn(mockSocket); //TODO: Remove
when(mockSocket.getOutputStream()).thenReturn(outputStream); //TODO: Remove
when(mockSocket.isConnected()).thenReturn(true); //TODO: Remove
}
private void setSettingsForMockSocket() {
private void createMocks()
throws MessagingException, IOException, NoSuchAlgorithmException, KeyManagementException {
mockTrustedSocketFactory = mock(TrustedSocketFactory.class);
mockSocket = mock(Socket.class);
outputStreamForMockSocket = new ByteArrayOutputStream();
when(mockTrustedSocketFactory.createSocket(null, host, port, null))
.thenReturn(mockSocket);
when(mockSocket.getOutputStream()).thenReturn(outputStreamForMockSocket);
when(mockSocket.isConnected()).thenReturn(true);
}
private void addSettingsForValidMockSocket() {
settings.setHost(host);
settings.setPort(port);
settings.setConnectionSecurity(ConnectionSecurity.SSL_TLS_REQUIRED);
}
@Test
public void constructor_doesntCreateSocket() throws Exception {
addSettingsForValidMockSocket();
settings.setAuthType(AuthType.PLAIN);
new Pop3Connection(settings, mockTrustedSocketFactory);
verifyZeroInteractions(mockTrustedSocketFactory);
}
//Using MockSocketFactory
@Test(expected = CertificateValidationException.class)
public void whenTrustedSocketFactoryThrowsSSLCertificateException_throwCertificateValidationException() throws Exception {
when(mockTrustedSocketFactory.createSocket(null, "server", 12345, null)).thenThrow(
public void open_whenTrustedSocketFactoryThrowsSSLCertificateException_throwCertificateValidationException()
throws Exception {
when(mockTrustedSocketFactory.createSocket(null, host, port, null)).thenThrow(
new SSLException(new CertificateException()));
setSettingsForMockSocket();
addSettingsForValidMockSocket();
settings.setAuthType(AuthType.PLAIN);
new Pop3Connection(settings, mockTrustedSocketFactory);
Pop3Connection connection = new Pop3Connection(settings, mockTrustedSocketFactory);
connection.open();
}
@Test(expected = MessagingException.class)
public void whenTrustedSocketFactoryThrowsCertificateException_throwMessagingException() throws Exception {
when(mockTrustedSocketFactory.createSocket(null, "server", 12345, null)).thenThrow(
public void open_whenTrustedSocketFactoryThrowsCertificateException_throwMessagingException() throws Exception {
when(mockTrustedSocketFactory.createSocket(null, host, port, null)).thenThrow(
new SSLException(""));
setSettingsForMockSocket();
addSettingsForValidMockSocket();
settings.setAuthType(AuthType.PLAIN);
new Pop3Connection(settings, mockTrustedSocketFactory);
Pop3Connection connection = new Pop3Connection(settings, mockTrustedSocketFactory);
connection.open();
}
@Test(expected = MessagingException.class)
public void whenTrustedSocketFactoryThrowsGeneralSecurityException_throwMessagingException() throws Exception {
when(mockTrustedSocketFactory.createSocket(null, "server", 12345, null)).thenThrow(
public void open_whenTrustedSocketFactoryThrowsGeneralSecurityException_throwMessagingException() throws Exception {
when(mockTrustedSocketFactory.createSocket(null, host, port, null)).thenThrow(
new NoSuchAlgorithmException(""));
setSettingsForMockSocket();
addSettingsForValidMockSocket();
settings.setAuthType(AuthType.PLAIN);
new Pop3Connection(settings, mockTrustedSocketFactory);
Pop3Connection connection = new Pop3Connection(settings, mockTrustedSocketFactory);
connection.open();
}
@Test(expected = MessagingException.class)
public void whenTrustedSocketFactoryThrowsIOException_throwMessagingException() throws Exception {
when(mockTrustedSocketFactory.createSocket(null, "server", 12345, null)).thenThrow(
public void open_whenTrustedSocketFactoryThrowsIOException_throwMessagingException() throws Exception {
when(mockTrustedSocketFactory.createSocket(null, host, port, null)).thenThrow(
new IOException(""));
setSettingsForMockSocket();
addSettingsForValidMockSocket();
settings.setAuthType(AuthType.PLAIN);
new Pop3Connection(settings, mockTrustedSocketFactory);
Pop3Connection connection = new Pop3Connection(settings, mockTrustedSocketFactory);
connection.open();
}
@Test(expected = MessagingException.class)
public void whenSocketNotConnected_throwsMessagingException() throws Exception {
public void open_whenSocketNotConnected_throwsMessagingException() throws Exception {
when(mockSocket.isConnected()).thenReturn(false);
setSettingsForMockSocket();
addSettingsForValidMockSocket();
settings.setAuthType(AuthType.PLAIN);
new Pop3Connection(settings, mockTrustedSocketFactory);
Pop3Connection connection = new Pop3Connection(settings, mockTrustedSocketFactory);
connection.open();
}
@Test
public void withTLS_connectsToSocket() throws Exception {
String response = INITIAL_RESPONSE +
AUTH_HANDLE_RESPONSE +
CAPA_RESPONSE +
AUTH_PLAIN_AUTHENTICATED_RESPONSE;
when(mockSocket.getInputStream()).thenReturn(new ByteArrayInputStream(response.getBytes()));
setSettingsForMockSocket();
public void open_withTLS_authenticatesOverSocket() throws Exception {
when(mockSocket.getInputStream()).thenReturn(new ByteArrayInputStream(SUCCESSFUL_PLAIN_AUTH_RESPONSE.getBytes()));
addSettingsForValidMockSocket();
settings.setAuthType(AuthType.PLAIN);
new Pop3Connection(settings, mockTrustedSocketFactory);
Pop3Connection connection = new Pop3Connection(settings, mockTrustedSocketFactory);
connection.open();
assertEquals(AUTH +
CAPA +
AUTH_PLAIN_WITH_LOGIN, new String(outputStream.toByteArray()));
assertEquals(SUCCESSFUL_PLAIN_AUTH, new String(outputStreamForMockSocket.toByteArray()));
}
//Using both
@Test(expected = CertificateValidationException.class)
public void open_withSTLSunavailable_throwsCertificateValidationException() throws Exception {
MockPop3Server server = setupUnavailableStartTLSConnection();
settings.setAuthType(AuthType.PLAIN);
settings.setConnectionSecurity(ConnectionSecurity.STARTTLS_REQUIRED);
createAndOpenPop3Connection(settings, mockTrustedSocketFactory);
}
@Test
public void withAuthTypePlainAndPlainAuthCapability_performsPlainAuth() throws Exception {
public void open_withSTLSunavailable_doesntCreateSocket() throws Exception {
MockPop3Server server = setupUnavailableStartTLSConnection();
settings.setAuthType(AuthType.PLAIN);
settings.setConnectionSecurity(ConnectionSecurity.STARTTLS_REQUIRED);
try {
Pop3Connection connection = new Pop3Connection(settings, mockTrustedSocketFactory);
connection.open();
} catch (Exception ignored) {
}
verify(mockTrustedSocketFactory, never()).createSocket(any(Socket.class), anyString(),
anyInt(), anyString());
}
@Test(expected = Pop3ErrorResponse.class)
public void open_withStartTLS_withSTLSerr_throwsException() throws Exception {
MockPop3Server server = setupFailedStartTLSConnection();
when(mockTrustedSocketFactory.createSocket(
any(Socket.class), eq(server.getHost()), eq(server.getPort()), eq((String) null)))
.thenReturn(mockSocket);
when(mockSocket.getInputStream()).thenReturn(new ByteArrayInputStream(SUCCESSFUL_PLAIN_AUTH_RESPONSE.getBytes()));
createAndOpenPop3Connection(settings, mockTrustedSocketFactory);
}
@Test
public void open_withStartTLS_withSTLSerr_doesntCreateSocket() throws Exception {
MockPop3Server server = setupFailedStartTLSConnection();;
when(mockTrustedSocketFactory.createSocket(
any(Socket.class), eq(server.getHost()), eq(server.getPort()), eq((String) null)))
.thenReturn(mockSocket);
when(mockSocket.getInputStream()).thenReturn(new ByteArrayInputStream(SUCCESSFUL_PLAIN_AUTH_RESPONSE.getBytes()));
try {
createAndOpenPop3Connection(settings, mockTrustedSocketFactory);
} catch (Exception ignored) {
}
verify(mockTrustedSocketFactory, never()).createSocket(any(Socket.class), anyString(),
anyInt(), anyString());
}
@Test
public void open_withStartTLS_usesSocketFactoryToCreateTLSSocket() throws Exception {
MockPop3Server server = setupStartTLSConnection();
settings.setAuthType(AuthType.PLAIN);
when(mockTrustedSocketFactory.createSocket(
any(Socket.class), eq(server.getHost()), eq(server.getPort()), eq((String) null)))
.thenReturn(mockSocket);
when(mockSocket.getInputStream()).thenReturn(new ByteArrayInputStream(SUCCESSFUL_PLAIN_AUTH_RESPONSE.getBytes()));
createAndOpenPop3Connection(settings, mockTrustedSocketFactory);
verify(mockTrustedSocketFactory).createSocket(any(Socket.class), eq(server.getHost()),
eq(server.getPort()), eq((String) null));
}
@Test(expected = MessagingException.class)
public void open_withStartTLS_whenSocketFactoryThrowsException_ThrowsException() throws Exception {
MockPop3Server server = setupStartTLSConnection();
settings.setAuthType(AuthType.PLAIN);
when(mockTrustedSocketFactory.createSocket(
any(Socket.class), eq(server.getHost()), eq(server.getPort()), eq((String) null)))
.thenThrow(new IOException());
when(mockSocket.getInputStream()).thenReturn(new ByteArrayInputStream(SUCCESSFUL_PLAIN_AUTH_RESPONSE.getBytes()));
createAndOpenPop3Connection(settings, mockTrustedSocketFactory);
verify(mockTrustedSocketFactory).createSocket(any(Socket.class), eq(server.getHost()),
eq(server.getPort()), eq((String) null));
}
@Test
public void open_withStartTLS_authenticatesOverSecureSocket() throws Exception {
MockPop3Server server = setupStartTLSConnection();
settings.setAuthType(AuthType.PLAIN);
when(mockTrustedSocketFactory.createSocket(
any(Socket.class), eq(server.getHost()), eq(server.getPort()), eq((String) null)))
.thenReturn(mockSocket);
when(mockSocket.getInputStream()).thenReturn(new ByteArrayInputStream(SUCCESSFUL_PLAIN_AUTH_RESPONSE.getBytes()));
createAndOpenPop3Connection(settings, mockTrustedSocketFactory);
assertEquals(SUCCESSFUL_PLAIN_AUTH, new String(outputStreamForMockSocket.toByteArray()));
}
private MockPop3Server setupStartTLSConnection() throws IOException {new MockPop3Server();
MockPop3Server server = new MockPop3Server();
setupServerWithStartTLSAvailable(server);
server.expect("STLS");
server.output("+OK Begin TLS negotiation");
server.start();
settings.setHost(server.getHost());
settings.setPort(server.getPort());
settings.setConnectionSecurity(ConnectionSecurity.STARTTLS_REQUIRED);
return server;
}
private MockPop3Server setupFailedStartTLSConnection() throws IOException {new MockPop3Server();
MockPop3Server server = new MockPop3Server();
setupServerWithStartTLSAvailable(server);
server.expect("STLS");
server.output("-ERR Unavailable");
server.start();
settings.setHost(server.getHost());
settings.setPort(server.getPort());
settings.setConnectionSecurity(ConnectionSecurity.STARTTLS_REQUIRED);
return server;
}
private MockPop3Server setupUnavailableStartTLSConnection() throws IOException {new MockPop3Server();
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output(".");
server.start();
settings.setHost(server.getHost());
settings.setPort(server.getPort());
settings.setConnectionSecurity(ConnectionSecurity.STARTTLS_REQUIRED);
return server;
}
private void setupServerWithStartTLSAvailable(MockPop3Server server) {
server.output("+OK POP3 server greeting");
server.expect("AUTH");
server.output("+OK Listing of supported mechanisms follows");
server.output("PLAIN");
server.output(".");
server.expect("CAPA");
server.output("+OK Listing of supported mechanisms follows");
server.output("STLS");
server.output(".");
}
//Using RealSocketFactory with MockPop3Server
@Test
public void open_withAuthTypePlainAndPlainAuthCapability_performsPlainAuth() throws Exception {
settings.setAuthType(AuthType.PLAIN);
MockPop3Server server = new MockPop3Server();
@ -184,14 +373,14 @@ public class Pop3ConnectionTest {
server.output("+OK");
server.expect(new String(Base64.encodeBase64(("\000"+username+"\000"+password).getBytes())));
server.output("+OK");
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
server.verifyConnectionStillOpen();
server.verifyInteractionCompleted();
}
@Test
public void withAuthTypePlainAndPlainAuthCapabilityAndInvalidPasswordResponse_throwsException() throws Exception {
public void open_withAuthTypePlainAndPlainAuthCapabilityAndInvalidPasswordResponse_throwsException() throws Exception {
settings.setAuthType(AuthType.PLAIN);
MockPop3Server server = new MockPop3Server();
@ -214,7 +403,7 @@ public class Pop3ConnectionTest {
server.output("-ERR");
try {
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
fail("Expected auth failure");
} catch (AuthenticationFailedException ignored) {}
@ -222,7 +411,7 @@ public class Pop3ConnectionTest {
}
@Test
public void withAuthTypePlainAndNoPlainAuthCapability_performsLogin() throws Exception {
public void open_withAuthTypePlainAndNoPlainAuthCapability_performsLogin() throws Exception {
settings.setAuthType(AuthType.PLAIN);
MockPop3Server server = new MockPop3Server();
@ -243,7 +432,7 @@ public class Pop3ConnectionTest {
server.output("-ERR");
try {
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
fail("Expected auth failure");
} catch (AuthenticationFailedException ignored) {}
@ -251,7 +440,7 @@ public class Pop3ConnectionTest {
}
@Test
public void withAuthTypePlainAndNoPlainAuthCapabilityAndLoginFailure_throwsException() throws Exception {
public void open_withAuthTypePlainAndNoPlainAuthCapabilityAndLoginFailure_throwsException() throws Exception {
settings.setAuthType(AuthType.PLAIN);
MockPop3Server server = new MockPop3Server();
@ -271,16 +460,15 @@ public class Pop3ConnectionTest {
server.expect("PASS password");
server.output("+OK");
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
server.verifyInteractionCompleted();
}
@Test
public void withAuthTypeCramMd5AndCapability_performsCramMd5Auth() throws IOException, MessagingException {
public void open_withAuthTypeCramMd5AndCapability_performsCramMd5Auth() throws IOException, MessagingException {
settings.setAuthType(AuthType.CRAM_MD5);
MockPop3Server server = new MockPop3Server();
server.output("+OK POP3 server greeting");
server.expect("AUTH");
@ -299,14 +487,14 @@ public class Pop3ConnectionTest {
server.output("+ abcd");
server.expect("dXNlciBhZGFhZTU2Zjk1NzAxZjQwNDQwZjhhMWU2YzY1ZjZmZg==");
server.output("+OK");
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
server.verifyConnectionStillOpen();
server.verifyInteractionCompleted();
}
@Test
public void withAuthTypeCramMd5AndCapabilityAndCramFailure_throwsException() throws IOException, MessagingException {
public void open_withAuthTypeCramMd5AndCapabilityAndCramFailure_throwsException() throws IOException, MessagingException {
settings.setAuthType(AuthType.CRAM_MD5);
@ -330,7 +518,7 @@ public class Pop3ConnectionTest {
server.output("-ERR");
try {
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
fail("Expected auth failure");
} catch (AuthenticationFailedException ignored) {}
@ -338,7 +526,7 @@ public class Pop3ConnectionTest {
}
@Test
public void withAuthTypeCramMd5AndNoCapability_performsApopAuth() throws IOException, MessagingException {
public void open_withAuthTypeCramMd5AndNoCapability_performsApopAuth() throws IOException, MessagingException {
settings.setAuthType(AuthType.CRAM_MD5);
MockPop3Server server = new MockPop3Server();
@ -355,14 +543,14 @@ public class Pop3ConnectionTest {
server.output(".");
server.expect("APOP user c8e8c560e385faaa6367d4145572b8ea");
server.output("+OK");
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
server.verifyConnectionStillOpen();
server.verifyInteractionCompleted();
}
@Test
public void withAuthTypeCramMd5AndNoCapabilityAndApopFailure_throwsException() throws IOException, MessagingException {
public void open_withAuthTypeCramMd5AndNoCapabilityAndApopFailure_throwsException() throws IOException, MessagingException {
settings.setAuthType(AuthType.CRAM_MD5);
@ -382,7 +570,7 @@ public class Pop3ConnectionTest {
server.output("-ERR");
try {
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
fail("Expected auth failure");
} catch (AuthenticationFailedException ignored) {}
@ -390,7 +578,7 @@ public class Pop3ConnectionTest {
}
@Test
public void withAuthTypeExternalAndCapability_performsExternalAuth() throws IOException, MessagingException {
public void open_withAuthTypeExternalAndCapability_performsExternalAuth() throws IOException, MessagingException {
settings.setAuthType(AuthType.EXTERNAL);
MockPop3Server server = new MockPop3Server();
@ -409,14 +597,14 @@ public class Pop3ConnectionTest {
server.output(".");
server.expect("AUTH EXTERNAL dXNlcg==");
server.output("+OK");
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
server.verifyConnectionStillOpen();
server.verifyInteractionCompleted();
}
@Test
public void withAuthTypeExternalAndNoCapability_throwsCVE() throws IOException, MessagingException {
public void open_withAuthTypeExternalAndNoCapability_throwsCVE() throws IOException, MessagingException {
settings.setAuthType(AuthType.EXTERNAL);
MockPop3Server server = new MockPop3Server();
@ -434,7 +622,7 @@ public class Pop3ConnectionTest {
server.output(".");
try {
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
fail("CVE expected");
} catch (CertificateValidationException e) {
assertEquals(Reason.MissingCapability, e.getReason());
@ -445,7 +633,7 @@ public class Pop3ConnectionTest {
}
@Test
public void withAuthTypeExternalAndCapability_withRejection_throwsCVE() throws IOException, MessagingException {
public void open_withAuthTypeExternalAndCapability_withRejection_throwsCVE() throws IOException, MessagingException {
settings.setAuthType(AuthType.EXTERNAL);
MockPop3Server server = new MockPop3Server();
@ -466,7 +654,7 @@ public class Pop3ConnectionTest {
server.output("-ERR Invalid certificate");
try {
startServerAndCreateConnection(server);
startServerAndCreateOpenConnection(server);
fail("CVE expected");
} catch (CertificateValidationException e) {
assertEquals("POP3 client certificate authentication failed: -ERR Invalid certificate", e.getMessage());
@ -475,16 +663,17 @@ public class Pop3ConnectionTest {
server.verifyInteractionCompleted();
}
private Pop3Connection startServerAndCreateConnection(MockPop3Server server) throws IOException,
private void startServerAndCreateOpenConnection(MockPop3Server server) throws IOException,
MessagingException {
server.start();
settings.setHost(server.getHost());
settings.setPort(server.getPort());
return createPop3Connection(settings, socketFactory);
createAndOpenPop3Connection(settings, socketFactory);
}
private Pop3Connection createPop3Connection(Pop3Settings settings, TrustedSocketFactory socketFactory)
private void createAndOpenPop3Connection(Pop3Settings settings, TrustedSocketFactory socketFactory)
throws MessagingException {
return new Pop3Connection(settings, socketFactory);
Pop3Connection connection = new Pop3Connection(settings, socketFactory);
connection.open();
}
}

View file

@ -53,16 +53,7 @@ public class Pop3FolderTest {
when(mockStore.createConnection()).thenReturn(mockConnection);
when(mockConnection.executeSimpleCommand(Pop3Commands.STAT_COMMAND)).thenReturn("+OK 10 0");
folder = new Pop3Folder(mockStore, "Inbox");
setupTempDirectory();
}
private void setupTempDirectory() {
File tempDirectory = new File("temp");
if (!tempDirectory.exists()) {
assertTrue(tempDirectory.mkdir());
tempDirectory.deleteOnExit();
}
BinaryTempFileBody.setTempDirectory(tempDirectory);
BinaryTempFileBody.setTempDirectory(new File(System.getProperty("java.io.tmpdir")));
}
@Test
@ -158,6 +149,15 @@ public class Pop3FolderTest {
folder.open(Folder.OPEN_MODE_RW);
}
@Test
public void open_createsAndOpensConnection()
throws MessagingException {
folder.open(Folder.OPEN_MODE_RW);
verify(mockStore, times(1)).createConnection();
verify(mockConnection).open();
}
@Test
public void open_whenAlreadyOpenWithValidConnection_doesNotCreateAnotherConnection()
throws MessagingException {