-
Notifications
You must be signed in to change notification settings - Fork 1
/
MailApiTest.scala
134 lines (108 loc) · 4.69 KB
/
MailApiTest.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package email
import com.sun.mail.imap.IdleManager
import io.qameta.allure.scalatest.AllureScalatestContext
import java.nio.file.Paths
import java.util.Properties
import javax.activation.{DataHandler, FileDataSource}
import javax.mail._
import javax.mail.event.{MessageCountAdapter, MessageCountEvent}
import javax.mail.internet.{InternetAddress, MimeBodyPart, MimeMessage, MimeMultipart}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Future, Promise}
import scala.io.Source
class MailApiTest extends BaseApiTest {
val messageSubject = "DEBUG MESSAGE"
val folderName = "Inbox"
val to: String = config.getString("recipient")
val from: String = config.getString("sender")
val props: Properties = getProperties
"Client" should "be able to send email message" in new AllureScalatestContext {
val session: Session = getSession(props)
sendEmail(session, from, to, messageSubject, "files/test.txt",
"files/test_attachment.txt")
}
"Client" should "be able to receive email message" in new AllureScalatestContext {
val session: Session = getSession(props)
val folder: Folder = openFolderInMailBox(session, folderName)
val message = receiveEmail(session, folder, messageSubject)
message.getSubject should be (messageSubject)
}
private def sendEmail(session: Session, from: String, to: String, subject: String, messagePath: String,
attachment: String): Unit = {
val message = new MimeMessage(session)
message.setFrom(new InternetAddress(from))
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to))
message.setSubject(subject)
val textPart = new MimeBodyPart
textPart.setText(Source.fromResource(messagePath).mkString)
val filePart = new MimeBodyPart
val res = getClass.getClassLoader.getResource(attachment)
val file = Paths.get(res.toURI).toFile
val fds = new FileDataSource(file.getAbsolutePath)
filePart.setDataHandler(new DataHandler(fds))
filePart.setFileName(fds.getName)
val multipart = new MimeMultipart
multipart.addBodyPart(textPart)
multipart.addBodyPart(filePart)
message.setContent(multipart)
Transport.send(message)
log.info(s"Message <$subject> is sent to $to")
}
private def receiveEmail(session: Session, folder: Folder, subject: String): Message = {
val manager = getIdleManager(session)
val event = waitForFirst(awaitForNewMessages(folder, manager))(_
.getMessages.toList.head.getSubject.contains(subject)).futureValue
val message = event.getMessages.toList.head
log.info(s"Message <${message.getSubject}> is received")
message
}
private def getIdleManager(session: Session) = {
new IdleManager(session, java.util.concurrent.Executors.newSingleThreadExecutor())
}
private def openFolderInMailBox(session: Session, folderName: String) = {
val store = session.getStore("imaps")
store.connect("imap.gmail.com", from,
config.getString("password"))
val folder = store.getFolder(folderName)
folder.open(Folder.READ_WRITE)
log.info(s"$folderName folder is opened for $from")
folder
}
private def awaitForNewMessages(folderName: Folder, idleManager: IdleManager): Future[MessageCountEvent] = {
val promise = Promise[MessageCountEvent]
folderName.addMessageCountListener(new MessageCountAdapter {
override def messagesAdded(e: MessageCountEvent): Unit = {
promise.trySuccess(e)
}
})
idleManager.watch(folderName)
promise.future
}
private def waitForFirst[A](futureA: => Future[A])(predicate: A => Boolean): Future[A] = {
futureA
.filter(predicate)
.recoverWith { case _: NoSuchElementException => waitForFirst(futureA)(predicate) }
}
private def getSession(properties: Properties) = {
val session: Session = Session.getInstance(properties, new Authenticator() {
override protected def getPasswordAuthentication: PasswordAuthentication = {
new PasswordAuthentication(config.getString("username"), config.getString("password"))
}
})
session.setDebug(false)
session
}
private def getProperties = {
val properties = System.getProperties
properties.put("mail.smtp.host", "smtp.gmail.com")
properties.put("mail.smtp.port", "465")
properties.put("mail.smtp.auth", "true")
properties.put("mail.smtp.ssl.enable", "true")
properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory")
properties.put("mail.store.protocol", "imaps")
properties.put("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory")
properties.put("mail.imap.socketFactory.fallback", "false")
properties.put("mail.imaps.usesocketchannels", "true")
properties
}
}