✨ Add handler for all notifications
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 29 Nov 2019 15:57:41 +0000 (16:57 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Fri, 29 Nov 2019 17:27:13 +0000 (18:27 +0100)
src/main/kotlin/net/pterodactylus/sone/web/notification/NotificationHandler.kt [new file with mode: 0644]
src/main/resources/i18n/sone.de.properties
src/main/resources/i18n/sone.en.properties
src/main/resources/i18n/sone.es.properties
src/main/resources/i18n/sone.fr.properties
src/main/resources/i18n/sone.ja.properties
src/main/resources/i18n/sone.no.properties
src/main/resources/i18n/sone.pl.properties
src/main/resources/i18n/sone.ru.properties
src/main/resources/templates/notify/soneLockedOnStartupNotification.html [new file with mode: 0644]
src/test/kotlin/net/pterodactylus/sone/web/notification/NotificationHandlerTest.kt [new file with mode: 0644]

diff --git a/src/main/kotlin/net/pterodactylus/sone/web/notification/NotificationHandler.kt b/src/main/kotlin/net/pterodactylus/sone/web/notification/NotificationHandler.kt
new file mode 100644 (file)
index 0000000..7f81f9a
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * Sone - NotificationHandler.kt - Copyright © 2019 David ‘Bombe’ Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.pterodactylus.sone.web.notification
+
+import com.google.common.eventbus.*
+import net.pterodactylus.sone.main.*
+import net.pterodactylus.util.notify.*
+import javax.inject.*
+
+/**
+ * Handler for notifications that can create notifications and register them with an event bus.
+ */
+@Suppress("UnstableApiUsage")
+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)
+       }
+
+}
index a2ff8b1..6c91fcd 100644 (file)
@@ -461,3 +461,4 @@ Notification.Mention.Text=Sie wurden in diesen Nachrichten erwähnt:
 Notification.SoneIsInserting.Text=Ihre Sone sone://{0} wird jetzt hoch geladen.
 Notification.SoneIsInserted.Text=Ihre Sone sone://{0} wurde in {1,number} {1,choice,0#Sekunden|1#Sekunde|1<Sekunden} hoch geladen.
 Notification.SoneInsertAborted.Text=Ihre Sone sone://{0} konnte nicht hoch geladen werden.
+Notification.SoneLockedOnStartup.Text=Einige Sones wurden beim Starten gesperrt, weil sie keine Inhalte enthielten. Versionen vor v81 hatten einen Fehler, der Sones ohne Inhalte zur Folge hatte. Um zu verhindern, dass solchermaßen defekte Sones hoch geladen werden, wurden sie automatisch gesperrt. Bitte überprüfen Sie Ihre Sones, benutzen Sie den Sonerettungsmodus und entsperren Sie die Sones manuell, wenn Sie mit den Inhalten Ihrer Sones zufrieden sind. Die gesperrten Sones sind:
index c599f84..1c0f2cb 100644 (file)
@@ -463,3 +463,4 @@ Notification.Mention.Text=You have been mentioned in the following posts:
 Notification.SoneIsInserting.Text=Your Sone sone://{0} is now being inserted.
 Notification.SoneIsInserted.Text=Your Sone sone://{0} has been inserted in {1,number} {1,choice,0#seconds|1#second|1<seconds}.
 Notification.SoneInsertAborted.Text=Your Sone sone://{0} could not be inserted.
+Notification.SoneLockedOnStartup.Text=Some Sones were locked on startup because they don’t contain anything. Versions prior to v81 had a bug that resulted in empty Sones. To prevent buggy Sones from being inserted they have been automatically locked. Please check your Sones, use the Rescue Mode if necessary, and unlock your Sones once you are satisfied with the results. Locked Sones are:
index 3a67a59..42a62d5 100644 (file)
@@ -461,4 +461,5 @@ Notification.Mention.Text=Has sido mencionado en las siguientes publicaciones:
 Notification.SoneIsInserting.Text=Tu Sone sone://{0} está siendo insertado.
 Notification.SoneIsInserted.Text=Tu Sone sone://{0} ha sido insertado en {1,number} {1,choice,0#segundos|1#segundo|1<segundos}.
 Notification.SoneInsertAborted.Text=Tu Sone sone://{0} no pudo ser insertado.
-# 55-61, 324–328, 360
+Notification.SoneLockedOnStartup.Text=Some Sones were locked on startup because they don’t contain anything. Versions prior to v81 had a bug that resulted in empty Sones. To prevent buggy Sones from being inserted they have been automatically locked. Please check your Sones, use the Rescue Mode if necessary, and unlock your Sones once you are satisfied with the results. Locked Sones are:
+# 55-61, 324–328, 360, 464
index a0bc86a..fc3717c 100644 (file)
@@ -461,4 +461,5 @@ Notification.Mention.Text=Vous avez été mentionné dans les messages suivants:
 Notification.SoneIsInserting.Text=Votre Sone sone://{0} va maintenant être inséré.
 Notification.SoneIsInserted.Text=votre Sone sone://{0} a été inséré dans {1,number} {1,choice,0#seconds|1#second|1<seconds}.
 Notification.SoneInsertAborted.Text=Votre Sone sone://{0} ne peut pas être inséré.
-# 55-61, 324–328, 360
+Notification.SoneLockedOnStartup.Text=Some Sones were locked on startup because they don’t contain anything. Versions prior to v81 had a bug that resulted in empty Sones. To prevent buggy Sones from being inserted they have been automatically locked. Please check your Sones, use the Rescue Mode if necessary, and unlock your Sones once you are satisfied with the results. Locked Sones are:
+# 55-61, 324–328, 360, 464
index f9b0483..e2509a7 100644 (file)
@@ -461,4 +461,5 @@ Notification.Mention.Text=次の投稿でメンションされています:
 Notification.SoneIsInserting.Text=あなたのSone sone://{0}は現在インサート中です。
 Notification.SoneIsInserted.Text=あなたのSone sone://{0}は{1,number}{1,choice,0#秒|1#秒|1<秒}でインサートされました。
 Notification.SoneInsertAborted.Text=あなたのSone sone://{0}のインサートに失敗しました。
-# 55-51, 67, 103, 324–328, 360, 455
+Notification.SoneLockedOnStartup.Text=Some Sones were locked on startup because they don’t contain anything. Versions prior to v81 had a bug that resulted in empty Sones. To prevent buggy Sones from being inserted they have been automatically locked. Please check your Sones, use the Rescue Mode if necessary, and unlock your Sones once you are satisfied with the results. Locked Sones are:
+# 55-51, 67, 103, 324–328, 360, 455, 464
index 02bed70..dfb49bb 100644 (file)
@@ -461,4 +461,5 @@ Notification.Mention.Text=Du har blitt nevnt i følgende innlegg:
 Notification.SoneIsInserting.Text=Your Sone sone://{0} is now being inserted.
 Notification.SoneIsInserted.Text=Your Sone sone://{0} has been inserted in {1,number} {1,choice,0#seconds|1#second|1<seconds}.
 Notification.SoneInsertAborted.Text=Your Sone sone://{0} could not be inserted.
-# 55-61, 67, 103, 123-124, 305-307, 309-311, 324–328, 360, 455, 461-463
+Notification.SoneLockedOnStartup.Text=Some Sones were locked on startup because they don’t contain anything. Versions prior to v81 had a bug that resulted in empty Sones. To prevent buggy Sones from being inserted they have been automatically locked. Please check your Sones, use the Rescue Mode if necessary, and unlock your Sones once you are satisfied with the results. Locked Sones are:
+# 55-61, 67, 103, 123-124, 305-307, 309-311, 324–328, 360, 455, 461-464
index d1b9f5f..0ce5740 100644 (file)
@@ -461,4 +461,5 @@ Notification.Mention.Text=Zostałeś oznaczony w następujących postach:
 Notification.SoneIsInserting.Text=Twoje Sone sone://{0} jest w tej chili wysyłane.
 Notification.SoneIsInserted.Text=Twoje sone://{0} zostało wysłane w {1,number} {1,choice,0#seconds|1#second|1<seconds}.
 Notification.SoneInsertAborted.Text=Twoje Sone sone://{0} nie mogło zostać wysłane.
-# 55-61, 324–328, 360, 455
+Notification.SoneLockedOnStartup.Text=Some Sones were locked on startup because they don’t contain anything. Versions prior to v81 had a bug that resulted in empty Sones. To prevent buggy Sones from being inserted they have been automatically locked. Please check your Sones, use the Rescue Mode if necessary, and unlock your Sones once you are satisfied with the results. Locked Sones are:
+# 55-61, 324–328, 360, 455, 464
index e409f02..8604ef6 100644 (file)
@@ -461,4 +461,5 @@ Notification.Mention.Text=Вас упомянули в следующих соо
 Notification.SoneIsInserting.Text=Your Sone sone://{0} is now being inserted.
 Notification.SoneIsInserted.Text=Your Sone sone://{0} has been inserted in {1,number} {1,choice,0#seconds|1#second|1<seconds}.
 Notification.SoneInsertAborted.Text=Your Sone sone://{0} could not be inserted.
-# 55-61, 67, 103, 123-124, 305-307, 309-311, 324–328, 360, 455, 461-463
+Notification.SoneLockedOnStartup.Text=Some Sones were locked on startup because they don’t contain anything. Versions prior to v81 had a bug that resulted in empty Sones. To prevent buggy Sones from being inserted they have been automatically locked. Please check your Sones, use the Rescue Mode if necessary, and unlock your Sones once you are satisfied with the results. Locked Sones are:
+# 55-61, 67, 103, 123-124, 305-307, 309-311, 324–328, 360, 455, 461-464
diff --git a/src/main/resources/templates/notify/soneLockedOnStartupNotification.html b/src/main/resources/templates/notify/soneLockedOnStartupNotification.html
new file mode 100644 (file)
index 0000000..8cd4e56
--- /dev/null
@@ -0,0 +1,6 @@
+<div class="text">
+       <%= Notification.SoneLockedOnStartup.Text|l10n|html>
+       <%foreach sones sone>
+               <a href="viewSone.html?sone=<% sone.id|html>" title="<% sone.requestUri|html>"><% sone.niceName|html></a><%notlast>,<%/notlast><%last>.<%/last>
+       <%/foreach>
+</div>
diff --git a/src/test/kotlin/net/pterodactylus/sone/web/notification/NotificationHandlerTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/notification/NotificationHandlerTest.kt
new file mode 100644 (file)
index 0000000..d145038
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * Sone - NotificationHandlerTest.kt - Copyright © 2019 David ‘Bombe’ Roden
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+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.*
+import net.pterodactylus.util.notify.*
+import net.pterodactylus.util.template.*
+import net.pterodactylus.util.web.*
+import org.hamcrest.MatcherAssert.*
+import org.hamcrest.Matchers.*
+import kotlin.test.*
+
+/**
+ * Unit test for [NotificationHandler].
+ */
+class NotificationHandlerTest {
+
+       private val eventBus = TestEventBus()
+       private val loaders = TestLoaders()
+       private val notificationManager = NotificationManager()
+       private val handler = NotificationHandler(eventBus, loaders, notificationManager)
+
+       @Test
+       fun `notification handler can be created by guice`() {
+               val injector = createInjector(
+                               EventBus::class.isProvidedBy(eventBus),
+                               NotificationManager::class.isProvidedBy(notificationManager),
+                               Loaders::class.isProvidedBy(loaders)
+               )
+               assertThat(injector.getInstance<NotificationHandler>(), notNullValue())
+       }
+
+       @Test
+       fun `notification handler registers handler for sone-locked event`() {
+               handler.start()
+               assertThat(eventBus.registeredObjects.any { it.javaClass == SoneLockedOnStartupHandler::class.java }, equalTo(true))
+       }
+
+       @Test
+       fun `notification handler loads sone-locked notification template`() {
+               handler.start()
+               assertThat(loaders.requestedTemplatePaths.any { it == "/templates/notify/soneLockedOnStartupNotification.html" }, equalTo(true))
+       }
+
+}
+
+@Suppress("UnstableApiUsage")
+private class TestEventBus : EventBus() {
+       private val _registeredObjects = mutableListOf<Any>()
+       val registeredObjects: List<Any>
+               get() = _registeredObjects
+
+       override fun register(`object`: Any) {
+               super.register(`object`)
+               _registeredObjects += `object`
+       }
+
+}
+
+private class TestLoaders : Loaders {
+       val requestedTemplatePaths = mutableListOf<String>()
+
+       override fun loadTemplate(path: String) =
+                       Template().also { requestedTemplatePaths += path }
+
+       override fun <REQ : Request> loadStaticPage(basePath: String, prefix: String, mimeType: String) = object : Page<REQ> {
+
+               override fun getPath() = ""
+               override fun isPrefixPage() = false
+               override fun handleRequest(request: REQ, response: Response) = response
+
+       }
+
+       override fun getTemplateProvider() = TemplateProvider { _, _ -> Template() }
+
+}