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