Giter Site home page Giter Site logo

something's Introduction

package mailhog

/* dependencies: testImplementation("org.testcontainers:testcontainers:1.15.2") testImplementation(platform("org.http4k:http4k-bom:4.3.5.4")) testImplementation("org.http4k:http4k-core") testImplementation("org.http4k:http4k-client-apache") { because("mailhog http api messages access") } testImplementation("org.http4k:http4k-format-jackson") { because("mailhog messages access unmarshalling") } testImplementation("com.sun.mail:javax.mail:1.5.6") { because("mailhog messages decoding") } */ import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.kotlin.KotlinModule import mailhog.MailhogJackson.auto import org.http4k.client.ApacheClient import org.http4k.core.Body import org.http4k.core.Method import org.http4k.core.Request import org.http4k.format.ConfigurableJackson import org.testcontainers.containers.GenericContainer import org.testcontainers.containers.wait.strategy.Wait import javax.mail.internet.MimeUtility

/**

  • A test container for mailhog, to allow to test sending emails with a real smtp server.
  • Example of use:
  • @Container
    
  • val mailhog = MailhogContainer()
    
  • @Test fun `my_test`() {
    
  •   myMailServiceUnderTest.setupSmtp(mailhog.smtpHost, mailhog.smtpPort)
    
  •   myMailServiceUnderTest.sendAMail()
    
  •   val messages = mailhog.messages
    
  •   expectThat(messages).hasSize(1)
    
  •   expectThat(messages)
    
  •       .filter { it.to.map { it.address }.contains("[email protected]") }
    
  •       .hasSize(1).first().and {
    
  •           get { subject }.contains("My Test")
    
  •           get { body }.contains("Hello!")
    
  •       }
    
  • }
    

*/ class MailhogContainer: GenericContainer("mailhog/mailhog") { private val PORT_SMTP = 1025 private val PORT_HTTP = 8025

init {
    withExposedPorts(PORT_SMTP, PORT_HTTP)
    waitingFor(Wait.forHttp("/"))
}

val smtpPort get() = getMappedPort(PORT_SMTP)
val smtpHost get() = getContainerIpAddress()
val httpUrl get() = "http://${getContainerIpAddress()}:${getMappedPort(PORT_HTTP)}"

val messages get() = messagesBodyLens(client(Request(Method.GET, httpUrl + "/api/v2/messages")))
    .items?.map { it.toMailMessage() }?:listOf()

companion object {
    val messagesBodyLens = Body.auto<MailhogMessages>().toLens()
    val client = ApacheClient()
}

}

// message structure for easy common use case testing data class MailMessage(val from:EmailAddress, val to:List, val subject:String, val body:String) data class EmailAddress(val address:String)

fun MailhogMessage.toMailMessage() = MailMessage( from = From?.toEmailAddress()?:throw IllegalArgumentException("no from address"), to = (To?:listOf()).map { it.toEmailAddress() }, subject = Content?.Headers?.get(MailhogMailHeaders.Subject.name)?.firstOrNull().orEmpty(), body = Content?.Body.orEmpty() .let { MimeUtility.decode(it.byteInputStream(), "quoted-printable").bufferedReader().readText() } )

fun MailhogEmailAddress.toEmailAddress() = EmailAddress(Mailbox.orEmpty() + "@" + Domain.orEmpty())

// raw Mailhog data structure data class MailhogMessages(val total: Number?, val count: Number?, val start: Number?, val items: List?)

data class MailhogMessage(val ID: String?, val From: MailhogEmailAddress?, val To: List?, val Content: MailhogContent?, val Created: String?, val MIME: Any?, val Raw: MailhogRaw?)

data class MailhogEmailAddress(val Relays: Any?, val Mailbox: String?, val Domain: String?, val Params: String?)

data class MailhogContent(val Headers: Map<String, List>, val Body: String?, val Size: Number?, val MIME: Any?)

data class MailhogRaw(val From: String?, val To: List?, val Data: String?, val Helo: String?)

enum class MailhogMailHeaders { Content-Transfer-Encoding, Content-Type, Date, From, MIME-Version, Message-ID, Received, Return-Path, Subject, To }

object MailhogJackson : ConfigurableJackson( ObjectMapper() .registerModule(KotlinModule()) .deactivateDefaultTyping() .setSerializationInclusion(JsonInclude.Include.NON_NULL) )

something's People

Contributors

pester500 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.