From e194b91c7053152c9c5503f8882e1ddefcd23bdc Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Sun, 10 Sep 2017 11:19:45 +0200 Subject: [PATCH] Add test for get notifications ajax page --- .../sone/web/ajax/GetNotificationsAjaxPageTest.kt | 118 +++++++++++++++++++++ .../sone/web/ajax/GetStatusAjaxPageTest.kt | 6 +- .../pterodactylus/sone/web/ajax/JsonPageTest.kt | 5 + 3 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 src/test/kotlin/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPageTest.kt diff --git a/src/test/kotlin/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPageTest.kt new file mode 100644 index 0000000..d625fac --- /dev/null +++ b/src/test/kotlin/net/pterodactylus/sone/web/ajax/GetNotificationsAjaxPageTest.kt @@ -0,0 +1,118 @@ +package net.pterodactylus.sone.web.ajax + +import net.pterodactylus.sone.main.SonePlugin +import net.pterodactylus.sone.test.argumentCaptor +import net.pterodactylus.sone.test.get +import net.pterodactylus.sone.test.mock +import net.pterodactylus.sone.test.whenever +import net.pterodactylus.util.notify.Notification +import net.pterodactylus.util.notify.TemplateNotification +import net.pterodactylus.util.template.TemplateContext +import net.pterodactylus.util.template.TemplateContextFactory +import net.pterodactylus.util.version.Version +import org.hamcrest.MatcherAssert.assertThat +import org.hamcrest.Matchers.containsInAnyOrder +import org.hamcrest.Matchers.empty +import org.hamcrest.Matchers.equalTo +import org.junit.Test +import org.mockito.ArgumentMatchers.any +import org.mockito.Mockito.verify +import java.io.Writer + +/** + * Unit test for [GetNotificationsAjaxPage]. + */ +class GetNotificationsAjaxPageTest : JsonPageTest("getNotifications.ajax", requiresLogin = false, needsFormPassword = false, pageSupplier = ::GetNotificationsAjaxPage) { + + private val notifications = listOf( + createNotification("n1", 2000, "t1", 5000, true), + createNotification("n2", 1000, "t2", 6000, false), + createNotification("n3", 3000, "t3", 7000, true) + ) + + private fun createNotification(id: String, createdTime: Long, text: String, lastUpdatedTime: Long, dismissable: Boolean): Notification { + return mock().apply { + whenever(this.id).thenReturn(id) + whenever(this.createdTime).thenReturn(createdTime) + whenever(this.lastUpdatedTime).thenReturn(lastUpdatedTime) + whenever(this.isDismissable).thenReturn(dismissable) + whenever(render(any())).then { it.get(0).write(text) } + } + } + + @Test + fun `notification hash is calculated correctly`() { + notifications.forEach { addNotification(it) } + assertThat(json.isSuccess, equalTo(true)) + assertThat(json["notificationHash"].asInt(), equalTo(listOf(1, 0, 2).map(notifications::get).hashCode())) + } + + @Test + fun `options are included correctly`() { + assertThat(json.isSuccess, equalTo(true)) + assertThat(json["options"]["ShowNotification/NewSones"].asBoolean(), equalTo(true)) + assertThat(json["options"]["ShowNotification/NewPosts"].asBoolean(), equalTo(true)) + assertThat(json["options"]["ShowNotification/NewReplies"].asBoolean(), equalTo(true)) + } + + @Test + fun `options are included correctly when all false`() { + currentSone.options.isShowNewSoneNotifications = false + currentSone.options.isShowNewPostNotifications = false + currentSone.options.isShowNewReplyNotifications = false + assertThat(json.isSuccess, equalTo(true)) + assertThat(json["options"]["ShowNotification/NewSones"].asBoolean(), equalTo(false)) + assertThat(json["options"]["ShowNotification/NewPosts"].asBoolean(), equalTo(false)) + assertThat(json["options"]["ShowNotification/NewReplies"].asBoolean(), equalTo(false)) + } + + @Test + fun `options are not included if user is not logged in`() { + unsetCurrentSone() + assertThat(json.isSuccess, equalTo(true)) + assertThat(json["options"].toList(), empty()) + } + + @Test + fun `notifications are rendered correctly`() { + notifications.forEach { addNotification(it) } + assertThat(json.isSuccess, equalTo(true)) + assertThat(json["notifications"].toList().map { node -> listOf("id", "text", "createdTime", "lastUpdatedTime", "dismissable").map { it to node.get(it).asText() }.toMap() }, containsInAnyOrder( + mapOf("id" to "n1", "createdTime" to "2000", "lastUpdatedTime" to "5000", "dismissable" to "true", "text" to "t1"), + mapOf("id" to "n2", "createdTime" to "1000", "lastUpdatedTime" to "6000", "dismissable" to "false", "text" to "t2"), + mapOf("id" to "n3", "createdTime" to "3000", "lastUpdatedTime" to "7000", "dismissable" to "true", "text" to "t3") + )) + } + + @Test + fun `template notifications are rendered correctly`() { + whenever(webInterface.templateContextFactory).thenReturn(TemplateContextFactory()) + whenever(updateChecker.hasLatestVersion()).thenReturn(true) + whenever(updateChecker.latestEdition).thenReturn(999) + whenever(updateChecker.latestVersion).thenReturn(Version(0, 1, 2)) + whenever(updateChecker.latestVersionDate).thenReturn(998) + val templateNotification = mock().apply { + whenever(id).thenReturn("n4") + whenever(createdTime).thenReturn(4000) + whenever(templateContext).thenReturn(TemplateContext()) + whenever(render(any(), any())).then { it.get(1).write("t4") } + } + notifications.forEach { addNotification(it) } + addNotification(templateNotification) + assertThat(json.isSuccess, equalTo(true)) + assertThat(json["notifications"].last()["text"].asText(), equalTo("t4")) + val templateContext = argumentCaptor() + verify(templateNotification).render(templateContext.capture(), any()) + assertThat(templateContext.value["core"], equalTo(core)) + assertThat(templateContext.value["currentSone"], equalTo(currentSone)) + assertThat(templateContext.value["localSones"], equalTo(core.localSones)) + assertThat(templateContext.value["request"], equalTo(freenetRequest)) + assertThat(templateContext.value["currentVersion"], equalTo(SonePlugin.getPluginVersion())) + assertThat(templateContext.value["hasLatestVersion"], equalTo(true)) + assertThat(templateContext.value["latestEdition"], equalTo(999L)) + assertThat(templateContext.value["latestVersion"], equalTo(Version(0, 1, 2))) + assertThat(templateContext.value["latestVersionTime"], equalTo(998L)) + assertThat(templateContext.value["notification"], equalTo(templateNotification)) + } + +} diff --git a/src/test/kotlin/net/pterodactylus/sone/web/ajax/GetStatusAjaxPageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/ajax/GetStatusAjaxPageTest.kt index e01764d..0d8cb54 100644 --- a/src/test/kotlin/net/pterodactylus/sone/web/ajax/GetStatusAjaxPageTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/web/ajax/GetStatusAjaxPageTest.kt @@ -54,9 +54,9 @@ class GetStatusAjaxPageTest: JsonPageTest("getStatus.ajax", requiresLogin = fals @Test fun `page returns options for sone if sone is logged in`() { assertThat(json.get("options").toMap(), allOf( - hasEntry("ShowNotification/NewSones", "false"), - hasEntry("ShowNotification/NewPosts", "false"), - hasEntry("ShowNotification/NewReplies", "false") + hasEntry("ShowNotification/NewSones", "true"), + hasEntry("ShowNotification/NewPosts", "true"), + hasEntry("ShowNotification/NewReplies", "true") )) } diff --git a/src/test/kotlin/net/pterodactylus/sone/web/ajax/JsonPageTest.kt b/src/test/kotlin/net/pterodactylus/sone/web/ajax/JsonPageTest.kt index d5314c5..ac70936 100644 --- a/src/test/kotlin/net/pterodactylus/sone/web/ajax/JsonPageTest.kt +++ b/src/test/kotlin/net/pterodactylus/sone/web/ajax/JsonPageTest.kt @@ -8,6 +8,7 @@ import net.pterodactylus.sone.core.Core import net.pterodactylus.sone.core.ElementLoader import net.pterodactylus.sone.core.LinkedElement import net.pterodactylus.sone.core.Preferences +import net.pterodactylus.sone.core.UpdateChecker import net.pterodactylus.sone.data.Album import net.pterodactylus.sone.data.Image import net.pterodactylus.sone.data.Post @@ -16,6 +17,7 @@ import net.pterodactylus.sone.data.Profile import net.pterodactylus.sone.data.Sone import net.pterodactylus.sone.data.Sone.SoneStatus import net.pterodactylus.sone.data.Sone.SoneStatus.idle +import net.pterodactylus.sone.data.SoneOptions.DefaultSoneOptions import net.pterodactylus.sone.test.deepMock import net.pterodactylus.sone.test.get import net.pterodactylus.sone.test.mock @@ -51,6 +53,7 @@ abstract class JsonPageTest( protected val core = mock() protected val eventBus = mock() protected val preferences = Preferences(eventBus) + protected val updateChecker = mock() protected val elementLoader = mock() protected open val page: JsonPage by lazy { pageSupplier(webInterface) } protected val json by lazy { page.createJsonObject(freenetRequest) } @@ -92,6 +95,7 @@ abstract class JsonPageTest( @Before fun setupCore() { whenever(core.preferences).thenReturn(preferences) + whenever(core.updateChecker).thenReturn(updateChecker) whenever(core.getSone(anyString())).thenAnswer { (localSones + remoteSones)[it.getArgument(0)].asOptional() } whenever(core.getLocalSone(anyString())).thenAnswer { localSones[it[0]] } whenever(core.getPost(anyString())).thenAnswer { (posts + newPosts)[it[0]].asOptional() } @@ -112,6 +116,7 @@ abstract class JsonPageTest( @Before fun setupCurrentSone() { + whenever(currentSone.options).thenReturn(DefaultSoneOptions()) currentSone.mock("soneId", "Sone_Id", true, 1000, idle) } -- 2.7.4