1 package net.pterodactylus.sone.web.ajax
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
32 import org.mockito.ArgumentMatchers.any
33 import org.mockito.ArgumentMatchers.anyLong
34 import java.util.Locale.ENGLISH
35 import java.util.TimeZone
38 * Unit test for [GetStatusAjaxPage].
40 class GetStatusAjaxPageTest: JsonPageTest("getStatus.ajax", requiresLogin = false, needsFormPassword = false) {
43 val overrideLocale = OverrideLocale(ENGLISH)
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"))
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 }
56 fun `page returns correct attribute “loggedIn” if sone is logged in`() {
57 assertThat(json.get("loggedIn")?.asText(), equalTo("true"))
61 fun `page returns correct attribute “loggedIn” if sone is not logged in`() {
63 assertThat(json.get("loggedIn")?.asText(), equalTo("false"))
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")
76 fun `page returns empty options if sone is not logged in`() {
78 assertThat(json.get("options"), emptyIterable())
82 fun `page returns empty sones object if no sone is logged in and no sones parameter is given`() {
84 assertThat(json.get("sones"), emptyIterable())
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")
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")
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) }
112 notifications.forEachIndexed { index, notification -> addNotification(notification, "notification$index")}
113 assertThat(json.get("notificationHash")?.asInt(), equalTo(notifications.sortedBy { it.createdTime }.hashCode()))
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")
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")
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")
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())
158 private fun JsonNode.toMap() = fields().asSequence().map { it.key!! to if (it.value.isNull) null else it.value.asText()!! }.toMap()