910f968cdf0300d573b790b5d2e64526126c49de
[Sone.git] / src / test / kotlin / net / pterodactylus / sone / notify / PostVisibilityFilterTest.kt
1 package net.pterodactylus.sone.notify
2
3 import com.google.common.base.Optional
4 import com.google.inject.Guice
5 import net.pterodactylus.sone.data.Post
6 import net.pterodactylus.sone.data.Sone
7 import net.pterodactylus.sone.freenet.wot.Identity
8 import net.pterodactylus.sone.freenet.wot.OwnIdentity
9 import net.pterodactylus.sone.freenet.wot.Trust
10 import net.pterodactylus.sone.test.mock
11 import net.pterodactylus.sone.test.verifySingletonInstance
12 import net.pterodactylus.sone.test.whenever
13 import org.hamcrest.MatcherAssert.assertThat
14 import org.hamcrest.Matchers.equalTo
15 import org.junit.Test
16
17 /**
18  * Unit test for [PostVisibilityFilterTest].
19  */
20 class PostVisibilityFilterTest {
21
22         private val postVisibilityFilter = PostVisibilityFilter()
23         private val localSone = mock<Sone>()
24         private val localIdentity = mock<OwnIdentity>()
25         private val post = mock<Post>()
26         private val remoteSone = mock<Sone>()
27         private val remoteIdentity = mock<Identity>()
28
29         init {
30                 whenever(localSone.id).thenReturn(LOCAL_ID)
31                 whenever(localSone.isLocal).thenReturn(true)
32                 whenever(localSone.identity).thenReturn(localIdentity)
33                 whenever(localIdentity.id).thenReturn(LOCAL_ID)
34                 whenever(remoteSone.id).thenReturn(REMOTE_ID)
35                 whenever(remoteSone.identity).thenReturn(remoteIdentity)
36                 whenever(remoteIdentity.id).thenReturn(REMOTE_ID)
37                 whenever(post.recipientId).thenReturn(Optional.absent())
38         }
39
40         @Test
41         fun `post visibility filter is only created once`() {
42                 val injector = Guice.createInjector()
43                 injector.verifySingletonInstance<PostVisibilityFilter>()
44         }
45
46         @Test
47         fun `post is not visible if it is not loaded`() {
48                 assertThat(postVisibilityFilter.isPostVisible(localSone, post), equalTo(false))
49         }
50
51         @Test
52         fun `loaded post is visible without sone`() {
53                 makePostLoaded(post)
54                 assertThat(postVisibilityFilter.isPostVisible(null, post), equalTo(true))
55         }
56
57         private fun makePostComeFromTheFuture() {
58                 whenever(post.time).thenReturn(System.currentTimeMillis() + 1000)
59         }
60
61         @Test
62         fun `loaded post from the future is not visible`() {
63                 makePostLoaded(post)
64                 makePostComeFromTheFuture()
65                 assertThat(postVisibilityFilter.isPostVisible(null, post), equalTo(false))
66         }
67
68         private fun makePostFromRemoteSone() {
69                 whenever(post.sone).thenReturn(remoteSone)
70         }
71
72         private fun giveRemoteIdentityNegativeExplicitTrust() {
73                 whenever(remoteIdentity.getTrust(localIdentity)).thenReturn(Trust(-1, null, null))
74         }
75
76         @Test
77         fun `loaded post from explicitely not trusted sone is not visible`() {
78                 makePostLoaded(post)
79                 makePostFromRemoteSone()
80                 giveRemoteIdentityNegativeExplicitTrust()
81                 assertThat(postVisibilityFilter.isPostVisible(localSone, post), equalTo(false))
82         }
83
84         private fun giveRemoteIdentityNegativeImplicitTrust() {
85                 whenever(remoteIdentity.getTrust(localIdentity)).thenReturn(Trust(null, -1, null))
86         }
87
88         @Test
89         fun `loaded post from implicitely untrusted sone is not visible`() {
90                 makePostLoaded(post)
91                 makePostFromRemoteSone()
92                 giveRemoteIdentityNegativeImplicitTrust()
93                 assertThat(postVisibilityFilter.isPostVisible(localSone, post), equalTo(false))
94         }
95
96         private fun makeLocalSoneFollowRemoteSone() {
97                 whenever(localSone.hasFriend(REMOTE_ID)).thenReturn(true)
98         }
99
100         private fun giveRemoteIdentityPositiveExplicitTrustButNegativeImplicitTrust() {
101                 whenever(remoteIdentity.getTrust(localIdentity)).thenReturn(Trust(1, -1, null))
102         }
103
104         @Test
105         fun `loaded post from explicitely trusted but implicitely untrusted sone is visible`() {
106                 makePostLoaded(post)
107                 makePostFromRemoteSone()
108                 makeLocalSoneFollowRemoteSone()
109                 giveRemoteIdentityPositiveExplicitTrustButNegativeImplicitTrust()
110                 assertThat(postVisibilityFilter.isPostVisible(localSone, post), equalTo(true))
111         }
112
113         private fun giveTheRemoteIdentityPositiveImplicitTrust() {
114                 whenever(remoteIdentity.getTrust(localIdentity)).thenReturn(Trust(null, 1, null))
115         }
116
117         @Test
118         fun `loaded post from implicitely trusted sone is visible`() {
119                 makePostLoaded(post)
120                 makePostFromRemoteSone()
121                 makeLocalSoneFollowRemoteSone()
122                 giveTheRemoteIdentityPositiveImplicitTrust()
123                 assertThat(postVisibilityFilter.isPostVisible(localSone, post), equalTo(true))
124         }
125
126         private fun giveTheRemoteIdentityUnknownTrust() {
127                 whenever(remoteIdentity.getTrust(localIdentity)).thenReturn(Trust(null, null, null))
128         }
129
130         @Test
131         fun `loaded post from sone with unknown trust is visible`() {
132                 makePostLoaded(post)
133                 makePostFromRemoteSone()
134                 makeLocalSoneFollowRemoteSone()
135                 giveTheRemoteIdentityUnknownTrust()
136                 assertThat(postVisibilityFilter.isPostVisible(localSone, post), equalTo(true))
137         }
138
139         @Test
140         fun `loaded post from unfollowed remote sone that is not directed at local sone is not visible`() {
141                 makePostLoaded(post)
142                 makePostFromRemoteSone()
143                 assertThat(postVisibilityFilter.isPostVisible(localSone, post), equalTo(false))
144         }
145
146         private fun makePostFromLocalSone() {
147                 makePostLoaded(post)
148                 whenever(post.sone).thenReturn(localSone)
149         }
150
151         @Test
152         fun `loaded post from local sone is visible`() {
153                 makePostFromLocalSone()
154                 assertThat(postVisibilityFilter.isPostVisible(localSone, post), equalTo(true))
155         }
156
157         @Test
158         fun `loaded post from followed remote sone that is not directed at local sone is visible`() {
159                 makePostLoaded(post)
160                 makePostFromRemoteSone()
161                 makeLocalSoneFollowRemoteSone()
162                 assertThat(postVisibilityFilter.isPostVisible(localSone, post), equalTo(true))
163         }
164
165         private fun makePostDirectedAtLocalId() {
166                 whenever(post.recipientId).thenReturn(Optional.of(LOCAL_ID))
167         }
168
169         @Test
170         fun `loaded post from remote sone that is directed at local sone is visible`() {
171                 makePostLoaded(post)
172                 makePostFromRemoteSone()
173                 makePostDirectedAtLocalId()
174                 assertThat(postVisibilityFilter.isPostVisible(localSone, post), equalTo(true))
175         }
176
177         @Test
178         fun `predicate will correctly recognize visible post`() {
179                 makePostFromLocalSone()
180                 assertThat(postVisibilityFilter.isVisible(null).apply(post), equalTo(true))
181         }
182
183         @Test
184         fun `predicate will correctly recognize not visible post`() {
185                 assertThat(postVisibilityFilter.isVisible(null).apply(post), equalTo(false))
186         }
187
188 }
189
190 private const val LOCAL_ID = "local-id"
191 private const val REMOTE_ID = "remote-id"
192
193 private fun makePostLoaded(post: Post) {
194         whenever(post.isLoaded).thenReturn(true)
195 }