Java Utility for sending reading emails - yoss123/test-automation-repo GitHub Wiki

Add the next dependency to pom.xml

<dependency>
     <groupId>com.sun.mail</groupId>
     <artifactId>javax.mail</artifactId>
     <version>1.6.2</version>
</dependency>
package com.[project-name].utils;

import org.junit.Assert;
import org.junit.Test;
import org.junit.jupiter.api.DisplayName;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Paths;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * Turn POP and IMAP on for users: Settings -> Forwarding and POP/IMAP -> POP download -> set to enabled ; IMAP access -> Enabled IMAP
 *
 * Important note !!!
 * Since May 30, 2022 Google is no longer provide access to less secure applications.
 * In other words, applications cannot simply authenticate with a user's username and password to send emails.
 * So that existing applications that send or receive emails using Google accounts continue to work without requiring changes in their programming,
 * there is the possibility of using an 'App Password.'
 *
 * Steps to obtain an App Password:
 * 1. Turn on two-step verification for your Google account
 * 2. Create an app password (https://support.google.com/mail/answer/185833?hl=en)
 * 3. Use that password in the application (assigning it to the corresponding password property).
 * (https://www.genexus.com/en/read-news/anuncio-el-30-de-mayo-google-deja-de-soportar-el-mecanismo-habitual-de-autenticacion-para-mails)
 */

/**
 * SMTP – Simple Mail Transfer Protocol is used for sending e-mails.
 * POP3 – Post Office Protocol is used to receive e-mails. It provides one to one mapping for users and mailboxes, which is one mailbox for one user.
 * IMAP – Internet Message Access Protocol is also used to receive e-mails. It supports multiple mailboxes for a single user.
 */

public class MailUtil {

    public static boolean sendMessage(String emailAddress, String emailPassword, String mailSentFromAddress,
                                      String mailRecipientslist, String mailSubject, String mailMessage, File file2attach) {
        try {
            Properties prop = new Properties();
            prop.put("mail.smtp.host", "smtp.gmail.com");
            prop.put("mail.smtp.port", "587");
            prop.put("mail.smtp.auth", "true");
            prop.put("mail.smtp.starttls.enable", "true"); // Transport Layer Security (TLS)
            Session mailSession = Session.getInstance(prop,
                    new javax.mail.Authenticator() {
                        protected PasswordAuthentication getPasswordAuthentication() {
                            return new PasswordAuthentication(emailAddress, emailPassword);
                        }
                    });

            Message message = new MimeMessage(mailSession);
            message.setFrom(new InternetAddress(mailSentFromAddress));
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(mailRecipientslist));
            message.setSubject(mailSubject);

//            String htmlMessage = "This is my <b style='color:red;'>bold-red email</b> using JavaMailer";
            MimeBodyPart mimeBodyPart = new MimeBodyPart();
            mimeBodyPart.setContent(mailMessage, "text/html");
            Multipart multipart = new MimeMultipart();
            multipart.addBodyPart(mimeBodyPart);
            message.setContent(multipart);
            // Alternatively you can set the email content with the next line:
            // message.setText(mailMessage);

            if(Objects.nonNull(file2attach)) {
                MimeBodyPart attachmentBodyPart = new MimeBodyPart();
                attachmentBodyPart.attachFile(file2attach);
                multipart.addBodyPart(attachmentBodyPart);
            }

            Transport.send(message);
            return true;
        } catch (MessagingException | IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    private static Session getSession2readEmails() {
        Properties prop = new Properties();
        prop.put("mail.pop3.host", "pop.gmail.com");
        prop.put("mail.pop3.port", "995");
        prop.put("mail.pop3.starttls.enable", "true");
        return Session.getDefaultInstance(prop);
    }

    private static void printEmailMessage(Message message) {
        try {
            System.out.println("------------ Start of email message -----------------");
            System.out.println("Email subject: " + message.getSubject());
            System.out.println("Sender: ");
            List.of(message.getFrom()).stream().forEach(sender -> System.out.print(sender+" "));
            System.out.println();
            System.out.print("Recipients: ");
            List.of(message.getAllRecipients()).stream().forEach(recipient -> System.out.print(recipient+" "));
            System.out.println();
            System.out.print("Reply to: ");
            List.of(message.getReplyTo()).stream().forEach(reply2 -> System.out.print(reply2+" "));
            System.out.println();
            System.out.println("Sent date: " + message.getSentDate());
            System.out.println("Recieved date: " + message.getReceivedDate());
            System.out.println("Message number: " + message.getMessageNumber());
            System.out.println("Content type: " + message.getContentType());
            System.out.println("Description: " + message.getDescription());
            System.out.println("Flags: " + message.getFlags());
            System.out.println("Content: " + getTextFromMessage(message));
            System.out.println("------------ End of email message -------------------");
        } catch(MessagingException | IOException e) {
            e.printStackTrace();
        }
    }

    public static boolean isExpectedEmailInInbox(String userName, String password, String expectedEmailMessageContent,
                                                 String mentionedUserMailSubject, String mentionedUserMailFrom, long timeoutInSeconds) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
        Timestamp timeoutInTimestamp = Timestamp.from(new Timestamp(System.currentTimeMillis()).toInstant().plusSeconds(timeoutInSeconds));
        String formatedTimeout = simpleDateFormat.format(new Date(timeoutInTimestamp.getTime()));
        System.out.println("Current time is "+simpleDateFormat.format(new Date())+" while timeout to recieve expected email is "+formatedTimeout);

        while(System.currentTimeMillis() < timeoutInTimestamp.getTime()) {
            if(isExpectedEmailInInbox(userName, password, expectedEmailMessageContent, mentionedUserMailSubject, mentionedUserMailFrom)) {
                System.out.println("Expected email was found in the Inbox of "+userName+" at "
                        +simpleDateFormat.format(new Date())+".");
                return true;
            }
            else {
                System.out.println("Expected email wasn't found in the Inbox of "+userName+" at "
                        +simpleDateFormat.format(new Date())+". Trying until timeout ("+formatedTimeout+")");
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {e.printStackTrace();}
            }
        }
        return false;
    }

    public static boolean isExpectedEmailInInbox(String userName, String password, String expectedEmailMessageContent,
                                                 String expectedMailSubject, String expectedMailFrom) {
        Session mailSession = null;
        Store store = null;
        Folder inbox = null;

        try {
            mailSession = getSession2readEmails();
            store = mailSession.getStore("pop3s");
            store.connect("pop.gmail.com", userName, password);
            inbox = store.getFolder("INBOX");
            inbox.open(Folder.READ_ONLY);
            Message[] messages = inbox.getMessages();
            return Arrays.stream(messages).anyMatch(message -> {
                try {
                    if(message.getSubject().equals(expectedMailSubject) && message.getFrom()[0].toString().equals(expectedMailFrom)) {
                        System.out.println("Email with EXPECTED subject '"+expectedMailSubject
                                +"' and sender '"+expectedMailFrom+"' was found in Inbox.");
                        String contentFromMessage = MailUtil.getTextFromMessage(message);

                        // Saving the 2 results (actual & expected) to further inquiry in case of a test failure
                        Files.write(Paths.get("contentFromMessage.txt"), contentFromMessage.getBytes());
                        contentFromMessage = Files.lines(Paths.get("contentFromMessage.txt")).collect(Collectors.joining(System.lineSeparator()));
                        Files.write(Paths.get("expectedCommentsEmail.txt"), expectedEmailMessageContent.getBytes(), new OpenOption[0]);
                        String expectedEmailMessageContentStr = Files.lines(Paths.get("expectedCommentsEmail.txt")).collect(Collectors.joining(System.lineSeparator()));

                        return contentFromMessage.equals(expectedEmailMessageContentStr);
                    } else {
                        return false;
                    }
                } catch (MessagingException | IOException e) {
                    e.printStackTrace();
                    return false;
                }
            });
        } catch (MessagingException e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (Objects.nonNull(inbox)) inbox.close(false);
                if(Objects.nonNull(store)) store.close();
            } catch(MessagingException e) {
                e.printStackTrace();
            }

        }
    }

    public static String getTextFromMessage(Message message) throws MessagingException, IOException {
        if(message.isMimeType("text/plain")) {
            return message.getContent().toString();
        } else if (message.isMimeType("text/html")){
            return message.getContent().toString();
        } else if (message.isMimeType("multipart/*")) {
            MimeMultipart mimeMultipart = (MimeMultipart) message.getContent();
            return getTextFromMimeMultipart(mimeMultipart);
        } else {
            System.out.println("Error -> Unknown MimeType");
            return null;
        }
    }

    private static String getTextFromMimeMultipart(
            MimeMultipart mimeMultipart)  throws MessagingException, IOException{
        String result = "";
        int mimeMultipartCount = mimeMultipart.getCount();
        for (int counter = 0; counter < mimeMultipartCount; counter++) {
            BodyPart bodyPart = mimeMultipart.getBodyPart(counter);
            if (bodyPart.isMimeType("text/plain")) {
                result = result + "\n" + bodyPart.getContent();
//                break; // without break same text appears twice in my tests
            } else if (bodyPart.isMimeType("text/html")) {
                result = result + "\n" + bodyPart.getContent();
            } else if (bodyPart.getContent() instanceof MimeMultipart){
                result = result + getTextFromMimeMultipart((MimeMultipart)bodyPart.getContent());
            }
        }
        return result;
    }

    @Test
    @DisplayName("Test send & recieve email")
    public void testSendAndRecieveEmail() {
        String testUserEmail = "[email protected]";
        String testUserEmailPassword = "Rami12levy";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyy hh:mm:ss");
        String mailSubject = "Test send & recieve email on "+simpleDateFormat.format(new Date());
        String emailMessage = "<b style='color:blue;'>Dear recipient,</b><br><br> "
                +"This is a <b>TEST</b> email to test SEND & RECIEVE emails via JAVA API<br><br>"
                +"Thanks<br><br>"
                +"Tester";
        sendMessage(testUserEmail, testUserEmailPassword, testUserEmail, testUserEmail, mailSubject,
                emailMessage, null);
        System.out.println("Email with subject '"+mailSubject+"' was sent. Now testing if its arrived to Inbox...");

        Assert.assertTrue("Sent email wasn't found in Inbox",
                isExpectedEmailInInbox(testUserEmail, testUserEmailPassword, emailMessage, mailSubject, testUserEmail, 120));
    }
}
⚠️ **GitHub.com Fallback** ⚠️