org.apache.james.protocols.pop3.AbstractPOP3ServerTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.james.protocols.pop3.AbstractPOP3ServerTest.java

Source

/****************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one   *
 * or more contributor license agreements.  See the NOTICE file *
 * distributed with this work for additional information        *
 * regarding copyright ownership.  The ASF licenses this file   *
 * to you 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.apache.james.protocols.pop3;

import static org.assertj.core.api.Assertions.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import org.apache.commons.net.pop3.POP3Client;
import org.apache.commons.net.pop3.POP3MessageInfo;
import org.apache.commons.net.pop3.POP3Reply;
import org.apache.james.protocols.api.Protocol;
import org.apache.james.protocols.api.ProtocolServer;
import org.apache.james.protocols.api.handler.WiringException;
import org.apache.james.protocols.api.utils.MockLogger;
import org.apache.james.protocols.api.utils.TestUtils;
import org.apache.james.protocols.pop3.core.AbstractApopCmdHandler;
import org.apache.james.protocols.pop3.core.AbstractPassCmdHandler;
import org.apache.james.protocols.pop3.mailbox.Mailbox;
import org.apache.james.protocols.pop3.utils.MockMailbox;
import org.apache.james.protocols.pop3.utils.MockMailbox.Message;
import org.apache.james.protocols.pop3.utils.TestPassCmdHandler;
import org.junit.Test;

public abstract class AbstractPOP3ServerTest {

    private static final Message MESSAGE1 = new Message("Subject: test\r\nX-Header: value\r\n", "My Body\r\n");
    private static final Message MESSAGE2 = new Message("Subject: test2\r\nX-Header: value2\r\n",
            "My Body with a DOT.\r\n.\r\n");

    private POP3Protocol createProtocol(AbstractPassCmdHandler handler) throws WiringException {
        return new POP3Protocol(new POP3ProtocolHandlerChain(handler), new POP3Configuration(), new MockLogger());
    }

    protected abstract ProtocolServer createServer(Protocol protocol, InetSocketAddress address);

    protected POP3Client createClient() {
        return new POP3Client();
    }

    @Test
    public void testInvalidAuth() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            server = createServer(createProtocol(new TestPassCmdHandler()), address);
            server.bind();

            POP3Client client = createClient();
            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("invalid", "invalid")).isFalse();
            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    @Test
    public void testEmptyInbox() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            String identifier = "id";
            TestPassCmdHandler handler = new TestPassCmdHandler();

            handler.add("valid", new MockMailbox(identifier));
            server = createServer(createProtocol(handler), address);
            server.bind();

            POP3Client client = createClient();
            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("valid", "valid")).isTrue();
            POP3MessageInfo[] info = client.listMessages();
            assertThat(info.length).isEqualTo(0);

            info = client.listUniqueIdentifiers();
            assertThat(info.length).isEqualTo(0);
            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    @Test
    public void testInboxWithMessages() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            String identifier = "id";
            TestPassCmdHandler handler = new TestPassCmdHandler();

            handler.add("valid", new MockMailbox(identifier, MESSAGE1, MESSAGE2));
            server = createServer(createProtocol(handler), address);
            server.bind();

            POP3Client client = createClient();
            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("valid", "valid")).isTrue();
            POP3MessageInfo[] info = client.listMessages();
            assertThat(info.length).isEqualTo(2);
            assertThat(info[0].size).isEqualTo((int) MESSAGE1.meta.getSize());
            assertThat(info[1].size).isEqualTo((int) MESSAGE2.meta.getSize());
            assertThat(info[0].number).isEqualTo(1);
            assertThat(info[1].number).isEqualTo(2);

            POP3MessageInfo mInfo = client.listMessage(1);
            assertThat(mInfo.size).isEqualTo((int) MESSAGE1.meta.getSize());
            assertThat(mInfo.number).isEqualTo(1);

            // try to retrieve message that not exist
            mInfo = client.listMessage(10);
            assertThat(mInfo).isNull();

            info = client.listUniqueIdentifiers();
            assertThat(info.length).isEqualTo(2);
            assertThat(info[0].identifier).isEqualTo(identifier + "-" + MESSAGE1.meta.getUid());
            assertThat(info[1].identifier).isEqualTo(identifier + "-" + MESSAGE2.meta.getUid());
            assertThat(info[0].number).isEqualTo(1);
            assertThat(info[1].number).isEqualTo(2);

            mInfo = client.listUniqueIdentifier(1);
            assertThat(mInfo.identifier).isEqualTo(identifier + "-" + MESSAGE1.meta.getUid());
            assertThat(mInfo.number).isEqualTo(1);

            // try to retrieve message that not exist
            mInfo = client.listUniqueIdentifier(10);
            assertThat(mInfo).isNull();

            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    @Test
    public void testRetr() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            String identifier = "id";
            TestPassCmdHandler factory = new TestPassCmdHandler();

            factory.add("valid", new MockMailbox(identifier, MESSAGE1, MESSAGE2));
            server = createServer(createProtocol(factory), address);
            server.bind();

            POP3Client client = createClient();
            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("valid", "valid")).isTrue();
            Reader reader = client.retrieveMessage(1);
            assertThat(reader).isNotNull();
            checkMessage(MESSAGE1, reader);
            reader.close();

            // does not exist
            reader = client.retrieveMessage(10);
            assertThat(reader).isNull();

            // delete and check for the message again, should now be deleted
            assertThat(client.deleteMessage(1)).isTrue();
            reader = client.retrieveMessage(1);
            assertThat(reader).isNull();

            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    @Test
    public void testTop() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            String identifier = "id";
            TestPassCmdHandler factory = new TestPassCmdHandler();

            factory.add("valid", new MockMailbox(identifier, MESSAGE1, MESSAGE2));
            server = createServer(createProtocol(factory), address);
            server.bind();

            POP3Client client = createClient();
            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("valid", "valid")).isTrue();
            Reader reader = client.retrieveMessageTop(1, 1000);
            assertThat(reader).isNotNull();
            checkMessage(MESSAGE1, reader);
            reader.close();

            reader = client.retrieveMessageTop(2, 1);
            assertThat(reader).isNotNull();
            checkMessage(MESSAGE2, reader, 1);
            reader.close();

            // does not exist
            reader = client.retrieveMessageTop(10, 100);
            assertThat(reader).isNull();

            // delete and check for the message again, should now be deleted
            assertThat(client.deleteMessage(1)).isTrue();
            reader = client.retrieveMessageTop(1, 1000);
            assertThat(reader).isNull();

            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    @Test
    public void testDele() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            String identifier = "id";
            TestPassCmdHandler factory = new TestPassCmdHandler();

            factory.add("valid", new MockMailbox(identifier, MESSAGE1, MESSAGE2));
            server = createServer(createProtocol(factory), address);
            server.bind();

            POP3Client client = createClient();
            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("valid", "valid")).isTrue();
            POP3MessageInfo[] info = client.listMessages();
            assertThat(info.length).isEqualTo(2);

            assertThat(client.deleteMessage(1)).isTrue();
            info = client.listMessages();
            assertThat(info.length).isEqualTo(1);

            assertThat(client.deleteMessage(1)).isFalse();
            info = client.listMessages();
            assertThat(info.length).isEqualTo(1);

            assertThat(client.deleteMessage(2)).isTrue();
            info = client.listMessages();
            assertThat(info.length).isEqualTo(0);

            // logout so the messages get expunged
            assertThat(client.logout()).isTrue();

            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("valid", "valid")).isTrue();
            info = client.listMessages();
            assertThat(info.length).isEqualTo(0);

            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    @Test
    public void testNoop() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            String identifier = "id";
            TestPassCmdHandler factory = new TestPassCmdHandler();

            factory.add("valid", new MockMailbox(identifier));
            server = createServer(createProtocol(factory), address);
            server.bind();

            POP3Client client = createClient();
            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("valid", "valid")).isTrue();
            assertThat(client.noop()).isTrue();
            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    @Test
    public void testRset() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            String identifier = "id";
            TestPassCmdHandler factory = new TestPassCmdHandler();

            factory.add("valid", new MockMailbox(identifier, MESSAGE1));
            server = createServer(createProtocol(factory), address);
            server.bind();

            POP3Client client = createClient();
            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("valid", "valid")).isTrue();
            assertThat(client.listMessages().length).isEqualTo(1);
            assertThat(client.deleteMessage(1)).isTrue();
            assertThat(client.listMessages().length).isEqualTo(0);

            // call RSET. After this the deleted mark should be removed again
            assertThat(client.reset()).isTrue();
            assertThat(client.listMessages().length).isEqualTo(1);

            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    @Test
    public void testStat() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            String identifier = "id";
            TestPassCmdHandler factory = new TestPassCmdHandler();

            factory.add("valid", new MockMailbox(identifier, MESSAGE1, MESSAGE2));
            server = createServer(createProtocol(factory), address);
            server.bind();

            POP3Client client = createClient();
            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("valid", "valid")).isTrue();
            POP3MessageInfo info = client.status();
            assertThat(info.size).isEqualTo((int) (MESSAGE1.meta.getSize() + MESSAGE2.meta.getSize()));
            assertThat(info.number).isEqualTo(2);
            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    @Test
    public void testDifferentStates() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            String identifier = "id";
            TestPassCmdHandler factory = new TestPassCmdHandler();

            factory.add("valid", new MockMailbox(identifier, MESSAGE1, MESSAGE2));
            server = createServer(createProtocol(factory), address);
            server.bind();

            POP3Client client = createClient();

            client.connect(address.getAddress().getHostAddress(), address.getPort());
            assertThat(client.listMessages()).isNull();
            assertThat(client.listUniqueIdentifiers()).isNull();
            assertThat(client.deleteMessage(1)).isFalse();
            assertThat(client.retrieveMessage(1)).isNull();
            assertThat(client.retrieveMessageTop(1, 10)).isNull();
            assertThat(client.status()).isNull();
            assertThat(client.reset()).isFalse();
            client.logout();

            client.connect(address.getAddress().getHostAddress(), address.getPort());

            assertThat(client.login("valid", "valid")).isTrue();
            assertThat(client.listMessages()).isNotNull();
            assertThat(client.listUniqueIdentifiers()).isNotNull();
            Reader reader = client.retrieveMessage(1);
            assertThat(reader).isNotNull();
            reader.close();
            assertThat(client.status()).isNotNull();
            reader = client.retrieveMessageTop(1, 1);
            assertThat(reader).isNotNull();
            reader.close();
            assertThat(client.deleteMessage(1)).isTrue();
            assertThat(client.reset()).isTrue();

            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    @Test
    public void testAPop() throws Exception {
        InetSocketAddress address = new InetSocketAddress("127.0.0.1", TestUtils.getFreePort());

        ProtocolServer server = null;
        try {
            TestApopCmdHandler handler = new TestApopCmdHandler();
            server = createServer(createProtocol(handler), address);
            server.bind();

            POP3Client client = createClient();
            client.connect(address.getAddress().getHostAddress(), address.getPort());
            String welcomeMessage = client.getReplyString();

            // check for valid syntax that include all info needed for APOP
            assertThat(welcomeMessage.trim()).matches(Pattern.compile("\\+OK \\<-?\\d+\\.\\d+@.+\\> .+"));

            assertThat(client.sendCommand("APOP invalid invalid")).isEqualTo(POP3Reply.ERROR);

            handler.add("valid", new MockMailbox("id"));
            assertThat(client.sendCommand("APOP valid valid")).isEqualTo(POP3Reply.OK);

            assertThat(client.logout()).isTrue();

        } finally {
            if (server != null) {
                server.unbind();
            }
        }

    }

    private void checkMessage(Message message, Reader reader) throws IOException {
        int read = 0;
        int i = -1;
        String content = message.toString();
        while ((i = reader.read()) != -1) {
            assertThat(i).isEqualTo(content.charAt(read++));
        }
        assertThat(read).isEqualTo(content.length());
    }

    private void checkMessage(Message message, Reader reader, int lines) throws IOException {
        int read = 0;
        String headers = message.headers + "\r\n";

        while (read < headers.length()) {
            assertThat(reader.read()).isEqualTo(headers.charAt(read++));
        }
        assertThat(read).isEqualTo(headers.length());

        BufferedReader bufReader = new BufferedReader(reader);
        String line = null;
        int linesRead = 0;
        String parts[] = message.body.split("\r\n");
        while ((line = bufReader.readLine()) != null) {
            assertThat(line).isEqualTo(parts[linesRead++]);

            if (linesRead == lines) {
                break;
            }
        }

        assertThat(linesRead).isEqualTo(lines);

    }

    private final class TestApopCmdHandler extends AbstractApopCmdHandler {
        private final Map<String, Mailbox> mailboxes = new HashMap<String, Mailbox>();

        public void add(String username, Mailbox mailbox) {
            mailboxes.put(username, mailbox);
        }

        @Override
        protected Mailbox auth(POP3Session session, String apopTimestamp, String user, String digest)
                throws Exception {
            return mailboxes.get(user);
        }

    }

}