From b6a8b559407daefde5ce01967190cccf97e2bb00 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Fri, 29 Nov 2019 22:11:55 +0100 Subject: [PATCH] =?utf8?q?=F0=9F=9A=A7=20Add=20new=20Sone=20handler=20to?= =?utf8?q?=20notifications?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../net/pterodactylus/sone/web/WebInterface.java | 36 ---------------------- .../sone/web/notification/NewSoneHandler.kt | 12 +++++++- .../sone/web/notification/NotificationHandler.kt | 7 +++-- .../kotlin/net/pterodactylus/sone/test/Matchers.kt | 19 ++++++++++++ .../sone/web/notification/NewSoneHandlerTest.kt | 35 +++++++++++++++++++-- .../web/notification/NotificationHandlerTest.kt | 17 ++++++++-- 6 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/main/java/net/pterodactylus/sone/web/WebInterface.java b/src/main/java/net/pterodactylus/sone/web/WebInterface.java index bcc7a11..58c9d19 100644 --- a/src/main/java/net/pterodactylus/sone/web/WebInterface.java +++ b/src/main/java/net/pterodactylus/sone/web/WebInterface.java @@ -157,9 +157,6 @@ public class WebInterface implements SessionProvider { private final MetricRegistry metricRegistry; private final Translation translation; - /** The “new Sone” notification. */ - private final ListNotification newSoneNotification; - /** The “new post” notification. */ private final ListNotification newPostNotification; @@ -233,9 +230,6 @@ public class WebInterface implements SessionProvider { templateContextFactory.addTemplateObject("formPassword", formPassword); /* create notifications. */ - Template newSoneNotificationTemplate = loaders.loadTemplate("/templates/notify/newSoneNotification.html"); - newSoneNotification = new ListNotification<>("new-sone-notification", "sones", newSoneNotificationTemplate, false); - Template newPostNotificationTemplate = loaders.loadTemplate("/templates/notify/newPostNotification.html"); newPostNotification = new ListNotification<>("new-post-notification", "posts", newPostNotificationTemplate, false); @@ -690,20 +684,6 @@ public class WebInterface implements SessionProvider { // /** - * Notifies the web interface that a new {@link Sone} was found. - * - * @param newSoneFoundEvent - * The event - */ - @Subscribe - public void newSoneFound(NewSoneFoundEvent newSoneFoundEvent) { - newSoneNotification.add(newSoneFoundEvent.getSone()); - if (!hasFirstStartNotification()) { - notificationManager.addNotification(newSoneNotification); - } - } - - /** * Notifies the web interface that a new {@link Post} was found. * * @param newPostFoundEvent @@ -755,17 +735,6 @@ public class WebInterface implements SessionProvider { } } - /** - * Notifies the web interface that a {@link Sone} was marked as known. - * - * @param markSoneKnownEvent - * The event - */ - @Subscribe - public void markSoneKnown(MarkSoneKnownEvent markSoneKnownEvent) { - newSoneNotification.remove(markSoneKnownEvent.getSone()); - } - @Subscribe public void markPostKnown(MarkPostKnownEvent markPostKnownEvent) { removePost(markPostKnownEvent.getPost()); @@ -777,11 +746,6 @@ public class WebInterface implements SessionProvider { } @Subscribe - public void soneRemoved(SoneRemovedEvent soneRemovedEvent) { - newSoneNotification.remove(soneRemovedEvent.getSone()); - } - - @Subscribe public void postRemoved(PostRemovedEvent postRemovedEvent) { removePost(postRemovedEvent.getPost()); } diff --git a/src/main/kotlin/net/pterodactylus/sone/web/notification/NewSoneHandler.kt b/src/main/kotlin/net/pterodactylus/sone/web/notification/NewSoneHandler.kt index 9ac6c28..83be6fd 100644 --- a/src/main/kotlin/net/pterodactylus/sone/web/notification/NewSoneHandler.kt +++ b/src/main/kotlin/net/pterodactylus/sone/web/notification/NewSoneHandler.kt @@ -29,7 +29,7 @@ import net.pterodactylus.util.template.* */ class NewSoneHandler(private val notificationManager: NotificationManager, template: Template) { - private val notification = ListNotification("new-sone-notification", "", template) + private val notification = ListNotification("new-sone-notification", "sones", template, dismissable = false) @Subscribe fun newSoneFound(newSoneFoundEvent: NewSoneFoundEvent) { @@ -39,6 +39,16 @@ class NewSoneHandler(private val notificationManager: NotificationManager, templ } } + @Subscribe + fun markedSoneKnown(markSoneKnownEvent: MarkSoneKnownEvent) { + notification.remove(markSoneKnownEvent.sone) + } + + @Subscribe + fun soneRemoved(soneRemovedEvent: SoneRemovedEvent) { + notification.remove(soneRemovedEvent.sone) + } + } private fun NotificationManager.hasNotification(id: String) = diff --git a/src/main/kotlin/net/pterodactylus/sone/web/notification/NotificationHandler.kt b/src/main/kotlin/net/pterodactylus/sone/web/notification/NotificationHandler.kt index 7f81f9a..37df1ac 100644 --- a/src/main/kotlin/net/pterodactylus/sone/web/notification/NotificationHandler.kt +++ b/src/main/kotlin/net/pterodactylus/sone/web/notification/NotificationHandler.kt @@ -29,8 +29,11 @@ import javax.inject.* class NotificationHandler @Inject constructor(private val eventBus: EventBus, private val loaders: Loaders, private val notificationManager: NotificationManager) { fun start() { - SoneLockedOnStartupHandler(notificationManager, loaders.loadTemplate("/templates/notify/soneLockedOnStartupNotification.html")) - .also(eventBus::register) + register { SoneLockedOnStartupHandler(it, loaders.loadTemplate("/templates/notify/soneLockedOnStartupNotification.html")) } + register { NewSoneHandler(it, loaders.loadTemplate("/templates/notify/newSoneNotification.html")) } } + private fun register(handler: (NotificationManager) -> Any) = + handler(notificationManager).also(eventBus::register) + } diff --git a/src/test/kotlin/net/pterodactylus/sone/test/Matchers.kt b/src/test/kotlin/net/pterodactylus/sone/test/Matchers.kt index 7fc9428..85ed9e7 100644 --- a/src/test/kotlin/net/pterodactylus/sone/test/Matchers.kt +++ b/src/test/kotlin/net/pterodactylus/sone/test/Matchers.kt @@ -5,8 +5,27 @@ import net.pterodactylus.sone.freenet.wot.* import net.pterodactylus.sone.utils.* import net.pterodactylus.util.web.* import org.hamcrest.* +import org.hamcrest.Matchers import org.hamcrest.Matchers.* +/** + * Returns a [hamcrest matcher][Matcher] constructed from the given predicate. + */ +fun matches(description: String? = null, predicate: (T) -> Boolean) = object : TypeSafeDiagnosingMatcher() { + + override fun matchesSafely(item: T, mismatchDescription: Description) = + predicate(item).onFalse { + mismatchDescription.appendValue(item).appendText(" did not match predicate") + } + + override fun describeTo(description: Description) { + description.appendText("matches predicate ").appendValue(predicate) + } + +}.let { matcher -> + description?.let { describedAs(description, matcher) } ?: matcher +} + fun hasHeader(name: String, value: String) = object : TypeSafeDiagnosingMatcher
() { override fun matchesSafely(item: Header, mismatchDescription: Description) = compare(item.name, { it.equals(name, ignoreCase = true) }) { mismatchDescription.appendText("name is ").appendValue(it) } diff --git a/src/test/kotlin/net/pterodactylus/sone/web/notification/NewSoneHandlerTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/notification/NewSoneHandlerTest.kt index 0f7b182..951de28 100644 --- a/src/test/kotlin/net/pterodactylus/sone/web/notification/NewSoneHandlerTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/web/notification/NewSoneHandlerTest.kt @@ -21,8 +21,9 @@ import com.google.common.eventbus.* import net.pterodactylus.sone.core.event.* import net.pterodactylus.sone.data.impl.* import net.pterodactylus.sone.notify.* +import net.pterodactylus.sone.test.* +import net.pterodactylus.sone.utils.* import net.pterodactylus.util.notify.* -import net.pterodactylus.util.template.* import org.hamcrest.MatcherAssert.* import org.hamcrest.Matchers.* import java.io.* @@ -33,7 +34,7 @@ class NewSoneHandlerTest { @Suppress("UnstableApiUsage") private val eventBus = EventBus() private val notificationManager = NotificationManager() - private val handler = NewSoneHandler(notificationManager, Template()) + private val handler = NewSoneHandler(notificationManager, "<% sones>".asTemplate()) init { eventBus.register(handler) @@ -54,6 +55,20 @@ class NewSoneHandlerTest { } @Test + fun `handler sets correct key for sones`() { + eventBus.post(NewSoneFoundEvent(sone)) + val notification = notificationManager.notifications.single() as ListNotification<*> + assertThat(notification.render(), equalTo(listOf(sone).toString())) + } + + @Test + fun `handler creates non-dismissable notification`() { + eventBus.post(NewSoneFoundEvent(sone)) + val notification = notificationManager.notifications.single() as ListNotification<*> + assertThat(notification, matches("is not dismissable") { !it.isDismissable }) + } + + @Test fun `handler does not add notification on new sone event if first-start notification is present`() { notificationManager.addNotification(object : AbstractNotification("first-start-notification") { override fun render(writer: Writer) = Unit @@ -63,6 +78,22 @@ class NewSoneHandlerTest { assertThat(notification.id, equalTo("first-start-notification")) } + @Test + fun `handler removes sone from notification if sone is marked as known`() { + eventBus.post(NewSoneFoundEvent(sone)) + val notification = notificationManager.notifications.single() as ListNotification<*> + eventBus.post(MarkSoneKnownEvent(sone)) + assertThat(notification.elements, emptyIterable()) + } + + @Test + fun `handler removes sone from notification if sone is removed`() { + eventBus.post(NewSoneFoundEvent(sone)) + val notification = notificationManager.notifications.single() as ListNotification<*> + eventBus.post(SoneRemovedEvent(sone)) + assertThat(notification.elements, emptyIterable()) + } + } private val sone = IdOnlySone("sone-id") diff --git a/src/test/kotlin/net/pterodactylus/sone/web/notification/NotificationHandlerTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/notification/NotificationHandlerTest.kt index d145038..a0ccb9d 100644 --- a/src/test/kotlin/net/pterodactylus/sone/web/notification/NotificationHandlerTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/web/notification/NotificationHandlerTest.kt @@ -18,7 +18,6 @@ package net.pterodactylus.sone.web.notification import com.google.common.eventbus.* -import com.google.inject.* import com.google.inject.Guice.* import net.pterodactylus.sone.main.* import net.pterodactylus.sone.test.* @@ -52,13 +51,25 @@ class NotificationHandlerTest { @Test fun `notification handler registers handler for sone-locked event`() { handler.start() - assertThat(eventBus.registeredObjects.any { it.javaClass == SoneLockedOnStartupHandler::class.java }, equalTo(true)) + assertThat(eventBus.registeredObjects, hasItem(matches { it.javaClass == SoneLockedOnStartupHandler::class.java })) } @Test fun `notification handler loads sone-locked notification template`() { handler.start() - assertThat(loaders.requestedTemplatePaths.any { it == "/templates/notify/soneLockedOnStartupNotification.html" }, equalTo(true)) + assertThat(loaders.requestedTemplatePaths, hasItem("/templates/notify/soneLockedOnStartupNotification.html")) + } + + @Test + fun `notification handler registers handler for new sone events`() { + handler.start() + assertThat(eventBus.registeredObjects, hasItem(matches { it.javaClass == NewSoneHandler::class.java })) + } + + @Test + fun `notification handler loads new sone notification template`() { + handler.start() + assertThat(loaders.requestedTemplatePaths, hasItem("/templates/notify/newSoneNotification.html")) } } -- 2.7.4