Skip to content

Commit db7e821

Browse files
committed
Part3: extensions
1 parent c3bfaa5 commit db7e821

File tree

6 files changed

+72
-28
lines changed

6 files changed

+72
-28
lines changed

build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ dependencies {
3434

3535
implementation("org.springframework.boot:spring-boot-starter-data-jdbc")
3636
runtimeOnly("com.h2database:h2")
37+
38+
implementation("org.jetbrains:markdown:0.1.45")
3739
}
3840

3941
tasks.withType<Test> {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.example.kotlin.chat
2+
3+
import com.example.kotlin.chat.repository.ContentType
4+
import com.example.kotlin.chat.repository.Message
5+
import com.example.kotlin.chat.service.MessageVM
6+
import com.example.kotlin.chat.service.UserVM
7+
import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor
8+
import org.intellij.markdown.html.HtmlGenerator
9+
import org.intellij.markdown.parser.MarkdownParser
10+
import java.net.URL
11+
12+
fun MessageVM.asDomainObject(contentType: ContentType = ContentType.MARKDOWN): Message = Message(
13+
content,
14+
contentType,
15+
sent,
16+
user.name,
17+
user.avatarImageLink.toString(),
18+
id
19+
)
20+
21+
fun Message.asViewModel(): MessageVM = MessageVM(
22+
contentType.render(content),
23+
UserVM(username, URL(userAvatarImageLink)),
24+
sent,
25+
id
26+
)
27+
28+
fun List<Message>.mapToViewModel(): List<MessageVM> = map { it.asViewModel() }
29+
30+
fun ContentType.render(content: String): String = when (this) {
31+
ContentType.PLAIN -> content
32+
ContentType.MARKDOWN -> {
33+
val flavour = CommonMarkFlavourDescriptor()
34+
HtmlGenerator(content, MarkdownParser(flavour).buildMarkdownTreeFromString(content), flavour).generateHtml()
35+
}
36+
}

src/main/kotlin/com/example/kotlin/chat/repository/DomainModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ data class Message(
1414
@Id var id: String? = null)
1515

1616
enum class ContentType {
17-
PLAIN
17+
PLAIN, MARKDOWN
1818
}
Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
11
package com.example.kotlin.chat.service
22

3-
import com.example.kotlin.chat.repository.ContentType
4-
import com.example.kotlin.chat.repository.Message
3+
import com.example.kotlin.chat.asDomainObject
4+
import com.example.kotlin.chat.mapToViewModel
55
import com.example.kotlin.chat.repository.MessageRepository
66
import org.springframework.context.annotation.Primary
77
import org.springframework.stereotype.Service
8-
import java.net.URL
98

109
@Service
1110
@Primary
1211
class PersistentMessageService(val messageRepository: MessageRepository) : MessageService {
1312

1413
override fun latest(): List<MessageVM> =
15-
messageRepository.findLatest()
16-
.map { with(it) { MessageVM(content, UserVM(username, URL(userAvatarImageLink)), sent, id) } }
14+
messageRepository.findLatest()
15+
.mapToViewModel()
1716

1817
override fun after(messageId: String): List<MessageVM> =
19-
messageRepository.findLatest(messageId)
20-
.map { with(it) { MessageVM(content, UserVM(username, URL(userAvatarImageLink)), sent, id) } }
18+
messageRepository.findLatest(messageId)
19+
.mapToViewModel()
2120

2221
override fun post(message: MessageVM) {
23-
messageRepository.save(
24-
with(message) { Message(content, ContentType.PLAIN, sent, user.name, user.avatarImageLink.toString()) }
25-
)
22+
messageRepository.save(message.asDomainObject())
2623
}
2724
}

src/test/kotlin/com/example/kotlin/chat/ChatKotlinApplicationTests.kt

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ class ChatKotlinApplicationTests {
5656
),
5757
Message(
5858
"**testMessage2**",
59-
ContentType.PLAIN,
59+
ContentType.MARKDOWN,
6060
secondBeforeNow,
6161
"test1",
6262
"http://test.com"
6363
),
6464
Message(
6565
"`testMessage3`",
66-
ContentType.PLAIN,
66+
ContentType.MARKDOWN,
6767
now,
6868
"test2",
6969
"http://test.com"
@@ -100,15 +100,15 @@ class ChatKotlinApplicationTests {
100100
)
101101
}
102102

103-
assertThat(messages?.map { with(it) { copy(id = null, sent = sent.truncatedTo(MILLIS)) } })
103+
assertThat(messages?.map { it.prepareForTesting() })
104104
.containsSubsequence(
105105
MessageVM(
106-
"**testMessage2**",
106+
"<body><p><strong>testMessage2</strong></p></body>",
107107
UserVM("test1", URL("http://test.com")),
108108
now.minusSeconds(1).truncatedTo(MILLIS)
109109
),
110110
MessageVM(
111-
"`testMessage3`",
111+
"<body><p><code>testMessage3</code></p></body>",
112112
UserVM("test2", URL("http://test.com")),
113113
now.truncatedTo(MILLIS)
114114
)
@@ -127,17 +127,17 @@ class ChatKotlinApplicationTests {
127127
)
128128
)
129129

130-
messageRepository.findAll()
131-
.first { it.content.contains("HelloWorld") }
132-
.apply {
133-
assertThat(this.copy(id = null, sent = sent.truncatedTo(MILLIS)))
134-
.isEqualTo(Message(
135-
"`HelloWorld`",
136-
ContentType.PLAIN,
137-
now.plusSeconds(1).truncatedTo(MILLIS),
138-
"test",
139-
"http://test.com"
140-
))
141-
}
130+
messageRepository.findAll()
131+
.first { it.content.contains("HelloWorld") }
132+
.apply {
133+
assertThat(this.prepareForTesting())
134+
.isEqualTo(Message(
135+
"`HelloWorld`",
136+
ContentType.MARKDOWN,
137+
now.plusSeconds(1).truncatedTo(MILLIS),
138+
"test",
139+
"http://test.com"
140+
))
141+
}
142142
}
143143
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.example.kotlin.chat
2+
3+
import com.example.kotlin.chat.repository.Message
4+
import com.example.kotlin.chat.service.MessageVM
5+
import java.time.temporal.ChronoUnit.MILLIS
6+
7+
fun MessageVM.prepareForTesting() = copy(id = null, sent = sent.truncatedTo(MILLIS))
8+
9+
fun Message.prepareForTesting() = copy(id = null, sent = sent.truncatedTo(MILLIS))

0 commit comments

Comments
 (0)