test(backend): add failing tests for step 4 — EmailReaderService
This commit is contained in:
@@ -0,0 +1,113 @@
|
|||||||
|
package com.condado.newsletter.service
|
||||||
|
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import jakarta.mail.Folder
|
||||||
|
import jakarta.mail.Message
|
||||||
|
import jakarta.mail.Session
|
||||||
|
import jakarta.mail.Store
|
||||||
|
import jakarta.mail.internet.InternetAddress
|
||||||
|
import jakarta.mail.internet.MimeMessage
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
class EmailReaderServiceTest {
|
||||||
|
|
||||||
|
private val mockStore: Store = mockk(relaxed = true)
|
||||||
|
private val service = EmailReaderService(storeFactory = { mockStore })
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun should_returnEmailsSortedChronologically_when_multipleEmailsFetched() {
|
||||||
|
val folder: Folder = mockk(relaxed = true)
|
||||||
|
val session: Session = mockk()
|
||||||
|
|
||||||
|
val newer = buildMimeMessage(session, "Newer email", "bob@x.com", Date())
|
||||||
|
val older = buildMimeMessage(session, "Older email", "alice@x.com", Date(System.currentTimeMillis() - 100_000))
|
||||||
|
|
||||||
|
every { mockStore.getFolder(any<String>()) } returns folder
|
||||||
|
every { folder.messageCount } returns 2
|
||||||
|
every { folder.getMessages() } returns arrayOf(newer, older)
|
||||||
|
|
||||||
|
val result = service.readEmails("INBOX", contextWindowDays = 10)
|
||||||
|
|
||||||
|
assertThat(result).hasSize(2)
|
||||||
|
assertThat(result[0].subject).isEqualTo("Older email")
|
||||||
|
assertThat(result[1].subject).isEqualTo("Newer email")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun should_returnEmptyList_when_imapConnectionFails() {
|
||||||
|
every { mockStore.getFolder(any<String>()) } throws RuntimeException("Connection refused")
|
||||||
|
|
||||||
|
val result = service.readEmails("INBOX", contextWindowDays = 3)
|
||||||
|
|
||||||
|
assertThat(result).isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun should_filterEmailsOlderThanContextWindow_when_windowIs3Days() {
|
||||||
|
val folder: Folder = mockk(relaxed = true)
|
||||||
|
val session: Session = mockk()
|
||||||
|
|
||||||
|
val recentDate = Date()
|
||||||
|
val oldDate = Date(System.currentTimeMillis() - 10L * 24 * 60 * 60 * 1000)
|
||||||
|
|
||||||
|
val recent = buildMimeMessage(session, "Recent", "a@x.com", recentDate)
|
||||||
|
val old = buildMimeMessage(session, "Old", "b@x.com", oldDate)
|
||||||
|
|
||||||
|
every { mockStore.getFolder(any<String>()) } returns folder
|
||||||
|
every { folder.messageCount } returns 2
|
||||||
|
every { folder.getMessages() } returns arrayOf(recent, old)
|
||||||
|
|
||||||
|
val result = service.readEmails("INBOX", contextWindowDays = 3)
|
||||||
|
|
||||||
|
assertThat(result).hasSize(1)
|
||||||
|
assertThat(result[0].subject).isEqualTo("Recent")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun should_stripHtml_when_emailBodyContainsHtmlTags() {
|
||||||
|
val folder: Folder = mockk(relaxed = true)
|
||||||
|
val session: Session = mockk()
|
||||||
|
|
||||||
|
val msg = buildMimeMessage(
|
||||||
|
session,
|
||||||
|
subject = "HTML email",
|
||||||
|
from = "dev@x.com",
|
||||||
|
date = Date(),
|
||||||
|
body = "<p>Hello <b>world</b></p>"
|
||||||
|
)
|
||||||
|
|
||||||
|
every { mockStore.getFolder(any<String>()) } returns folder
|
||||||
|
every { folder.messageCount } returns 1
|
||||||
|
every { folder.getMessages() } returns arrayOf(msg)
|
||||||
|
|
||||||
|
val result = service.readEmails("INBOX", contextWindowDays = 10)
|
||||||
|
|
||||||
|
assertThat(result).hasSize(1)
|
||||||
|
assertThat(result[0].body).doesNotContain("<p>", "<b>", "</b>", "</p>")
|
||||||
|
assertThat(result[0].body).contains("Hello")
|
||||||
|
assertThat(result[0].body).contains("world")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── helper ──────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private fun buildMimeMessage(
|
||||||
|
session: Session,
|
||||||
|
subject: String,
|
||||||
|
from: String,
|
||||||
|
date: Date,
|
||||||
|
body: String = "Plain text body"
|
||||||
|
): MimeMessage {
|
||||||
|
val msg: MimeMessage = mockk(relaxed = true)
|
||||||
|
every { msg.subject } returns subject
|
||||||
|
every { msg.from } returns arrayOf(InternetAddress(from))
|
||||||
|
every { msg.sentDate } returns date
|
||||||
|
every { msg.receivedDate } returns date
|
||||||
|
every { msg.contentType } returns "text/plain"
|
||||||
|
every { msg.content } returns body
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user