1 package net.pterodactylus.sone.core
3 import com.google.common.base.Optional.*
4 import net.pterodactylus.sone.core.ConfigurationSoneParser.*
5 import net.pterodactylus.sone.data.*
6 import net.pterodactylus.sone.database.*
7 import net.pterodactylus.sone.test.*
8 import net.pterodactylus.sone.test.Matchers.*
9 import net.pterodactylus.util.config.*
10 import org.hamcrest.MatcherAssert.*
11 import org.hamcrest.Matchers.*
13 import org.junit.rules.*
14 import org.mockito.ArgumentMatchers.*
15 import org.mockito.ArgumentMatchers.eq
18 * Unit test for [ConfigurationSoneParser].
20 class ConfigurationSoneParserTest {
24 val expectedException = ExpectedException.none()!!
26 private val configuration = mock<Configuration>()
27 private val sone = mock<Sone>().apply {
28 whenever(this.id).thenReturn("1")
30 private val configurationSoneParser = ConfigurationSoneParser(configuration, sone)
33 fun emptyProfileIsLoadedCorrectly() {
35 val profile = configurationSoneParser.parseProfile()
36 assertThat(profile, notNullValue())
37 assertThat(profile.firstName, nullValue())
38 assertThat(profile.middleName, nullValue())
39 assertThat(profile.lastName, nullValue())
40 assertThat(profile.birthDay, nullValue())
41 assertThat(profile.birthMonth, nullValue())
42 assertThat(profile.birthYear, nullValue())
43 assertThat(profile.fields, emptyIterable())
46 private fun setupEmptyProfile() {
47 whenever(configuration.getStringValue(anyString())).thenReturn(TestValue.from(null))
48 whenever(configuration.getIntValue(anyString())).thenReturn(TestValue.from(null))
52 fun filledProfileWithFieldsIsParsedCorrectly() {
54 val profile = configurationSoneParser.parseProfile()
55 assertThat(profile, notNullValue())
56 assertThat(profile.firstName, equalTo("First"))
57 assertThat(profile.middleName, equalTo("M."))
58 assertThat(profile.lastName, equalTo("Last"))
59 assertThat(profile.birthDay, equalTo(18))
60 assertThat(profile.birthMonth, equalTo(12))
61 assertThat(profile.birthYear, equalTo(1976))
62 val fields = profile.fields
63 assertThat(fields, hasSize<Any>(2))
64 assertThat(fields[0].name, equalTo("Field1"))
65 assertThat(fields[0].value, equalTo("Value1"))
66 assertThat(fields[1].name, equalTo("Field2"))
67 assertThat(fields[1].value, equalTo("Value2"))
70 private fun setupFilledProfile() {
71 setupString("Sone/1/Profile/FirstName", "First")
72 setupString("Sone/1/Profile/MiddleName", "M.")
73 setupString("Sone/1/Profile/LastName", "Last")
74 setupInteger("Sone/1/Profile/BirthDay", 18)
75 setupInteger("Sone/1/Profile/BirthMonth", 12)
76 setupInteger("Sone/1/Profile/BirthYear", 1976)
77 setupString("Sone/1/Profile/Fields/0/Name", "Field1")
78 setupString("Sone/1/Profile/Fields/0/Value", "Value1")
79 setupString("Sone/1/Profile/Fields/1/Name", "Field2")
80 setupString("Sone/1/Profile/Fields/1/Value", "Value2")
81 setupString("Sone/1/Profile/Fields/2/Name")
84 private fun setupString(nodeName: String, value: String? = null) {
85 whenever(configuration.getStringValue(eq(nodeName))).thenReturn(TestValue.from(value))
88 private fun setupInteger(nodeName: String, value: Int?) {
89 whenever(configuration.getIntValue(eq(nodeName))).thenReturn(TestValue.from(value))
93 fun postsAreParsedCorrectly() {
95 val postBuilderFactory = createPostBuilderFactory()
96 val posts = configurationSoneParser.parsePosts(postBuilderFactory)
97 assertThat(posts, containsInAnyOrder(
98 isPost("P0", 1000L, "T0", null),
99 isPost("P1", 1001L, "T1", "1234567890123456789012345678901234567890123")
103 private fun createPostBuilderFactory(): PostBuilderFactory {
104 val postBuilderFactory = mock<PostBuilderFactory>()
105 whenever(postBuilderFactory.newPostBuilder()).thenAnswer { TestPostBuilder() }
106 return postBuilderFactory
109 private fun setupCompletePosts() {
110 setupPost("0", "P0", 1000L, "T0")
111 setupPost("1", "P1", 1001L, "T1", "1234567890123456789012345678901234567890123")
115 private fun setupPost(postNumber: String, postId: String? = null, time: Long = 0, text: String? = null, recipientId: String? = null) {
116 setupString("Sone/1/Posts/$postNumber/ID", postId)
117 setupLong("Sone/1/Posts/$postNumber/Time", time)
118 setupString("Sone/1/Posts/$postNumber/Text", text)
119 setupString("Sone/1/Posts/$postNumber/Recipient", recipientId)
122 private fun setupLong(nodeName: String, value: Long?) {
123 whenever(configuration.getLongValue(eq(nodeName))).thenReturn(TestValue.from(value))
127 fun postWithoutTimeIsRecognized() {
128 setupPostWithoutTime()
129 expectedException.expect<InvalidPostFound>()
130 configurationSoneParser.parsePosts(createPostBuilderFactory())
133 private fun setupPostWithoutTime() {
134 setupPost("0", "P0", 0L, "T0")
138 fun postWithoutTextIsRecognized() {
139 setupPostWithoutText()
140 expectedException.expect<InvalidPostFound>()
141 configurationSoneParser.parsePosts(createPostBuilderFactory())
144 private fun setupPostWithoutText() {
145 setupPost("0", "P0", 1000L)
149 fun postWithInvalidRecipientIdIsRecognized() {
150 setupPostWithInvalidRecipientId()
151 val posts = configurationSoneParser.parsePosts(createPostBuilderFactory())
152 assertThat(posts, contains(isPost("P0", 1000L, "T0", null)))
155 private fun setupPostWithInvalidRecipientId() {
156 setupPost("0", "P0", 1000L, "T0", "123")
161 fun postRepliesAreParsedCorrectly() {
163 val postReplyBuilderFactory = object : PostReplyBuilderFactory {
164 override fun newPostReplyBuilder(): PostReplyBuilder {
165 return TestPostReplyBuilder()
168 val postReplies = configurationSoneParser.parsePostReplies(postReplyBuilderFactory)
169 assertThat(postReplies, hasSize(2))
170 assertThat(postReplies, containsInAnyOrder(
171 isPostReply("R0", "P0", 1000L, "T0"),
172 isPostReply("R1", "P1", 1001L, "T1")
176 private fun setupPostReplies() {
177 setupPostReply("0", "R0", "P0", 1000L, "T0")
178 setupPostReply("1", "R1", "P1", 1001L, "T1")
182 private fun setupPostReply(postReplyNumber: String, postReplyId: String? = null, postId: String? = null, time: Long = 0, text: String? = null) {
183 setupString("Sone/1/Replies/$postReplyNumber/ID", postReplyId)
184 setupString("Sone/1/Replies/$postReplyNumber/Post/ID", postId)
185 setupLong("Sone/1/Replies/$postReplyNumber/Time", time)
186 setupString("Sone/1/Replies/$postReplyNumber/Text", text)
190 fun missingPostIdIsRecognized() {
191 setupPostReplyWithMissingPostId()
192 expectedException.expect<InvalidPostReplyFound>()
193 configurationSoneParser.parsePostReplies(null)
196 private fun setupPostReplyWithMissingPostId() {
197 setupPostReply("0", "R0", null, 1000L, "T0")
201 fun missingPostReplyTimeIsRecognized() {
202 setupPostReplyWithMissingPostReplyTime()
203 expectedException.expect<InvalidPostReplyFound>()
204 configurationSoneParser.parsePostReplies(null)
207 private fun setupPostReplyWithMissingPostReplyTime() {
208 setupPostReply("0", "R0", "P0", 0L, "T0")
212 fun missingPostReplyTextIsRecognized() {
213 setupPostReplyWithMissingPostReplyText()
214 expectedException.expect<InvalidPostReplyFound>()
215 configurationSoneParser.parsePostReplies(null)
218 private fun setupPostReplyWithMissingPostReplyText() {
219 setupPostReply("0", "R0", "P0", 1000L)
223 fun likedPostIdsParsedCorrectly() {
225 val likedPostIds = configurationSoneParser.parseLikedPostIds()
226 assertThat(likedPostIds, containsInAnyOrder("P1", "P2", "P3"))
229 private fun setupLikedPostIds() {
230 setupString("Sone/1/Likes/Post/0/ID", "P1")
231 setupString("Sone/1/Likes/Post/1/ID", "P2")
232 setupString("Sone/1/Likes/Post/2/ID", "P3")
233 setupString("Sone/1/Likes/Post/3/ID")
237 fun likedPostReplyIdsAreParsedCorrectly() {
238 setupLikedPostReplyIds()
239 val likedPostReplyIds = configurationSoneParser.parseLikedPostReplyIds()
240 assertThat(likedPostReplyIds, containsInAnyOrder("R1", "R2", "R3"))
243 private fun setupLikedPostReplyIds() {
244 setupString("Sone/1/Likes/Reply/0/ID", "R1")
245 setupString("Sone/1/Likes/Reply/1/ID", "R2")
246 setupString("Sone/1/Likes/Reply/2/ID", "R3")
247 setupString("Sone/1/Likes/Reply/3/ID")
251 fun friendsAreParsedCorrectly() {
253 val friends = configurationSoneParser.parseFriends()
254 assertThat(friends, containsInAnyOrder("F1", "F2", "F3"))
257 private fun setupFriends() {
258 setupString("Sone/1/Friends/0/ID", "F1")
259 setupString("Sone/1/Friends/1/ID", "F2")
260 setupString("Sone/1/Friends/2/ID", "F3")
261 setupString("Sone/1/Friends/3/ID")
265 fun topLevelAlbumsAreParsedCorrectly() {
266 setupTopLevelAlbums()
267 val albumBuilderFactory = createAlbumBuilderFactory()
268 val topLevelAlbums = configurationSoneParser.parseTopLevelAlbums(albumBuilderFactory)
269 assertThat(topLevelAlbums, hasSize<Any>(2))
270 val firstAlbum = topLevelAlbums[0]
271 assertThat(firstAlbum, isAlbum("A1", null, "T1", "D1"))
272 assertThat(firstAlbum.albums, emptyIterable<Any>())
273 assertThat<List<Image>>(firstAlbum.images, emptyIterable<Any>())
274 val secondAlbum = topLevelAlbums[1]
275 assertThat(secondAlbum, isAlbum("A2", null, "T2", "D2"))
276 assertThat(secondAlbum.albums, hasSize<Any>(1))
277 assertThat<List<Image>>(secondAlbum.images, emptyIterable<Any>())
278 val thirdAlbum = secondAlbum.albums[0]
279 assertThat(thirdAlbum, isAlbum("A3", "A2", "T3", "D3"))
280 assertThat(thirdAlbum.albums, emptyIterable<Any>())
281 assertThat<List<Image>>(thirdAlbum.images, emptyIterable<Any>())
284 private fun setupTopLevelAlbums() {
285 setupAlbum(0, "A1", null, "T1", "D1", "I1")
286 setupAlbum(1, "A2", null, "T2", "D2")
287 setupAlbum(2, "A3", "A2", "T3", "D3", "I3")
291 private fun setupAlbum(albumNumber: Int, albumId: String? = null, parentAlbumId: String? = null, title: String? = null, description: String? = null, imageId: String? =null) {
292 val albumPrefix = "Sone/1/Albums/$albumNumber"
293 setupString("$albumPrefix/ID", albumId)
294 setupString("$albumPrefix/Title", title)
295 setupString("$albumPrefix/Description", description)
296 setupString("$albumPrefix/Parent", parentAlbumId)
297 setupString("$albumPrefix/AlbumImage", imageId)
300 private fun createAlbumBuilderFactory(): AlbumBuilderFactory {
301 val albumBuilderFactory = mock<AlbumBuilderFactory>()
302 whenever(albumBuilderFactory.newAlbumBuilder()).thenAnswer { TestAlbumBuilder() }
303 return albumBuilderFactory
307 fun albumWithInvalidTitleIsRecognized() {
308 setupAlbum(0, "A1", null, null, "D1", "I1")
309 expectedException.expect<InvalidAlbumFound>()
310 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
314 fun albumWithInvalidDescriptionIsRecognized() {
315 setupAlbum(0, "A1", null, "T1", null, "I1")
316 expectedException.expect<InvalidAlbumFound>()
317 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
321 fun albumWithInvalidParentIsRecognized() {
322 setupAlbum(0, "A1", "A0", "T1", "D1", "I1")
323 expectedException.expect<InvalidParentAlbumFound>()
324 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
328 fun imagesAreParsedCorrectly() {
329 setupTopLevelAlbums()
330 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
332 configurationSoneParser.parseImages(createImageBuilderFactory())
333 val albums = configurationSoneParser.albums
334 assertThat<List<Image>>(albums["A1"]!!.images, contains<Image>(isImage("I1", 1000L, "K1", "T1", "D1", 16, 9)))
335 assertThat<List<Image>>(albums["A2"]!!.images, contains<Image>(isImage("I2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2)))
336 assertThat<List<Image>>(albums["A3"]!!.images, contains<Image>(isImage("I3", 3000L, "K3", "T3", "D3", 16 * 3, 9 * 3)))
339 private fun setupImages() {
340 setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, 9)
341 setupImage(1, "I2", "A2", 2000L, "K2", "T2", "D2", 16 * 2, 9 * 2)
342 setupImage(2, "I3", "A3", 3000L, "K3", "T3", "D3", 16 * 3, 9 * 3)
343 setupImage(3, null, null, 0L, null, null, null, 0, 0)
346 private fun setupImage(imageNumber: Int, id: String?, parentAlbumId: String?, creationTime: Long?, key: String?, title: String?, description: String?, width: Int?, height: Int?) {
347 val imagePrefix = "Sone/1/Images/$imageNumber"
348 setupString("$imagePrefix/ID", id)
349 setupString("$imagePrefix/Album", parentAlbumId)
350 setupLong("$imagePrefix/CreationTime", creationTime)
351 setupString("$imagePrefix/Key", key)
352 setupString("$imagePrefix/Title", title)
353 setupString("$imagePrefix/Description", description)
354 setupInteger("$imagePrefix/Width", width)
355 setupInteger("$imagePrefix/Height", height)
358 private fun createImageBuilderFactory(): ImageBuilderFactory {
359 val imageBuilderFactory = mock<ImageBuilderFactory>()
360 whenever(imageBuilderFactory.newImageBuilder()).thenAnswer { TestImageBuilder() }
361 return imageBuilderFactory
365 fun missingAlbumIdIsRecognized() {
366 setupTopLevelAlbums()
367 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
368 setupImage(0, "I1", null, 1000L, "K1", "T1", "D1", 16, 9)
369 expectedException.expect<InvalidImageFound>()
370 configurationSoneParser.parseImages(createImageBuilderFactory())
374 fun invalidAlbumIdIsRecognized() {
375 setupTopLevelAlbums()
376 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
377 setupImage(0, "I1", "A4", 1000L, "K1", "T1", "D1", 16, 9)
378 expectedException.expect<InvalidParentAlbumFound>()
379 configurationSoneParser.parseImages(createImageBuilderFactory())
383 fun missingCreationTimeIsRecognized() {
384 setupTopLevelAlbums()
385 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
386 setupImage(0, "I1", "A1", null, "K1", "T1", "D1", 16, 9)
387 expectedException.expect<InvalidImageFound>()
388 configurationSoneParser.parseImages(createImageBuilderFactory())
392 fun missingKeyIsRecognized() {
393 setupTopLevelAlbums()
394 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
395 setupImage(0, "I1", "A1", 1000L, null, "T1", "D1", 16, 9)
396 expectedException.expect<InvalidImageFound>()
397 configurationSoneParser.parseImages(createImageBuilderFactory())
401 fun missingTitleIsRecognized() {
402 setupTopLevelAlbums()
403 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
404 setupImage(0, "I1", "A1", 1000L, "K1", null, "D1", 16, 9)
405 expectedException.expect<InvalidImageFound>()
406 configurationSoneParser.parseImages(createImageBuilderFactory())
410 fun missingDescriptionIsRecognized() {
411 setupTopLevelAlbums()
412 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
413 setupImage(0, "I1", "A1", 1000L, "K1", "T1", null, 16, 9)
414 expectedException.expect<InvalidImageFound>()
415 configurationSoneParser.parseImages(createImageBuilderFactory())
419 fun missingWidthIsRecognized() {
420 setupTopLevelAlbums()
421 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
422 setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", null, 9)
423 expectedException.expect<InvalidImageFound>()
424 configurationSoneParser.parseImages(createImageBuilderFactory())
428 fun missingHeightIsRecognized() {
429 setupTopLevelAlbums()
430 configurationSoneParser.parseTopLevelAlbums(createAlbumBuilderFactory())
431 setupImage(0, "I1", "A1", 1000L, "K1", "T1", "D1", 16, null)
432 expectedException.expect<InvalidImageFound>()
433 configurationSoneParser.parseImages(createImageBuilderFactory())