-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(mail): support the use of markdown in the email body
- Loading branch information
Showing
9 changed files
with
180 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package support | ||
|
||
import org.intellij.markdown.IElementType | ||
import org.intellij.markdown.ast.ASTNode | ||
import org.intellij.markdown.flavours.MarkdownFlavourDescriptor | ||
import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor | ||
import org.intellij.markdown.html.HtmlGenerator | ||
import org.intellij.markdown.parser.MarkdownParser | ||
|
||
private val flavour: MarkdownFlavourDescriptor = CommonMarkFlavourDescriptor() | ||
private val parser: MarkdownParser = MarkdownParser(flavour) | ||
|
||
fun markdownToHtml(markdownText: String): String { | ||
val parsedTree = parser.buildMarkdownTreeFromString(markdownText) | ||
return generateHtml(markdownText, parsedTree) | ||
} | ||
|
||
// https://github.com/JetBrains/markdown/issues/72 | ||
fun markdownToEmbeddedHtml(markdownText: String): String { | ||
val parsedTree = parser.parse(IElementType("ROOT"), markdownText) | ||
return generateHtml(markdownText, parsedTree) | ||
} | ||
|
||
private fun generateHtml(markdownText: String, parsedTree: ASTNode): String { | ||
return HtmlGenerator(markdownText, parsedTree, flavour).generateHtml() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -63,7 +63,7 @@ | |
padding-right: 8px; | ||
" | ||
> | ||
<span th:utext="${content}"></span> | ||
[(${content})] | ||
</td> | ||
</tr> | ||
</table> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package apply.application.mail | ||
|
||
import mu.KotlinLogging | ||
import org.springframework.core.io.ByteArrayResource | ||
|
||
private val logger = KotlinLogging.logger {} | ||
|
||
class FakeMailSender : MailSender { | ||
override fun send(toAddress: String, subject: String, body: String) { | ||
logger.debug { "toAddress: $toAddress, subject: $subject" } | ||
logger.debug { "body: $body" } | ||
} | ||
|
||
override fun sendBcc( | ||
toAddresses: List<String>, | ||
subject: String, | ||
body: String, | ||
attachments: Map<String, ByteArrayResource> | ||
) { | ||
logger.debug { "toAddresses: $toAddresses, subject: $subject" } | ||
logger.debug { "body: $body" } | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
src/test/kotlin/apply/application/mail/MailServiceIntegrationTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package apply.application.mail | ||
|
||
import apply.config.TestMailConfiguration | ||
import apply.createMailData | ||
import io.kotest.core.spec.style.BehaviorSpec | ||
import io.kotest.matchers.string.shouldContain | ||
import org.springframework.context.annotation.Import | ||
import support.test.IntegrationTest | ||
|
||
@Import(TestMailConfiguration::class) | ||
@IntegrationTest | ||
class MailServiceIntegrationTest( | ||
private val mailService: MailService | ||
) : BehaviorSpec({ | ||
Given("마크다운으로 본문을 작성한 이메일이 있는 경우") { | ||
val body = """ | ||
|안녕하세요. 우아한테크코스입니다. | ||
|오늘은 미션 안내와 더불어 2주 차부터 시작되는 커뮤니티에 대한 가이드도 함께 공유드리니 **반드시 이메일 내용을 꼼꼼하게 정독**해 주세요. | ||
""".trimMargin() | ||
val mailData = createMailData(body = body) | ||
|
||
When("이메일 본문을 생성하면") { | ||
val actual = mailService.generateMailBody(mailData) | ||
|
||
Then("본문이 HTML로 변환된 이메일이 생성된다") { | ||
actual shouldContain "<title>email</title>" | ||
actual shouldContain """ | ||
|<p>안녕하세요. 우아한테크코스입니다.<br /> | ||
|오늘은 미션 안내와 더불어 2주 차부터 시작되는 커뮤니티에 대한 가이드도 함께 공유드리니 <strong>반드시 이메일 내용을 꼼꼼하게 정독</strong>해 주세요.</p> | ||
""".trimMargin() | ||
} | ||
} | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package apply.config | ||
|
||
import apply.application.mail.FakeMailSender | ||
import apply.application.mail.MailSender | ||
import org.springframework.boot.test.context.TestConfiguration | ||
import org.springframework.context.annotation.Bean | ||
import org.springframework.context.annotation.Primary | ||
|
||
@TestConfiguration | ||
class TestMailConfiguration { | ||
@Primary | ||
@Bean | ||
fun fakeMailSender(): MailSender { | ||
return FakeMailSender() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package support | ||
|
||
import io.kotest.core.spec.style.StringSpec | ||
import io.kotest.matchers.shouldBe | ||
import io.kotest.matchers.string.shouldNotContain | ||
|
||
class MarkdownTest : StringSpec({ | ||
"마크다운을 HTML로 변환한다" { | ||
val markdownText = """ | ||
|# 마크다운 | ||
| | ||
|## 마크다운(Markdown)이란? | ||
| | ||
|2004년에 존 그루버(John Gruber)와 애런 스워츠(Aaron Swartz)가 만든 마크업 언어의 하나로 읽기 쉽고 쓰기 쉬운 텍스트 포맷입니다. | ||
| | ||
|이 페이지의 왼쪽은 마크다운 편집기입니다. **자유롭게 연습해 보세요**. 여러분이 연습한 내용은 다른 사람에게 보이지 않고, 저장되지 않습니다. | ||
| | ||
|아래 링크를 클릭하여 해당 도움말(연습장)로 바로 이동할 수도 있습니다. | ||
| | ||
|* [문단](#paragraph) | ||
|* [제목](#heading) | ||
|* [인용](#blockquote) | ||
|* [강조](#emphasis) | ||
|* [취소선](#strike) | ||
|* [목록](#list) | ||
|* [할일 목록](#tasklist) | ||
|* [링크](#link) | ||
|* [표](#table) | ||
|* [코드 포맷](#code) | ||
|* [수식](#math) | ||
|* [UML](#uml) | ||
""".trimMargin() | ||
val actual = markdownToHtml(markdownText) | ||
actual shouldBe """ | ||
|<body> | ||
|<h1>마크다운</h1> | ||
|<h2>마크다운(Markdown)이란?</h2> | ||
|<p>2004년에 존 그루버(John Gruber)와 애런 스워츠(Aaron Swartz)가 만든 마크업 언어의 하나로 읽기 쉽고 쓰기 쉬운 텍스트 포맷입니다.</p> | ||
|<p>이 페이지의 왼쪽은 마크다운 편집기입니다. <strong>자유롭게 연습해 보세요</strong>. 여러분이 연습한 내용은 다른 사람에게 보이지 않고, 저장되지 않습니다.</p> | ||
|<p>아래 링크를 클릭하여 해당 도움말(연습장)로 바로 이동할 수도 있습니다.</p> | ||
|<ul> | ||
|<li><a href="#paragraph">문단</a></li> | ||
|<li><a href="#heading">제목</a></li> | ||
|<li><a href="#blockquote">인용</a></li> | ||
|<li><a href="#emphasis">강조</a></li> | ||
|<li><a href="#strike">취소선</a></li> | ||
|<li><a href="#list">목록</a></li> | ||
|<li><a href="#tasklist">할일 목록</a></li> | ||
|<li><a href="#link">링크</a></li> | ||
|<li><a href="#table">표</a></li> | ||
|<li><a href="#code">코드 포맷</a></li> | ||
|<li><a href="#math">수식</a></li> | ||
|<li><a href="#uml">UML</a></li> | ||
|</ul> | ||
|</body> | ||
""".trimMargin().replace(System.lineSeparator(), "") | ||
} | ||
|
||
"마크다운을 <body> 태그를 제거한 HTML로 변환한다" { | ||
val markdownText = "2004년에 존 그루버(John Gruber)와 애런 스워츠(Aaron Swartz)가 만든 마크업 언어의 하나로 읽기 쉽고 쓰기 쉬운 텍스트 포맷입니다." | ||
val actual = markdownToEmbeddedHtml(markdownText) | ||
actual shouldNotContain "<body>" | ||
} | ||
}) |