001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.util.test;
016    
017    import com.dumbster.smtp.MailMessage;
018    import com.dumbster.smtp.SmtpServer;
019    import com.dumbster.smtp.SmtpServerFactory;
020    import com.dumbster.smtp.mailstores.RollingMailStore;
021    
022    import com.liferay.mail.service.MailServiceUtil;
023    import com.liferay.portal.kernel.test.ReflectionTestUtil;
024    import com.liferay.portal.kernel.util.PropsKeys;
025    import com.liferay.portal.kernel.util.SocketUtil;
026    import com.liferay.portal.kernel.util.SocketUtil.ServerSocketConfigurator;
027    
028    import java.io.IOException;
029    
030    import java.net.InetAddress;
031    import java.net.ServerSocket;
032    import java.net.SocketException;
033    
034    import java.nio.channels.ServerSocketChannel;
035    
036    import java.util.ArrayList;
037    import java.util.List;
038    
039    /**
040     * @author Manuel de la Pe??a
041     * @author Jos?? Manuel Navarro
042     */
043    public class MailServiceTestUtil {
044    
045            public static void clearMessages() {
046                    _smtpServer.clearMessages();
047            }
048    
049            public static int getInboxSize() {
050                    return _smtpServer.getEmailCount();
051            }
052    
053            public static MailMessage getLastMailMessage() {
054                    MailMessage[] mailMessages = _smtpServer.getMessages();
055    
056                    if (mailMessages.length > 0) {
057                            return mailMessages[mailMessages.length - 1];
058                    }
059    
060                    throw new IndexOutOfBoundsException(
061                            "There are no messages in the inbox");
062            }
063    
064            public static List<MailMessage> getMailMessages(
065                    String headerName, String headerValue) {
066    
067                    List<MailMessage> mailMessages = new ArrayList<>();
068    
069                    for (MailMessage mailMessage : _smtpServer.getMessages()) {
070                            if (headerName.equals("Body")) {
071                                    String body = mailMessage.getBody();
072    
073                                    if (body.equals(headerValue)) {
074                                            mailMessages.add(mailMessage);
075                                    }
076                            }
077                            else {
078                                    String messageHeaderValue = mailMessage.getFirstHeaderValue(
079                                            headerName);
080    
081                                    if (messageHeaderValue.equals(headerValue)) {
082                                            mailMessages.add(mailMessage);
083                                    }
084                            }
085                    }
086    
087                    return mailMessages;
088            }
089    
090            public static boolean lastMailMessageContains(String text) {
091                    MailMessage mailMessage = getLastMailMessage();
092    
093                    String bodyMailMessage = mailMessage.getBody();
094    
095                    return bodyMailMessage.contains(text);
096            }
097    
098            public static void start() throws Exception {
099                    if (_smtpServer != null) {
100                            throw new IllegalStateException("Server is already running");
101                    }
102    
103                    int smtpPort = _getFreePort();
104    
105                    _prefsPropsTemporarySwapper = new PrefsPropsTemporarySwapper(
106                            PropsKeys.MAIL_SESSION_MAIL_SMTP_PORT, smtpPort,
107                            PropsKeys.MAIL_SESSION_MAIL, true);
108    
109                    _smtpServer = new SmtpServer();
110    
111                    _smtpServer.setMailStore(
112                            new RollingMailStore() {
113    
114                                    @Override
115                                    public void addMessage(MailMessage message) {
116                                            try {
117                                                    List<MailMessage> receivedMail =
118                                                            ReflectionTestUtil.getFieldValue(
119                                                                    this, "receivedMail");
120    
121                                                    receivedMail.add(message);
122    
123                                                    if (getEmailCount() > 100) {
124                                                            receivedMail.remove(0);
125                                                    }
126                                            }
127                                            catch (Exception e) {
128                                                    throw new RuntimeException(e);
129                                            }
130                                    }
131    
132                            });
133                    _smtpServer.setPort(smtpPort);
134    
135                    _smtpServer.setThreaded(false);
136    
137                    ReflectionTestUtil.invoke(
138                            SmtpServerFactory.class, "startServerThread",
139                            new Class<?>[] {SmtpServer.class}, _smtpServer);
140    
141                    MailServiceUtil.clearSession();
142            }
143    
144            public static void stop() throws Exception {
145                    if ((_smtpServer != null) && _smtpServer.isStopped()) {
146                            throw new IllegalStateException("Server is already stopped");
147                    }
148    
149                    _smtpServer.stop();
150    
151                    _smtpServer = null;
152    
153                    _prefsPropsTemporarySwapper.close();
154    
155                    MailServiceUtil.clearSession();
156            }
157    
158            private static int _getFreePort() throws IOException {
159                    try (ServerSocketChannel serverSocketChannel =
160                                    SocketUtil.createServerSocketChannel(
161                                            InetAddress.getLocalHost(), _START_PORT,
162                                            new ServerSocketConfigurator() {
163    
164                                                    @Override
165                                                    public void configure(ServerSocket serverSocket)
166                                                            throws SocketException {
167    
168                                                            serverSocket.setReuseAddress(true);
169                                                    }
170    
171                                            })) {
172    
173                            ServerSocket serverSocket = serverSocketChannel.socket();
174    
175                            return serverSocket.getLocalPort();
176                    }
177            }
178    
179            private static final int _START_PORT = 3241;
180    
181            private static PrefsPropsTemporarySwapper _prefsPropsTemporarySwapper;
182            private static SmtpServer _smtpServer;
183    
184    }