🎨 Remove template context factory from web interface API
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / ajax / GetNotificationsAjaxPageTest.kt
1 package net.pterodactylus.sone.web.ajax
2
3 import net.pterodactylus.sone.main.SonePlugin
4 import net.pterodactylus.sone.test.argumentCaptor
5 import net.pterodactylus.sone.test.get
6 import net.pterodactylus.sone.test.getInstance
7 import net.pterodactylus.sone.test.mock
8 import net.pterodactylus.sone.test.whenever
9 import net.pterodactylus.sone.web.baseInjector
10 import net.pterodactylus.util.notify.Notification
11 import net.pterodactylus.util.notify.TemplateNotification
12 import net.pterodactylus.util.template.TemplateContext
13 import net.pterodactylus.util.template.TemplateContextFactory
14 import net.pterodactylus.util.version.Version
15 import org.hamcrest.MatcherAssert.assertThat
16 import org.hamcrest.Matchers.containsInAnyOrder
17 import org.hamcrest.Matchers.empty
18 import org.hamcrest.Matchers.equalTo
19 import org.hamcrest.Matchers.notNullValue
20 import org.junit.Test
21 import org.mockito.ArgumentMatchers.any
22 import org.mockito.Mockito.verify
23 import java.io.Writer
24
25 /**
26  * Unit test for [GetNotificationsAjaxPage].
27  */
28 class GetNotificationsAjaxPageTest : JsonPageTest("getNotifications.ajax", requiresLogin = false, needsFormPassword = false) {
29
30         override val page: JsonPage by lazy { GetNotificationsAjaxPage(webInterface, TemplateContextFactory()) }
31
32         private val testNotifications = listOf(
33                         createNotification("n1", 2000, "t1", 5000, true),
34                         createNotification("n2", 1000, "t2", 6000, false),
35                         createNotification("n3", 3000, "t3", 7000, true)
36         )
37
38         private fun createNotification(id: String, createdTime: Long, text: String, lastUpdatedTime: Long, dismissable: Boolean): Notification {
39                 return mock<Notification>().apply {
40                         whenever(this.id).thenReturn(id)
41                         whenever(this.createdTime).thenReturn(createdTime)
42                         whenever(this.lastUpdatedTime).thenReturn(lastUpdatedTime)
43                         whenever(this.isDismissable).thenReturn(dismissable)
44                         whenever(render(any())).then { it.get<Writer>(0).write(text) }
45                 }
46         }
47
48         @Test
49         fun `notification hash is calculated correctly`() {
50                 testNotifications.forEach { addNotification(it) }
51                 assertThatJsonIsSuccessful()
52                 assertThat(json["notificationHash"]?.asInt(), equalTo(listOf(1, 0, 2).map(testNotifications::get).hashCode()))
53         }
54
55         @Test
56         fun `options are included correctly`() {
57                 assertThatJsonIsSuccessful()
58                 assertThat(json["options"]!!["ShowNotification/NewSones"].asBoolean(), equalTo(true))
59                 assertThat(json["options"]!!["ShowNotification/NewPosts"].asBoolean(), equalTo(true))
60                 assertThat(json["options"]!!["ShowNotification/NewReplies"].asBoolean(), equalTo(true))
61         }
62
63         @Test
64         fun `options are included correctly when all false`() {
65                 currentSone.options.isShowNewSoneNotifications = false
66                 currentSone.options.isShowNewPostNotifications = false
67                 currentSone.options.isShowNewReplyNotifications = false
68                 assertThatJsonIsSuccessful()
69                 assertThat(json["options"]!!["ShowNotification/NewSones"].asBoolean(), equalTo(false))
70                 assertThat(json["options"]!!["ShowNotification/NewPosts"].asBoolean(), equalTo(false))
71                 assertThat(json["options"]!!["ShowNotification/NewReplies"].asBoolean(), equalTo(false))
72         }
73
74         @Test
75         fun `options are not included if user is not logged in`() {
76                 unsetCurrentSone()
77                 assertThatJsonIsSuccessful()
78                 assertThat(json["options"]?.toList(), empty())
79         }
80
81         @Test
82         fun `notifications are rendered correctly`() {
83                 testNotifications.forEach { addNotification(it) }
84                 assertThatJsonIsSuccessful()
85                 assertThat(json["notifications"]!!.toList().map { node -> listOf("id", "text", "createdTime", "lastUpdatedTime", "dismissable").map { it to node.get(it).asText() }.toMap() }, containsInAnyOrder(
86                                 mapOf("id" to "n1", "createdTime" to "2000", "lastUpdatedTime" to "5000", "dismissable" to "true", "text" to "t1"),
87                                 mapOf("id" to "n2", "createdTime" to "1000", "lastUpdatedTime" to "6000", "dismissable" to "false", "text" to "t2"),
88                                 mapOf("id" to "n3", "createdTime" to "3000", "lastUpdatedTime" to "7000", "dismissable" to "true", "text" to "t3")
89                 ))
90         }
91
92         @Test
93         fun `template notifications are rendered correctly`() {
94                 whenever(updateChecker.hasLatestVersion()).thenReturn(true)
95                 whenever(updateChecker.latestEdition).thenReturn(999)
96                 whenever(updateChecker.latestVersion).thenReturn(Version(0, 1, 2))
97                 whenever(updateChecker.latestVersionDate).thenReturn(998)
98                 val templateNotification = mock<TemplateNotification>().apply {
99                         whenever(id).thenReturn("n4")
100                         whenever(createdTime).thenReturn(4000)
101                         whenever(templateContext).thenReturn(TemplateContext())
102                         whenever(render(any(), any())).then { it.get<Writer>(1).write("t4") }
103                 }
104                 testNotifications.forEach { addNotification(it) }
105                 addNotification(templateNotification)
106                 assertThatJsonIsSuccessful()
107                 assertThat(json["notifications"]!!.last()["text"].asText(), equalTo("t4"))
108                 val templateContext = argumentCaptor<TemplateContext>()
109                 verify(templateNotification).render(templateContext.capture(), any())
110                 assertThat(templateContext.value["core"], equalTo<Any>(core))
111                 assertThat(templateContext.value["currentSone"], equalTo<Any>(currentSone))
112                 assertThat(templateContext.value["localSones"], equalTo<Any>(core.localSones))
113                 assertThat(templateContext.value["request"], equalTo<Any>(freenetRequest))
114                 assertThat(templateContext.value["currentVersion"], equalTo<Any>(SonePlugin.getPluginVersion()))
115                 assertThat(templateContext.value["hasLatestVersion"], equalTo<Any>(true))
116                 assertThat(templateContext.value["latestEdition"], equalTo<Any>(999L))
117                 assertThat(templateContext.value["latestVersion"], equalTo<Any>(Version(0, 1, 2)))
118                 assertThat(templateContext.value["latestVersionTime"], equalTo<Any>(998L))
119                 assertThat(templateContext.value["notification"], equalTo<Any>(templateNotification))
120         }
121
122         @Test
123         fun `page can be created by dependency injection`() {
124             assertThat(baseInjector.getInstance<GetNotificationsAjaxPage>(), notNullValue())
125         }
126
127 }