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.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.NewElements
19 import net.pterodactylus.sone.web.baseInjector
20 import net.pterodactylus.util.notify.Notification
21 import org.hamcrest.MatcherAssert.assertThat
22 import org.hamcrest.Matchers.allOf
23 import org.hamcrest.Matchers.containsInAnyOrder
24 import org.hamcrest.Matchers.emptyIterable
25 import org.hamcrest.Matchers.equalTo
26 import org.hamcrest.Matchers.hasEntry
27 import org.hamcrest.Matchers.notNullValue
28 import org.junit.Before
30 import org.mockito.ArgumentMatchers.any
31 import org.mockito.ArgumentMatchers.anyLong
32 import java.util.TimeZone
35 * Unit test for [GetStatusAjaxPage].
37 class GetStatusAjaxPageTest: JsonPageTest("getStatus.ajax", requiresLogin = false, needsFormPassword = false) {
39 private val timeTextConverter = mock<TimeTextConverter>()
40 private val l10nFilter = mock<L10nFilter>()
41 private val newElements = mock<NewElements>().apply {
42 whenever(newPosts).then { this@GetStatusAjaxPageTest.newPosts.values }
43 whenever(newReplies).then { this@GetStatusAjaxPageTest.newReplies.values }
45 override var page: JsonPage = GetStatusAjaxPage(webInterface, elementLoader, newElements, timeTextConverter, l10nFilter, TimeZone.getTimeZone("UTC"))
48 fun setupTimeTextConverter() {
49 whenever(timeTextConverter.getTimeText(anyLong())).thenAnswer { TimeText(L10nText(it.getArgument<Long>(0).toString()), it.getArgument(0)) }
50 whenever(l10nFilter.format(any(), any(), any())).thenAnswer { it.getArgument<L10nText>(1).text }
54 fun `page returns correct attribute “loggedIn” if sone is logged in`() {
55 assertThat(json.get("loggedIn")?.asText(), equalTo("true"))
59 fun `page returns correct attribute “loggedIn” if sone is not logged in`() {
61 assertThat(json.get("loggedIn")?.asText(), equalTo("false"))
65 fun `page returns options for sone if sone is logged in`() {
66 assertThat(json.get("options")?.toMap(), allOf(
67 hasEntry("ShowNotification/NewSones", "true"),
68 hasEntry("ShowNotification/NewPosts", "true"),
69 hasEntry("ShowNotification/NewReplies", "true")
74 fun `page returns empty options if sone is not logged in`() {
76 assertThat(json.get("options"), emptyIterable())
80 fun `page returns empty sones object if no sone is logged in and no sones parameter is given`() {
82 assertThat(json.get("sones"), emptyIterable())
86 fun `page returns a sones object with the current sone if not other sones parameter is given`() {
87 assertThat(json.get("sones")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
88 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")
93 fun `page returns some sones objects with the current sone and some sones given as sones parameter`() {
94 addSone(deepMock<Sone>().mock("sone1", "Sone 1", false, 2000, downloading))
95 addSone(deepMock<Sone>().mock("sone3", "Sone 3", true, 3000, inserting))
96 addRequestParameter("soneIds", "sone1,sone2,sone3")
97 assertThat(json.get("sones")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
98 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"),
99 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"),
100 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")
105 fun `page returns correct notifications hash`() {
106 val notifications = listOf(
107 mock<Notification>().apply { whenever(this.createdTime).thenReturn(2000) },
108 mock<Notification>().apply { whenever(this.createdTime).thenReturn(1000) }
110 notifications.forEachIndexed { index, notification -> addNotification(notification, "notification$index")}
111 assertThat(json.get("notificationHash")?.asInt(), equalTo(notifications.sortedBy { it.createdTime }.hashCode()))
115 fun `page returns new posts`() {
116 addNewPost("post1", "sone1", 1000)
117 addNewPost("post2", "sone2", 2000, "sone1")
118 assertThat(json.get("newPosts")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
119 mapOf("id" to "post1", "sone" to "sone1", "time" to "1000", "recipient" to null),
120 mapOf("id" to "post2", "sone" to "sone2", "time" to "2000", "recipient" to "sone1")
125 fun `page returns new replies`() {
126 addNewReply("reply1", "sone1", "post1", "sone11")
127 addNewReply("reply2", "sone2", "post2", "sone22")
128 assertThat(json.get("newReplies")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
129 mapOf<String, String?>("id" to "reply1", "sone" to "sone1", "post" to "post1", "postSone" to "sone11"),
130 mapOf("id" to "reply2", "sone" to "sone2", "post" to "post2", "postSone" to "sone22")
135 fun `page returns information about loaded elements`() {
136 addLinkedElement("KSK@test.png", loading = false, failed = false)
137 addLinkedElement("KSK@test.html", loading = true, failed = false)
138 addLinkedElement("KSK@test.jpeg", loading = false, failed = true)
139 addRequestParameter("elements", jsonArray("KSK@test.png", "KSK@test.html", "KSK@test.jpeg").toString())
140 assertThat(json.get("linkedElements")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
141 mapOf<String, String?>("link" to "KSK@test.png", "loading" to "false", "failed" to "false"),
142 mapOf("link" to "KSK@test.html", "loading" to "true", "failed" to "false"),
143 mapOf("link" to "KSK@test.jpeg", "loading" to "false", "failed" to "true")
148 fun `page can be created by dependency injection`() {
149 assertThat(baseInjector.createChildInjector(
150 ElementLoader::class.isProvidedByMock(),
151 TimeTextConverter::class.isProvidedByMock(),
152 L10nFilter::class.isProvidedByMock()
153 ).getInstance<GetStatusAjaxPage>(), notNullValue())
156 private fun JsonNode.toMap() = fields().asSequence().map { it.key!! to if (it.value.isNull) null else it.value.asText()!! }.toMap()