Refactoring of Notification system

This commit is contained in:
2021-04-18 01:57:04 +02:00
parent 1c33c026f0
commit fee5e5784b
23 changed files with 497 additions and 286 deletions

View File

@@ -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()
}
}

View File

@@ -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

View File

@@ -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()

View 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()
}
}