diff --git a/build.gradle.kts b/build.gradle.kts index c231a33..e9cfc8d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -49,6 +49,7 @@ dependencies { implementation("net.pearx.kasechange:kasechange-jvm:1.1.0") implementation("com.auth0:java-jwt:3.8.2") implementation("fr.postgresjson:postgresjson:$postgresjson_version") + implementation("com.sendgrid:sendgrid-java:4.4.1") testImplementation("io.ktor:ktor-server-tests:$ktor_version") testImplementation("io.ktor:ktor-client-mock:$ktor_version") diff --git a/src/main/kotlin/fr/dcproject/Configuration.kt b/src/main/kotlin/fr/dcproject/Configuration.kt index ff9e6fb..f261b68 100644 --- a/src/main/kotlin/fr/dcproject/Configuration.kt +++ b/src/main/kotlin/fr/dcproject/Configuration.kt @@ -18,6 +18,8 @@ class Config { var username: String = config.getString("db.username") var password: String = config.getString("db.password") val port: Int = config.getInt("db.port") + + val sendGridKey: String = config.getString("mail.sendGrid.key") } object JwtConfig { diff --git a/src/main/kotlin/fr/dcproject/Module.kt b/src/main/kotlin/fr/dcproject/Module.kt index 0e99e72..7c14aa6 100644 --- a/src/main/kotlin/fr/dcproject/Module.kt +++ b/src/main/kotlin/fr/dcproject/Module.kt @@ -1,5 +1,6 @@ package fr.dcproject +import fr.dcproject.messages.Mailer import fr.postgresjson.connexion.Connection import fr.postgresjson.connexion.Requester import fr.postgresjson.migration.Migrations @@ -47,4 +48,6 @@ val Module = module { single { VoteCommentRepository(get()) } single { Migrations(connection = get(), directory = config.sqlFiles) } + + single { Mailer(config.sendGridKey) } } diff --git a/src/main/kotlin/fr/dcproject/messages/Mailer.kt b/src/main/kotlin/fr/dcproject/messages/Mailer.kt new file mode 100644 index 0000000..fa02143 --- /dev/null +++ b/src/main/kotlin/fr/dcproject/messages/Mailer.kt @@ -0,0 +1,34 @@ +package fr.dcproject.messages + +import com.sendgrid.Method +import com.sendgrid.Request +import com.sendgrid.SendGrid +import com.sendgrid.helpers.mail.Mail +import com.sendgrid.helpers.mail.objects.Content +import com.sendgrid.helpers.mail.objects.Email +import java.io.IOException + +class Mailer ( + private val key: String +) { + fun sendEmail(from: String, to: String, content: String, subject: String): Boolean { + val mail = Mail( + Email(from), + subject, + Email(to), + Content("text/plain", content) + ) + + val sg = SendGrid(key) + val request = Request() + try { + request.method = Method.POST + request.endpoint = "mail/send" + request.body = mail.build() + val response = sg.api(request) + return response.statusCode == 202 + } catch (ex: IOException) { + throw ex + } + } +} \ No newline at end of file diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index 3a4f629..d13fee4 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -19,3 +19,9 @@ db { password = dc-project port = 5432 } + +mail { + sendGrid { + key = ${?SEND_GRID_KEY} + } +} diff --git a/src/test/kotlin/MailerTest.kt b/src/test/kotlin/MailerTest.kt new file mode 100644 index 0000000..ae0ff0f --- /dev/null +++ b/src/test/kotlin/MailerTest.kt @@ -0,0 +1,28 @@ +import fr.dcproject.Env +import fr.dcproject.messages.Mailer +import fr.dcproject.module +import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.server.testing.withTestApplication +import io.ktor.util.KtorExperimentalAPI +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.koin.test.AutoCloseKoinTest +import org.koin.test.KoinTest +import org.koin.test.get + +@KtorExperimentalLocationsAPI +@KtorExperimentalAPI +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class MailerTest: KoinTest, AutoCloseKoinTest() { + @Test + fun `can be send an email`() { + withTestApplication({ module(Env.TEST) }) { + get().sendEmail( + "reset-password@dc-project.fr", + "fabrice.lecomte.be@gmail.com", + "Email Work !", + "Test" + ) + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/RepositoryTest.kt b/src/test/kotlin/RepositoryTest.kt index a8fe8ed..449dcf1 100644 --- a/src/test/kotlin/RepositoryTest.kt +++ b/src/test/kotlin/RepositoryTest.kt @@ -1,16 +1,16 @@ -import fr.dcproject.Module +import fr.dcproject.Env import fr.dcproject.entity.Article import fr.dcproject.entity.Constitution +import fr.dcproject.module import io.ktor.locations.KtorExperimentalLocationsAPI +import io.ktor.server.testing.withTestApplication import io.ktor.util.KtorExperimentalAPI import org.amshove.kluent.`should equal` import org.amshove.kluent.shouldBe -import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS -import org.koin.core.context.startKoin -import org.koin.dsl.koinApplication +import org.koin.test.AutoCloseKoinTest import org.koin.test.KoinTest import org.koin.test.get import fr.dcproject.repository.Article as RepositoryArticle @@ -19,15 +19,10 @@ import fr.dcproject.repository.Constitution as RepositoryConstitution @KtorExperimentalLocationsAPI @KtorExperimentalAPI @TestInstance(PER_CLASS) -class RepositoryTest: KoinTest { - @BeforeAll - fun beforeAll() { - startKoin { modules(Module) } - } - +class RepositoryTest: KoinTest, AutoCloseKoinTest() { @Test fun `test get repository`() { - koinApplication { + withTestApplication({ module(Env.TEST) }) { val repoArticle = get() (repoArticle is RepositoryArticle) shouldBe true repoArticle.entityName `should equal` Article::class