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 override var page: JsonPage = GetStatusAjaxPage(webInterface, elementLoader, newElements, timeTextConverter, l10nFilter, TimeZone.getTimeZone("UTC"))
44 fun setupTimeTextConverter() {
45 whenever(timeTextConverter.getTimeText(anyLong())).thenAnswer { TimeText(L10nText(it.getArgument<Long>(0).toString()), it.getArgument(0)) }
46 whenever(l10nFilter.format(any(), any(), any())).thenAnswer { it.getArgument<L10nText>(1).text }
50 fun `page returns correct attribute “loggedIn” if sone is logged in`() {
51 assertThat(json.get("loggedIn")?.asText(), equalTo("true"))
55 fun `page returns correct attribute “loggedIn” if sone is not logged in`() {
57 assertThat(json.get("loggedIn")?.asText(), equalTo("false"))
61 fun `page returns options for sone if sone is logged in`() {
62 assertThat(json.get("options")?.toMap(), allOf(
63 hasEntry("ShowNotification/NewSones", "true"),
64 hasEntry("ShowNotification/NewPosts", "true"),
65 hasEntry("ShowNotification/NewReplies", "true")
70 fun `page returns empty options if sone is not logged in`() {
72 assertThat(json.get("options"), emptyIterable())
76 fun `page returns empty sones object if no sone is logged in and no sones parameter is given`() {
78 assertThat(json.get("sones"), emptyIterable())
82 fun `page returns a sones object with the current sone if not other sones parameter is given`() {
83 assertThat(json.get("sones")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
84 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")
89 fun `page returns some sones objects with the current sone and some sones given as sones parameter`() {
90 addSone(deepMock<Sone>().mock("sone1", "Sone 1", false, 2000, downloading))
91 addSone(deepMock<Sone>().mock("sone3", "Sone 3", true, 3000, inserting))
92 addRequestParameter("soneIds", "sone1,sone2,sone3")
93 assertThat(json.get("sones")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
94 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 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"),
96 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")
101 fun `page returns correct notifications hash`() {
102 val notifications = listOf(
103 mock<Notification>().apply { whenever(this.createdTime).thenReturn(2000) },
104 mock<Notification>().apply { whenever(this.createdTime).thenReturn(1000) }
106 notifications.forEachIndexed { index, notification -> addNotification(notification, "notification$index")}
107 assertThat(json.get("notificationHash")?.asInt(), equalTo(notifications.sortedBy { it.createdTime }.hashCode()))
111 fun `page returns new posts`() {
112 addNewPost("post1", "sone1", 1000)
113 addNewPost("post2", "sone2", 2000, "sone1")
114 assertThat(json.get("newPosts")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
115 mapOf("id" to "post1", "sone" to "sone1", "time" to "1000", "recipient" to null),
116 mapOf("id" to "post2", "sone" to "sone2", "time" to "2000", "recipient" to "sone1")
121 fun `page returns new replies`() {
122 addNewReply("reply1", "sone1", "post1", "sone11")
123 addNewReply("reply2", "sone2", "post2", "sone22")
124 assertThat(json.get("newReplies")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
125 mapOf<String, String?>("id" to "reply1", "sone" to "sone1", "post" to "post1", "postSone" to "sone11"),
126 mapOf("id" to "reply2", "sone" to "sone2", "post" to "post2", "postSone" to "sone22")
131 fun `page returns information about loaded elements`() {
132 addLinkedElement("KSK@test.png", loading = false, failed = false)
133 addLinkedElement("KSK@test.html", loading = true, failed = false)
134 addLinkedElement("KSK@test.jpeg", loading = false, failed = true)
135 addRequestParameter("elements", jsonArray("KSK@test.png", "KSK@test.html", "KSK@test.jpeg").toString())
136 assertThat(json.get("linkedElements")!!.elements().asSequence().map { it.toMap() }.toList(), containsInAnyOrder(
137 mapOf<String, String?>("link" to "KSK@test.png", "loading" to "false", "failed" to "false"),
138 mapOf("link" to "KSK@test.html", "loading" to "true", "failed" to "false"),
139 mapOf("link" to "KSK@test.jpeg", "loading" to "false", "failed" to "true")
144 fun `page can be created by dependency injection`() {
145 assertThat(baseInjector.createChildInjector(
146 ElementLoader::class.isProvidedByMock(),
147 TimeTextConverter::class.isProvidedByMock(),
148 L10nFilter::class.isProvidedByMock()
149 ).getInstance<GetStatusAjaxPage>(), notNullValue())
152 private fun JsonNode.toMap() = fields().asSequence().map { it.key!! to if (it.value.isNull) null else it.value.asText()!! }.toMap()