Refactoring of Notification system
This commit is contained in:
@@ -10,10 +10,11 @@ import fr.dcproject.component.citizen.database.CitizenCreator
|
||||
import fr.dcproject.component.citizen.database.CitizenI
|
||||
import fr.dcproject.component.follow.database.FollowArticleRepository
|
||||
import fr.dcproject.component.follow.database.FollowForView
|
||||
import fr.dcproject.component.notification.ArticleUpdateNotification
|
||||
import fr.dcproject.component.notification.NotificationConsumer
|
||||
import fr.dcproject.component.notification.NotificationEmailSender
|
||||
import fr.dcproject.component.notification.Publisher
|
||||
import fr.dcproject.component.notification.ArticleUpdateNotificationMessage
|
||||
import fr.dcproject.component.notification.NotificationPublisherAsync
|
||||
import fr.dcproject.component.notification.email.NotificationEmailConsumer
|
||||
import fr.dcproject.component.notification.email.NotificationEmailSender
|
||||
import fr.dcproject.component.notification.push.NotificationPushConsumer
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import io.lettuce.core.RedisClient
|
||||
@@ -88,9 +89,8 @@ class NotificationConsumerTest {
|
||||
}
|
||||
|
||||
/* Config consumer */
|
||||
val consumer = NotificationConsumer(
|
||||
val emailConsumer = NotificationEmailConsumer(
|
||||
rabbitFactory = rabbitFactory,
|
||||
redisClient = redisClient,
|
||||
followArticleRepo = followArticleRepo,
|
||||
followConstitutionRepo = mockk(), // TODO test followConstitution
|
||||
followCitizenRepo = mockk(), // TODO test followCitizen
|
||||
@@ -98,12 +98,21 @@ class NotificationConsumerTest {
|
||||
exchangeName = "notification",
|
||||
).apply { start() }
|
||||
|
||||
val pushConsumer = NotificationPushConsumer(
|
||||
rabbitFactory = rabbitFactory,
|
||||
followArticleRepo = followArticleRepo,
|
||||
followConstitutionRepo = mockk(), // TODO test followConstitution
|
||||
followCitizenRepo = mockk(), // TODO test followCitizen
|
||||
redisClient = redisClient,
|
||||
exchangeName = "notification",
|
||||
).apply { start() }
|
||||
|
||||
/* Push message */
|
||||
Publisher(
|
||||
NotificationPublisherAsync(
|
||||
factory = rabbitFactory,
|
||||
exchangeName = "notification",
|
||||
).publish(
|
||||
ArticleUpdateNotification(
|
||||
).publishAsync(
|
||||
ArticleUpdateNotificationMessage(
|
||||
ArticleForView(
|
||||
title = "MyTitle",
|
||||
content = "myContent",
|
||||
@@ -122,6 +131,7 @@ class NotificationConsumerTest {
|
||||
verify(timeout = 2000) { emailSender.sendEmail(any()) }
|
||||
verify(timeout = 2000) { asyncCommand.zadd(any<String>(), any<Double>(), any<String>()) }
|
||||
|
||||
consumer.close()
|
||||
emailConsumer.close()
|
||||
pushConsumer.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ import fr.dcproject.component.article.database.ArticleForView
|
||||
import fr.dcproject.component.auth.database.UserCreator
|
||||
import fr.dcproject.component.citizen.database.CitizenCreator
|
||||
import fr.dcproject.component.citizen.database.CitizenI
|
||||
import fr.dcproject.component.notification.ArticleUpdateNotification
|
||||
import fr.dcproject.component.notification.Notification
|
||||
import fr.dcproject.component.notification.NotificationsPush
|
||||
import fr.dcproject.component.notification.ArticleUpdateNotificationMessage
|
||||
import fr.dcproject.component.notification.NotificationMessage
|
||||
import fr.dcproject.component.notification.push.NotificationPushListener
|
||||
import io.lettuce.core.RedisClient
|
||||
import io.mockk.every
|
||||
import io.mockk.spyk
|
||||
@@ -68,14 +68,14 @@ internal class NotificationsPushTest {
|
||||
title = "Super Title",
|
||||
)
|
||||
/* Init two notification, one called before subscription, and the other after */
|
||||
val notifBeforeSubscribe = ArticleUpdateNotification(article)
|
||||
val notifBeforeSubscribe = ArticleUpdateNotificationMessage(article)
|
||||
runBlocking {
|
||||
delay(100)
|
||||
}
|
||||
val notifAfterSubscribe = ArticleUpdateNotification(article)
|
||||
val notifAfterSubscribe = ArticleUpdateNotificationMessage(article)
|
||||
|
||||
/* init event for emulate incoming message from websocket */
|
||||
val event = MutableSharedFlow<Notification>()
|
||||
val event = MutableSharedFlow<NotificationMessage>()
|
||||
val incomingFlow = event.asSharedFlow()
|
||||
|
||||
spyk(object { var counter = 0 }).run { /* Counter for count the callback of notification */
|
||||
@@ -90,7 +90,7 @@ internal class NotificationsPushTest {
|
||||
}
|
||||
|
||||
/* Init NotificationPush system, and set assertion in callback */
|
||||
val notificationPush = NotificationsPush.Builder(redisClient).build(citizen, incomingFlow) {
|
||||
val notificationPush = NotificationPushListener.Builder(redisClient).build(citizen, incomingFlow) {
|
||||
counter++
|
||||
if (counter == 1) it.id `should be equal to` notifBeforeSubscribe.id
|
||||
else it.id `should be equal to` notifAfterSubscribe.id
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
package integration
|
||||
|
||||
import fr.dcproject.common.utils.toUUID
|
||||
import fr.dcproject.component.article.database.ArticleForView
|
||||
import fr.dcproject.component.auth.database.UserCreator
|
||||
import fr.dcproject.component.citizen.database.CitizenCreator
|
||||
import fr.dcproject.component.citizen.database.CitizenI.Name
|
||||
import fr.dcproject.component.notification.ArticleUpdateNotification
|
||||
import fr.dcproject.component.notification.Notification
|
||||
import fr.dcproject.component.notification.Publisher
|
||||
import fr.dcproject.component.notification.ArticleUpdateNotificationMessage
|
||||
import fr.dcproject.component.notification.NotificationMessage
|
||||
import integration.steps.given.`Given I have article update notification`
|
||||
import integration.steps.given.`Given I have article`
|
||||
import integration.steps.given.`Given I have citizen`
|
||||
import integration.steps.given.`Given I have follow on article`
|
||||
import integration.steps.given.`authenticated in url as`
|
||||
import io.ktor.http.cio.websocket.Frame
|
||||
import io.ktor.http.cio.websocket.readText
|
||||
import kotlinx.coroutines.launch
|
||||
import org.junit.jupiter.api.Tag
|
||||
import org.junit.jupiter.api.Tags
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import org.koin.test.get
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@@ -31,26 +25,7 @@ class `Notification routes` : BaseTest() {
|
||||
`Given I have citizen`("John", "Doe", id = "1a34191a-9cde-45ba-8ac1-230138a102d3")
|
||||
`Given I have article`(id = "a06cbfb7-3094-4d64-aaa1-7486c0c292f4", createdBy = Name(firstName = "John", lastName = "Doe"))
|
||||
`Given I have follow on article`("John", "Doe", article = "a06cbfb7-3094-4d64-aaa1-7486c0c292f4")
|
||||
val notification = ArticleUpdateNotification(
|
||||
ArticleForView(
|
||||
id = "a06cbfb7-3094-4d64-aaa1-7486c0c292f4".toUUID(),
|
||||
title = "MyTitle",
|
||||
content = "myContent",
|
||||
description = "myDescription",
|
||||
createdBy = CitizenCreator(
|
||||
id = "1a34191a-9cde-45ba-8ac1-230138a102d3".toUUID(),
|
||||
name = Name(firstName = "John", lastName = "Doe"),
|
||||
email = "john-doe@plop.com",
|
||||
user = UserCreator(username = "john-doe"),
|
||||
)
|
||||
)
|
||||
)
|
||||
val publisher = get<Publisher>()
|
||||
launch {
|
||||
publisher
|
||||
.publish(notification)
|
||||
.await()
|
||||
}
|
||||
`Given I have article update notification`("a06cbfb7-3094-4d64-aaa1-7486c0c292f4")
|
||||
|
||||
Thread.sleep(1000)
|
||||
|
||||
@@ -62,7 +37,7 @@ class `Notification routes` : BaseTest() {
|
||||
) { incoming, outgoing ->
|
||||
incoming.receive().let {
|
||||
when (it) {
|
||||
is Frame.Text -> Notification.fromString<ArticleUpdateNotification>(it.readText()).let { notif ->
|
||||
is Frame.Text -> NotificationMessage.fromString<ArticleUpdateNotificationMessage>(it.readText()).let { notif ->
|
||||
assertEquals(
|
||||
"a06cbfb7-3094-4d64-aaa1-7486c0c292f4",
|
||||
notif.target.id.toString()
|
||||
|
||||
40
src/test/kotlin/integration/steps/given/Notification.kt
Normal file
40
src/test/kotlin/integration/steps/given/Notification.kt
Normal file
@@ -0,0 +1,40 @@
|
||||
package integration.steps.given
|
||||
|
||||
import fr.dcproject.common.utils.toUUID
|
||||
import fr.dcproject.component.article.database.ArticleForView
|
||||
import fr.dcproject.component.auth.database.UserCreator
|
||||
import fr.dcproject.component.citizen.database.CitizenCreator
|
||||
import fr.dcproject.component.citizen.database.CitizenI
|
||||
import fr.dcproject.component.notification.ArticleUpdateNotificationMessage
|
||||
import fr.dcproject.component.notification.NotificationPublisherAsync
|
||||
import io.ktor.server.testing.TestApplicationEngine
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.mp.KoinPlatformTools
|
||||
import java.util.UUID
|
||||
|
||||
fun TestApplicationEngine.`Given I have article update notification`(
|
||||
id: String = UUID.randomUUID().toString()
|
||||
) {
|
||||
val notification = ArticleUpdateNotificationMessage(
|
||||
ArticleForView(
|
||||
id = id.toUUID(),
|
||||
title = "MyTitle",
|
||||
content = "myContent",
|
||||
description = "myDescription",
|
||||
createdBy = CitizenCreator(
|
||||
id = "1a34191a-9cde-45ba-8ac1-230138a102d3".toUUID(),
|
||||
name = CitizenI.Name(firstName = "John", lastName = "Doe"),
|
||||
email = "john-doe@plop.com",
|
||||
user = UserCreator(username = "john-doe"),
|
||||
)
|
||||
)
|
||||
)
|
||||
launch {
|
||||
KoinPlatformTools
|
||||
.defaultContext()
|
||||
.get()
|
||||
.get<NotificationPublisherAsync>()
|
||||
.publishAsync(notification)
|
||||
.await()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user