✨ Use recipient Sone as reply sender
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / template / PostAccessorTest.kt
1 package net.pterodactylus.sone.template
2
3 import net.pterodactylus.sone.core.*
4 import net.pterodactylus.sone.data.*
5 import net.pterodactylus.sone.test.*
6 import net.pterodactylus.sone.utils.*
7 import net.pterodactylus.util.template.*
8 import org.hamcrest.MatcherAssert.*
9 import org.hamcrest.Matchers.*
10 import org.junit.*
11
12 /**
13  * Unit test for [PostAccessor].
14  */
15 class PostAccessorTest {
16
17         private val core = mock<Core>()
18         private val accessor = PostAccessor(core)
19         private val post = mock<Post>()
20         private val now = System.currentTimeMillis()
21
22         @Before
23         fun setupPost() {
24                 whenever(post.id).thenReturn("post-id")
25         }
26
27         @Test
28         fun `accessor returns the correct replies`() {
29                 val replies = listOf(
30                                 createPostReply(2000),
31                                 createPostReply(-1000),
32                                 createPostReply(-2000),
33                                 createPostReply(-3000),
34                                 createPostReply(-4000)
35                 )
36                 whenever(core.getReplies("post-id")).thenReturn(replies)
37                 val repliesForPost = accessor[null, post, "replies"] as Collection<PostReply>
38                 assertThat(repliesForPost, contains(
39                                 replies[1],
40                                 replies[2],
41                                 replies[3],
42                                 replies[4]
43                 ))
44         }
45
46         private fun createPostReply(timeOffset: Long) = mock<PostReply>().apply {
47                 whenever(time).thenReturn(now + timeOffset)
48         }
49
50         @Test
51         fun `accessor returns the liking sones`() {
52                 val sones = setOf<Sone>()
53                 whenever(core.getLikes(post)).thenReturn(sones)
54                 val likingSones = accessor[null, post, "likes"] as Set<Sone>
55                 assertThat(likingSones, equalTo(sones))
56         }
57
58         @Test
59         fun `accessor returns whether the current sone liked a post`() {
60                 val sone = mock<Sone>()
61                 whenever(sone.isLikedPostId("post-id")).thenReturn(true)
62                 val templateContext = TemplateContext()
63                 templateContext["currentSone"] = sone
64                 assertThat(accessor[templateContext, post, "liked"], equalTo<Any>(true))
65         }
66
67         @Test
68         fun `accessor returns false if post is not liked`() {
69                 val sone = mock<Sone>()
70                 val templateContext = TemplateContext()
71                 templateContext["currentSone"] = sone
72                 assertThat(accessor[templateContext, post, "liked"], equalTo<Any>(false))
73         }
74
75         @Test
76         fun `accessor returns false if there is no current sone`() {
77                 val templateContext = TemplateContext()
78                 assertThat(accessor[templateContext, post, "liked"], equalTo<Any>(false))
79         }
80
81         @Test
82         fun `accessor returns that not known post is new`() {
83                 assertThat(accessor[null, post, "new"], equalTo<Any>(true))
84         }
85
86         @Test
87         fun `accessor returns that known post is not new`() {
88                 whenever(post.isKnown).thenReturn(true)
89                 assertThat(accessor[null, post, "new"], equalTo<Any>(false))
90         }
91
92         @Test
93         fun `accessor returns if post is bookmarked`() {
94                 whenever(core.isBookmarked(post)).thenReturn(true)
95                 assertThat(accessor[null, post, "bookmarked"], equalTo<Any>(true))
96         }
97
98         @Test
99         fun `reply sone for remote post without replies is current sone`() {
100                 val post = mockPostFrom(remoteSone)
101                 assertThat(accessor[templateContext, post, "replySone"], equalTo<Any>(currentSone))
102         }
103
104         @Test
105         fun `reply sone for remote post with remote replies is current sone`() {
106                 val post = mockPostFrom(remoteSone)
107                 val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(remoteSone))
108                 whenever(core.getReplies("post-id")).thenReturn(replies)
109                 assertThat(accessor[templateContext, post, "replySone"], equalTo<Any>(currentSone))
110         }
111
112         @Test
113         fun `reply sone for remote post with remote and one local replies is sone of local reply`() {
114                 val post = mockPostFrom(remoteSone)
115                 val localSone = mockLocalSone()
116                 val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(localSone))
117                 whenever(core.getReplies("post-id")).thenReturn(replies)
118                 assertThat(accessor[templateContext, post, "replySone"], equalTo<Any>(localSone))
119         }
120
121         @Test
122         fun `reply sone for remote post with remote and several local replies is sone of latest local reply`() {
123                 val post = mockPostFrom(remoteSone)
124                 val localSone1 = mockLocalSone()
125                 val localSone2 = mockLocalSone()
126                 val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(localSone1), mockReplyFrom(localSone2))
127                 whenever(core.getReplies("post-id")).thenReturn(replies)
128                 assertThat(accessor[templateContext, post, "replySone"], equalTo<Any>(localSone2))
129         }
130
131         @Test
132         fun `reply sone for local post without replies is post sone`() {
133                 val localSone = mockLocalSone()
134                 val post = mockPostFrom(localSone)
135                 assertThat(accessor[templateContext, post, "replySone"], equalTo<Any>(localSone))
136         }
137
138         @Test
139         fun `reply sone for local post with remote replies is local sone`() {
140                 val localSone = mockLocalSone()
141                 val post = mockPostFrom(localSone)
142                 val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(remoteSone))
143                 whenever(core.getReplies("post-id")).thenReturn(replies)
144                 assertThat(accessor[templateContext, post, "replySone"], equalTo<Any>(localSone))
145         }
146
147         @Test
148         fun `reply sone for local post with remote and one local replies is local reply sone`() {
149                 val localSone1 = mockLocalSone()
150                 val post = mockPostFrom(localSone1)
151                 val localSone2 = mockLocalSone()
152                 val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(localSone2))
153                 whenever(core.getReplies("post-id")).thenReturn(replies)
154                 assertThat(accessor[templateContext, post, "replySone"], equalTo<Any>(localSone2))
155         }
156
157         @Test
158         fun `reply sone for local post with remote and several local replies is latest local reply sone`() {
159                 val localSone1 = mockLocalSone()
160                 val post = mockPostFrom(localSone1)
161                 val localSone2 = mockLocalSone()
162                 val localSone3 = mockLocalSone()
163                 val replies = listOf(mockReplyFrom(remoteSone), mockReplyFrom(localSone2), mockReplyFrom(localSone3))
164                 whenever(core.getReplies("post-id")).thenReturn(replies)
165                 assertThat(accessor[templateContext, post, "replySone"], equalTo<Any>(localSone3))
166         }
167
168         @Test
169         fun `reply sone for post directed at local sone is local sone`() {
170                 val localSone = mockLocalSone()
171                 val post = mockPostFrom(remoteSone, localSone)
172                 assertThat(accessor[templateContext, post, "replySone"], equalTo<Any>(localSone))
173         }
174
175
176         @Test
177         fun `accessor returns other properties`() {
178                 assertThat(accessor[null, post, "hashCode"], equalTo<Any>(post.hashCode()))
179         }
180
181 }
182
183 private val currentSone = mock<Sone>()
184 private val remoteSone = mock<Sone>()
185 private fun mockLocalSone() = mock<Sone>().apply { whenever(isLocal).thenReturn(true) }
186
187 private val templateContext = TemplateContext().apply {
188         this["currentSone"] = currentSone
189 }
190
191 private fun mockPostFrom(sone: Sone, recipient: Sone? = null) = mock<Post>().apply {
192         whenever(id).thenReturn("post-id")
193         whenever(this.sone).thenReturn(sone)
194         whenever(this.recipient).thenReturn(recipient.asOptional())
195 }
196
197 private fun mockReplyFrom(sone: Sone) = mock<PostReply>().apply { whenever(this.sone).thenReturn(sone) }