1 package net.pterodactylus.sone.web.pages
3 import net.pterodactylus.sone.data.Album
4 import net.pterodactylus.sone.data.Image
5 import net.pterodactylus.sone.data.Post
6 import net.pterodactylus.sone.data.PostReply
7 import net.pterodactylus.sone.data.Profile
8 import net.pterodactylus.sone.data.Sone
9 import net.pterodactylus.sone.freenet.wot.Identity
10 import net.pterodactylus.sone.freenet.wot.OwnIdentity
11 import net.pterodactylus.sone.test.getInstance
12 import net.pterodactylus.sone.test.mock
13 import net.pterodactylus.sone.test.whenever
14 import net.pterodactylus.sone.utils.Pagination
15 import net.pterodactylus.sone.web.baseInjector
16 import net.pterodactylus.sone.web.page.*
17 import org.hamcrest.MatcherAssert.assertThat
18 import org.hamcrest.Matchers.contains
19 import org.hamcrest.Matchers.equalTo
20 import org.hamcrest.Matchers.notNullValue
21 import org.junit.Before
25 * Unit test for [KnownSonesPage].
27 class KnownSonesPageTest: WebPageTest(::KnownSonesPage) {
29 private val sones = listOf(
30 createSone(1000, 4, 7, 2, "sone2", true, true),
31 createSone(2000, 3, 2, 3, "Sone1", false, true),
32 createSone(3000, 3, 8, 1, "Sone3", true, false),
33 createSone(4000, 1, 6, 0, "sone0", false, false)
38 addSone("sone1", sones[0])
39 addSone("sone2", sones[1])
40 addSone("sone3", sones[2])
41 addSone("sone4", sones[3])
44 private fun createSone(time: Long, posts: Int, replies: Int, images: Int, name: String, local: Boolean, new: Boolean) = mock<Sone>().apply {
45 whenever(identity).thenReturn(if (local) mock<OwnIdentity>() else mock<Identity>())
46 whenever(this.isLocal).thenReturn(local)
47 whenever(isKnown).thenReturn(!new)
48 whenever(this.time).thenReturn(time)
49 whenever(this.posts).thenReturn((0..(posts - 1)).map { mock<Post>() })
50 whenever(this.replies).thenReturn((0..(replies - 1)).map { mock<PostReply>() }.toSet())
51 val album = mock<Album>()
52 whenever(album.images).thenReturn(((0..(images - 1)).map { mock<Image>() }))
53 val rootAlbum = mock<Album>().apply {
54 whenever(albums).thenReturn(listOf(album))
56 whenever(this.rootAlbum).thenReturn(rootAlbum)
57 whenever(this.profile).thenReturn(mock())
58 whenever(id).thenReturn(name.toLowerCase())
59 whenever(this.name).thenReturn(name)
62 private fun verifySonesAreInOrder(vararg indices: Int) {
63 @Suppress("UNCHECKED_CAST")
64 assertThat(templateContext["knownSones"] as Iterable<Sone>, contains(
65 *indices.map { sones[it] }.toTypedArray()
69 private fun verifyStoredFields(sort: String, order: String, filter: String) {
70 assertThat(templateContext["sort"], equalTo<Any>(sort))
71 assertThat(templateContext["order"], equalTo<Any>(order))
72 assertThat(templateContext["filter"], equalTo<Any>(filter))
76 fun `page returns correct path`() {
77 assertThat(page.path, equalTo("knownSones.html"))
81 fun `page does not require login`() {
82 assertThat(page.requiresLogin(), equalTo(false))
86 fun `page returns correct title`() {
87 whenever(l10n.getString("Page.KnownSones.Title")).thenReturn("known sones page title")
88 assertThat(page.getPageTitle(soneRequest), equalTo("known sones page title"))
92 fun `default known sones are sorted newest first`() {
94 verifySonesAreInOrder(3, 2, 1, 0)
95 verifyStoredFields("activity", "desc", "")
100 fun `known sones can be sorted by oldest first`() {
101 addHttpRequestParameter("order", "asc")
103 verifySonesAreInOrder(0, 1, 2, 3)
104 verifyStoredFields("activity", "asc", "")
109 fun `known sones can be sorted by posts, most posts first`() {
110 addHttpRequestParameter("sort", "posts")
112 verifySonesAreInOrder(0, 2, 1, 3)
113 verifyStoredFields("posts", "desc", "")
118 fun `known sones can be sorted by posts, least posts first`() {
119 addHttpRequestParameter("sort", "posts")
120 addHttpRequestParameter("order", "asc")
122 verifySonesAreInOrder(3, 1, 2, 0)
123 verifyStoredFields("posts", "asc", "")
128 fun `known sones can be sorted by images, most images first`() {
129 addHttpRequestParameter("sort", "images")
131 verifySonesAreInOrder(1, 0, 2, 3)
132 verifyStoredFields("images", "desc", "")
137 fun `known sones can be sorted by images, least images first`() {
138 addHttpRequestParameter("sort", "images")
139 addHttpRequestParameter("order", "asc")
141 verifySonesAreInOrder(3, 2, 0, 1)
142 verifyStoredFields("images", "asc", "")
147 fun `known sones can be sorted by nice name, ascending`() {
148 addHttpRequestParameter("sort", "name")
149 addHttpRequestParameter("order", "asc")
151 verifySonesAreInOrder(3, 1, 0, 2)
152 verifyStoredFields("name", "asc", "")
157 fun `known sones can be sorted by nice name, descending`() {
158 addHttpRequestParameter("sort", "name")
160 verifySonesAreInOrder(2, 0, 1, 3)
161 verifyStoredFields("name", "desc", "")
166 fun `known sones can be filtered by local sones`() {
167 addHttpRequestParameter("filter", "own")
169 verifySonesAreInOrder(2, 0)
170 verifyStoredFields("activity", "desc", "own")
175 fun `known sones can be filtered by non-local sones`() {
176 addHttpRequestParameter("filter", "not-own")
178 verifySonesAreInOrder(3, 1)
179 verifyStoredFields("activity", "desc", "not-own")
184 fun `known sones can be filtered by new sones`() {
185 addHttpRequestParameter("filter", "new")
187 verifySonesAreInOrder(1, 0)
188 verifyStoredFields("activity", "desc", "new")
193 fun `known sones can be filtered by known sones`() {
194 addHttpRequestParameter("filter", "not-new")
196 verifySonesAreInOrder(3, 2)
197 verifyStoredFields("activity", "desc", "not-new")
202 fun `known sones can be filtered by followed sones`() {
203 addHttpRequestParameter("filter", "followed")
204 listOf("sone1", "sone3").forEach { whenever(currentSone.hasFriend(it)).thenReturn(true) }
206 verifySonesAreInOrder(2, 1)
207 verifyStoredFields("activity", "desc", "followed")
212 fun `known sones can be filtered by not-followed sones`() {
213 addHttpRequestParameter("filter", "not-followed")
214 listOf("sone1", "sone3").forEach { whenever(currentSone.hasFriend(it)).thenReturn(true) }
216 verifySonesAreInOrder(3, 0)
217 verifyStoredFields("activity", "desc", "not-followed")
222 fun `known sones can not be filtered by followed sones if there is no current sone`() {
223 addHttpRequestParameter("filter", "followed")
226 verifySonesAreInOrder(3, 2, 1, 0)
227 verifyStoredFields("activity", "desc", "followed")
232 fun `known sones can not be filtered by not-followed sones if there is no current sone`() {
233 addHttpRequestParameter("filter", "not-followed")
236 verifySonesAreInOrder(3, 2, 1, 0)
237 verifyStoredFields("activity", "desc", "not-followed")
242 fun `pagination is set in template context`() {
244 @Suppress("UNCHECKED_CAST")
245 assertThat((templateContext["pagination"] as Pagination<Sone>).items, contains(*listOf(3, 2, 1, 0).map { sones[it] }.toTypedArray()))
250 fun `page can be created by dependency injection`() {
251 assertThat(baseInjector.getInstance<KnownSonesPage>(), notNullValue())
255 fun `page is annotated with the correct menuname`() {
256 assertThat(page.menuName, equalTo("KnownSones"))