Add test for DI constructability of GetStatusAjaxPage
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / web / ajax / GetStatusAjaxPageTest.kt
1 package net.pterodactylus.sone.web.ajax
2
3 import com.fasterxml.jackson.databind.JsonNode
4 import net.pterodactylus.sone.core.ElementLoader
5 import net.pterodactylus.sone.data.Sone
6 import net.pterodactylus.sone.data.Sone.SoneStatus.downloading
7 import net.pterodactylus.sone.data.Sone.SoneStatus.inserting
8 import net.pterodactylus.sone.freenet.L10nFilter
9 import net.pterodactylus.sone.freenet.L10nText
10 import net.pterodactylus.sone.test.deepMock
11 import net.pterodactylus.sone.test.getInstance
12 import net.pterodactylus.sone.test.isProvidedByMock
13 import net.pterodactylus.sone.test.mock
14 import net.pterodactylus.sone.test.whenever
15 import net.pterodactylus.sone.text.TimeText
16 import net.pterodactylus.sone.text.TimeTextConverter
17 import net.pterodactylus.sone.utils.jsonArray
18 import net.pterodactylus.sone.web.baseInjector
19 import net.pterodactylus.util.notify.Notification
20 import org.hamcrest.MatcherAssert.assertThat
21 import org.hamcrest.Matchers.allOf
22 import org.hamcrest.Matchers.containsInAnyOrder
23 import org.hamcrest.Matchers.emptyIterable
24 import org.hamcrest.Matchers.equalTo
25 import org.hamcrest.Matchers.hasEntry
26 import org.hamcrest.Matchers.notNullValue
27 import org.junit.Before
28 import org.junit.Test
29 import org.mockito.ArgumentMatchers.any
30 import org.mockito.ArgumentMatchers.anyLong
31 import java.util.TimeZone
32
33 /**
34  * Unit test for [GetStatusAjaxPage].
35  */
36 class GetStatusAjaxPageTest: JsonPageTest("getStatus.ajax", requiresLogin = false, needsFormPassword = false) {
37
38         private val timeTextConverter = mock<TimeTextConverter>()
39         private val l10nFilter = mock<L10nFilter>()
40         override var page: JsonPage = GetStatusAjaxPage(webInterface, elementLoader, timeTextConverter, l10nFilter, TimeZone.getTimeZone("UTC"))
41
42         @Before
43         fun setupTimeTextConverter() {
44                 whenever(timeTextConverter.getTimeText(anyLong())).thenAnswer { TimeText(L10nText(it.getArgument<Long>(0).toString()), it.getArgument(0)) }
45                 whenever(l10nFilter.format(any(), any(), any())).thenAnswer { it.getArgument<L10nText>(1).text }
46         }
47
48         @Test
49         fun `page returns correct attribute “loggedIn” if sone is logged in`() {
50                 assertThat(json.get("loggedIn")?.asText(), equalTo("true"))
51         }
52
53         @Test
54         fun `page returns correct attribute “loggedIn” if sone is not logged in`() {
55                 unsetCurrentSone()
56                 assertThat(json.get("loggedIn")?.asText(), equalTo("false"))
57         }
58
59         @Test
60         fun `page returns options for sone if sone is logged in`() {
61                 assertThat(json.get("options")?.toMap(), allOf(
62                                 hasEntry("ShowNotification/NewSones", "true"),
63                                 hasEntry("ShowNotification/NewPosts", "true"),
64                                 hasEntry("ShowNotification/NewReplies", "true")
65                 ))
66         }
67
68         @Test
69         fun `page returns empty options if sone is not logged in`() {
70                 unsetCurrentSone()
71                 assertThat(json.get("options"), emptyIterable())
72         }
73
74         @Test
75         fun `page returns empty sones object if no sone is logged in and no sones parameter is given`() {
76                 unsetCurrentSone()
77                 assertThat(json.get("sones"), emptyIterable())
78         }
79
80         @Test
81         fun `page returns a sones object with the current sone if not other sones parameter is given`() {
82                 assertThat(json.get("sones")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
83                                 mapOf<String, String?>("id" to "soneId", "name" to "Sone_Id", "local" to "true", "status" to "idle", "modified" to "false", "locked" to "false", "lastUpdatedUnknown" to "false", "lastUpdated" to "Jan 1, 1970, 00:00:01", "lastUpdatedText" to "1000")
84                 ))
85         }
86
87         @Test
88         fun `page returns some sones objects with the current sone and some sones given as sones parameter`() {
89                 addSone(deepMock<Sone>().mock("sone1", "Sone 1", false, 2000, downloading))
90                 addSone(deepMock<Sone>().mock("sone3", "Sone 3", true, 3000, inserting))
91                 addRequestParameter("soneIds", "sone1,sone2,sone3")
92                 assertThat(json.get("sones")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
93                                 mapOf<String, String?>("id" to "soneId", "name" to "Sone_Id", "local" to "true", "status" to "idle", "modified" to "false", "locked" to "false", "lastUpdatedUnknown" to "false", "lastUpdated" to "Jan 1, 1970, 00:00:01", "lastUpdatedText" to "1000"),
94                                 mapOf("id" to "sone1", "name" to "Sone 1", "local" to "false", "status" to "downloading", "modified" to "false", "locked" to "false", "lastUpdatedUnknown" to "false", "lastUpdated" to "Jan 1, 1970, 00:00:02", "lastUpdatedText" to "2000"),
95                                 mapOf("id" to "sone3", "name" to "Sone 3", "local" to "true", "status" to "inserting", "modified" to "false", "locked" to "false", "lastUpdatedUnknown" to "false", "lastUpdated" to "Jan 1, 1970, 00:00:03", "lastUpdatedText" to "3000")
96                 ))
97         }
98
99         @Test
100         fun `page returns correct notifications hash`() {
101                 val notifications = listOf(
102                                 mock<Notification>().apply { whenever(this.createdTime).thenReturn(2000) },
103                                 mock<Notification>().apply { whenever(this.createdTime).thenReturn(1000) }
104                 )
105                 notifications.forEachIndexed { index, notification -> addNotification(notification, "notification$index")}
106                 assertThat(json.get("notificationHash")?.asInt(), equalTo(notifications.sortedBy { it.createdTime }.hashCode()))
107         }
108
109         @Test
110         fun `page returns new posts`() {
111                 addNewPost("post1", "sone1", 1000)
112                 addNewPost("post2", "sone2", 2000, "sone1")
113                 assertThat(json.get("newPosts")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
114                                 mapOf("id" to "post1", "sone" to "sone1", "time" to "1000", "recipient" to null),
115                                 mapOf("id" to "post2", "sone" to "sone2", "time" to "2000", "recipient" to "sone1")
116                 ))
117         }
118
119         @Test
120         fun `page returns new replies`() {
121                 addNewReply("reply1", "sone1", "post1", "sone11")
122                 addNewReply("reply2", "sone2", "post2", "sone22")
123                 assertThat(json.get("newReplies")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
124                                 mapOf<String, String?>("id" to "reply1", "sone" to "sone1", "post" to "post1", "postSone" to "sone11"),
125                                 mapOf("id" to "reply2", "sone" to "sone2", "post" to "post2", "postSone" to "sone22")
126                 ))
127         }
128
129         @Test
130         fun `page returns information about loaded elements`() {
131                 addLinkedElement("KSK@test.png", loading = false, failed = false)
132                 addLinkedElement("KSK@test.html", loading = true, failed = false)
133                 addLinkedElement("KSK@test.jpeg", loading = false, failed = true)
134                 addRequestParameter("elements", jsonArray("KSK@test.png", "KSK@test.html", "KSK@test.jpeg").toString())
135                 assertThat(json.get("linkedElements")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
136                                 mapOf<String, String?>("link" to "KSK@test.png", "loading" to "false", "failed" to "false"),
137                                 mapOf("link" to "KSK@test.html", "loading" to "true", "failed" to "false"),
138                                 mapOf("link" to "KSK@test.jpeg", "loading" to "false", "failed" to "true")
139                 ))
140         }
141
142         @Test
143         fun `page can be created by dependency injection`() {
144             assertThat(baseInjector.createChildInjector(
145                             ElementLoader::class.isProvidedByMock(),
146                             TimeTextConverter::class.isProvidedByMock(),
147                             L10nFilter::class.isProvidedByMock()
148             ).getInstance<GetStatusAjaxPage>(), notNullValue())
149         }
150
151         private fun JsonNode.toMap() = fields().asSequence().map { it.key!! to if (it.value.isNull) null else it.value.asText()!! }.toMap()
152
153 }