Skip to content

Commit

Permalink
HAI-1526 Add functions to send hanke and application invitation emails
Browse files Browse the repository at this point in the history
Add templates for hanke and application invitation emails. Add functionality to send these invitations in EmailSenderService.

Note: It is possible for inviter name to be unknown. In these cases the emails use only the inviter email ([email protected] kutsui sinut..).

Using the new email sending features will be implemented on a different upcoming pr.
  • Loading branch information
pitkni committed Sep 1, 2023
1 parent 8e4ece4 commit eac3ea3
Show file tree
Hide file tree
Showing 8 changed files with 394 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ import assertk.assertions.startsWith
import com.icegreen.greenmail.configuration.GreenMailConfiguration
import com.icegreen.greenmail.junit5.GreenMailExtension
import com.icegreen.greenmail.util.ServerSetupTest
import fi.hel.haitaton.hanke.ContactType
import fi.hel.haitaton.hanke.DatabaseTest
import fi.hel.haitaton.hanke.application.ApplicationType
import fi.hel.haitaton.hanke.firstReceivedMessage
import jakarta.mail.internet.MimeMessage
import jakarta.mail.internet.MimeMultipart
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.RegisterExtension
import org.springframework.beans.factory.annotation.Autowired
Expand All @@ -22,7 +25,9 @@ import org.springframework.test.context.ActiveProfiles
import org.testcontainers.junit.jupiter.Testcontainers

private const val TEST_EMAIL = "[email protected]"
private const val HAITATON_NO_REPLY = "[email protected]"
private const val APPLICATION_IDENTIFIER = "JS2300001"
private const val DEFAULT_INVITER_NAME = "Kalle Kutsuja"

@Testcontainers
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
Expand All @@ -39,54 +44,202 @@ class EmailSenderServiceITest : DatabaseTest() {

@Autowired lateinit var emailSenderService: EmailSenderService

@Test
fun `sendJohtoselvitysCompleteEmail sends email with correct recipient`() {
emailSenderService.sendJohtoselvitysCompleteEmail(TEST_EMAIL, 13L, APPLICATION_IDENTIFIER)
@Nested
inner class JohtoSelvitysComplete {
@Test
fun `sendJohtoselvitysCompleteEmail sends email with correct recipient`() {
emailSenderService.sendJohtoselvitysCompleteEmail(
TEST_EMAIL,
13L,
APPLICATION_IDENTIFIER
)

val email = greenMail.firstReceivedMessage()
assertThat(email.allRecipients).hasSize(1)
assertThat(email.allRecipients[0].toString()).isEqualTo(TEST_EMAIL)
}
val email = greenMail.firstReceivedMessage()
assertThat(email.allRecipients).hasSize(1)
assertThat(email.allRecipients[0].toString()).isEqualTo(TEST_EMAIL)
}

@Test
fun `sendJohtoselvitysCompleteEmail sends email with sender from properties`() {
emailSenderService.sendJohtoselvitysCompleteEmail(TEST_EMAIL, 13L, APPLICATION_IDENTIFIER)
@Test
fun `sendJohtoselvitysCompleteEmail sends email with sender from properties`() {
emailSenderService.sendJohtoselvitysCompleteEmail(
TEST_EMAIL,
13L,
APPLICATION_IDENTIFIER
)

val email = greenMail.firstReceivedMessage()
assertThat(email.from).hasSize(1)
assertThat(email.from[0].toString()).isEqualTo("[email protected]")
}
val email = greenMail.firstReceivedMessage()
assertThat(email.from).hasSize(1)
assertThat(email.from[0].toString()).isEqualTo(HAITATON_NO_REPLY)
}

@Test
fun `sendJohtoselvitysCompleteEmail sends email with correct subject`() {
emailSenderService.sendJohtoselvitysCompleteEmail(TEST_EMAIL, 13L, APPLICATION_IDENTIFIER)
@Test
fun `sendJohtoselvitysCompleteEmail sends email with correct subject`() {
emailSenderService.sendJohtoselvitysCompleteEmail(
TEST_EMAIL,
13L,
APPLICATION_IDENTIFIER
)

val email = greenMail.firstReceivedMessage()
assertThat(email.subject)
.isEqualTo(
"Johtoselvitys JS2300001 / Ledningsutredning JS2300001 / Cable report JS2300001"
)
}

val email = greenMail.firstReceivedMessage()
assertThat(email.subject)
.isEqualTo(
"Johtoselvitys JS2300001 / Ledningsutredning JS2300001 / Cable report JS2300001"
@Test
fun `sendJohtoselvitysCompleteEmail sends email with parametrized hybrid body`() {
emailSenderService.sendJohtoselvitysCompleteEmail(
TEST_EMAIL,
13L,
APPLICATION_IDENTIFIER
)

val email = greenMail.firstReceivedMessage()
val (textBody, htmlBody) = getBodiesFromHybridEmail(email)
assertThat(textBody).all {
contains(APPLICATION_IDENTIFIER)
contains("http://localhost:3001/fi/hakemus/13")
contains("http://localhost:3001/sv/ansokan/13")
contains("http://localhost:3001/en/application/13")
}
// Compress all whitespace into single spaces so that they don't interfere with
// matching.
val squashedHtmlBody = htmlBody.replace("\\s+".toRegex(), " ")
assertThat(squashedHtmlBody).all {
contains(APPLICATION_IDENTIFIER)
contains("""<a href="http://localhost:3001/fi/hakemus/13">""")
contains("""<a href="http://localhost:3001/sv/ansokan/13">""")
contains("""<a href="http://localhost:3001/en/application/13">""")
}
}
}

@Test
fun `sendJohtoselvitysCompleteEmail sends email with parametrized hybrid body`() {
emailSenderService.sendJohtoselvitysCompleteEmail(TEST_EMAIL, 13L, APPLICATION_IDENTIFIER)

val email = greenMail.firstReceivedMessage()
val (textBody, htmlBody) = getBodiesFromHybridEmail(email)
assertThat(textBody).all {
contains(APPLICATION_IDENTIFIER)
contains("http://localhost:3001/fi/hakemus/13")
contains("http://localhost:3001/sv/ansokan/13")
contains("http://localhost:3001/en/application/13")
@Nested
inner class HankeInvitation {

@Test
fun `sendHankeInvitationEmail sends email with correct recipient`() {
emailSenderService.sendHankeInvitationEmail(hankeInvitationData())

val email = greenMail.firstReceivedMessage()
assertThat(email.allRecipients).hasSize(1)
assertThat(email.allRecipients[0].toString()).isEqualTo(TEST_EMAIL)
}

@Test
fun `sendHankeInvitationEmail sends email with sender from properties`() {
emailSenderService.sendHankeInvitationEmail(hankeInvitationData())

val email = greenMail.firstReceivedMessage()
assertThat(email.from).hasSize(1)
assertThat(email.from[0].toString()).isEqualTo(HAITATON_NO_REPLY)
}

@Test
fun `sendHankeInvitationEmail sends email with correct subject`() {
emailSenderService.sendHankeInvitationEmail(hankeInvitationData())

val email = greenMail.firstReceivedMessage()
assertThat(email.subject).isEqualTo("Sinut on lisätty hankkeelle HAI24-1")
}
// Compress all whitespace into single spaces so that they don't interfere with matching.
val squashedHtmlBody = htmlBody.replace("\\s+".toRegex(), " ")
assertThat(squashedHtmlBody).all {
contains(APPLICATION_IDENTIFIER)
contains("""<a href="http://localhost:3001/fi/hakemus/13">""")
contains("""<a href="http://localhost:3001/sv/ansokan/13">""")
contains("""<a href="http://localhost:3001/en/application/13">""")

@Test
fun `sendHankeInvitationEmail sends email with parametrized hybrid body`() {
val data = hankeInvitationData()

emailSenderService.sendHankeInvitationEmail(data)

val email = greenMail.firstReceivedMessage()
val (textBody, htmlBody) = getBodiesFromHybridEmail(email)
assertThat(textBody).all {
startsWith("${data.inviterName} (${data.inviterEmail}) lisäsi sinut")
contains("hankkeelle ${data.hankeNimi} (${data.hankeTunnus}).")
contains("http://localhost:3001/${data.invitationToken}")
}
assertThat(htmlBody).all {
contains("<p>${data.inviterName} (${data.inviterEmail}) lisäsi sinut")
contains("hankkeelle <b>${data.hankeNimi} (${data.hankeTunnus})</b>.")
contains("""<a href="http://localhost:3001/${data.invitationToken}">""")
}
}

@Test
fun `sendHankeInvitationEmail handles input without inviter name`() {
val data = hankeInvitationData(inviterName = null)

emailSenderService.sendHankeInvitationEmail(data)

val email = greenMail.firstReceivedMessage()
val (textBody, htmlBody) = getBodiesFromHybridEmail(email)
assertThat(textBody).startsWith("Asioija ${data.inviterEmail} lisäsi sinut")
assertThat(htmlBody).contains("<p>Asioija ${data.inviterEmail} lisäsi sinut")
}
}

@Nested
inner class ApplicationInvitation {
@Test
fun `sendApplicationInvitationEmail sends email with correct recipient`() {
emailSenderService.sendApplicationInvitationEmail(applicationInvitationData())

val email = greenMail.firstReceivedMessage()
assertThat(email.allRecipients).hasSize(1)
assertThat(email.allRecipients[0].toString()).isEqualTo(TEST_EMAIL)
}

@Test
fun `sendApplicationInvitationEmail sends email with sender from properties`() {
emailSenderService.sendApplicationInvitationEmail(applicationInvitationData())

val email = greenMail.firstReceivedMessage()
assertThat(email.from).hasSize(1)
assertThat(email.from[0].toString()).isEqualTo(HAITATON_NO_REPLY)
}

@Test
fun `sendApplicationInvitationEmail sends email with correct subject`() {
val data = applicationInvitationData()
emailSenderService.sendApplicationInvitationEmail(data)

val email = greenMail.firstReceivedMessage()
assertThat(email.subject)
.isEqualTo("Sinut on lisätty hakemukselle ${data.applicationIdentifier}")
}

@Test
fun `sendApplicationInvitationEmail sends email with parametrized hybrid body`() {
val data = applicationInvitationData()

emailSenderService.sendApplicationInvitationEmail(data)

val email = greenMail.firstReceivedMessage()
val (textBody, htmlBody) = getBodiesFromHybridEmail(email)
assertThat(textBody).all {
startsWith("${data.inviterName} (${data.inviterEmail}) on")
contains("tehnyt johtoselvityshakemuksen (${data.applicationIdentifier})")
contains("hankkeella ${data.hankeTunnus}")
contains("rooliin ${data.roleType.text()}.")
contains("Tarkastele hakemusta Haitattomassa: http://localhost:3001")
}
assertThat(htmlBody).all {
contains("${data.inviterName} (${data.inviterEmail})")
contains("johtoselvityshakemuksen (${data.applicationIdentifier})")
contains("rooliin ${data.roleType.text()}")
contains("""Tarkastele hakemusta Haitattomassa: <a href="http://localhost:3001">""")
}
}

@Test
fun `sendApplicationInvitationEmail handles input without inviter name`() {
val data = applicationInvitationData(inviterName = null)

emailSenderService.sendApplicationInvitationEmail(data)

val email = greenMail.firstReceivedMessage()
val (textBody, htmlBody) = getBodiesFromHybridEmail(email)
assertThat(textBody).startsWith("Asioija ${data.inviterEmail} on tehnyt")
assertThat(htmlBody).contains("<p>Asioija ${data.inviterEmail} on tehnyt")
}
}

Expand Down Expand Up @@ -116,4 +269,27 @@ class EmailSenderServiceITest : DatabaseTest() {
.map { i -> mp3.getBodyPart(i).content.toString() }
return Pair(bodies[0], bodies[1])
}

private fun hankeInvitationData(inviterName: String? = DEFAULT_INVITER_NAME) =
HankeInvitationData(
inviterName = inviterName,
inviterEmail = "[email protected]",
recipientEmail = TEST_EMAIL,
hankeTunnus = "HAI24-1",
hankeNimi = "Mannerheimintien liikenneuudistus",
invitationToken = "MgtzRbcPsvoKQamnaSxCnmW7",
)

private fun applicationInvitationData(inviterName: String? = DEFAULT_INVITER_NAME) =
ApplicationInvitationData(
inviterName = inviterName,
inviterEmail = "[email protected]",
recipientEmail = TEST_EMAIL,
applicationType = ApplicationType.CABLE_REPORT,
applicationIdentifier = APPLICATION_IDENTIFIER,
hankeTunnus = "HAI24-1",
roleType = ContactType.RAKENNUTTAJA,
)

private fun ContactType.text() = toString().lowercase()
}
Loading

0 comments on commit eac3ea3

Please sign in to comment.