1 package net.pterodactylus.sone.fcp
3 import com.google.common.base.Optional
4 import com.google.common.base.Optional.absent
5 import freenet.support.SimpleFieldSet
6 import net.pterodactylus.sone.core.Core
7 import net.pterodactylus.sone.data.Post
8 import net.pterodactylus.sone.data.PostReply
9 import net.pterodactylus.sone.data.Profile
10 import net.pterodactylus.sone.data.Sone
11 import net.pterodactylus.sone.freenet.fcp.FcpException
12 import net.pterodactylus.sone.template.SoneAccessor
13 import net.pterodactylus.sone.test.OneByOneMatcher
14 import net.pterodactylus.sone.test.mock
15 import net.pterodactylus.sone.test.whenever
16 import net.pterodactylus.sone.utils.asOptional
17 import org.junit.Before
19 import org.junit.rules.ExpectedException
20 import org.mockito.ArgumentMatchers.anyString
23 * Base class for Sone FCP command tests.
25 abstract class SoneCommandTest {
27 @Rule @JvmField val expectedException = ExpectedException.none()!!
29 protected val core = mock<Core>()
30 protected val command: AbstractSoneCommand by lazy { createCommand(core) }
32 protected val parameters = SimpleFieldSet(true)
33 protected val localSone = mock<Sone>().apply {
34 whenever(isLocal).thenReturn(true)
36 protected val remoteSone = mock<Sone>()
38 protected abstract fun createCommand(core: Core): AbstractSoneCommand
42 whenever(core.getSone(anyString())).thenReturn(absent())
43 whenever(core.getPost(anyString())).thenReturn(absent())
44 whenever(core.getPostReply(anyString())).thenReturn(absent())
47 protected fun createSone(id: String, name: String, firstName: String, lastName: String, time: Long) = mock<Sone>().apply {
48 whenever(this.id).thenReturn(id)
49 whenever(this.name).thenReturn(name)
50 whenever(profile).thenReturn(Profile(this).apply {
51 this.firstName = firstName
52 this.lastName = lastName
54 whenever(this.time).thenReturn(time)
57 protected fun createPost(id: String, sone: Sone, recipientId: String?, time: Long, text: String) = mock<Post>().apply {
58 whenever(this.id).thenReturn(id)
59 whenever(this.sone).thenReturn(sone)
60 whenever(this.recipientId).thenReturn(recipientId.asOptional())
61 whenever(this.time).thenReturn(time)
62 whenever(this.text).thenReturn(text)
65 protected fun createReply(id: String, sone: Sone, post: Post, time: Long, text: String) = mock<PostReply>().apply {
66 whenever(this.id).thenReturn(id)
67 whenever(this.sone).thenReturn(sone)
68 whenever(this.post).thenReturn(post.asOptional())
69 whenever(this.time).thenReturn(time)
70 whenever(this.text).thenReturn(text)
73 protected fun executeCommandAndExpectFcpException() {
74 expectedException.expect(FcpException::class.java)
75 command.execute(parameters)
78 protected fun requestWithoutAnyParameterResultsInFcpException() {
79 expectedException.expect(FcpException::class.java)
80 command.execute(parameters)
83 protected fun requestWithEmptySoneParameterResultsInFcpException() {
84 parameters += "Sone" to null
85 executeCommandAndExpectFcpException()
88 protected fun requestWithInvalidSoneParameterResultsInFcpException() {
89 parameters += "Sone" to "InvalidSoneId"
90 executeCommandAndExpectFcpException()
93 fun requestWithValidRemoteSoneParameterResultsInFcpException() {
94 parameters += "Sone" to "RemoteSoneId"
95 whenever(core.getSone("RemoteSoneId")).thenReturn(Optional.of(remoteSone))
96 executeCommandAndExpectFcpException()
99 protected operator fun SimpleFieldSet.plusAssign(keyValue: Pair<String, String?>) = putSingle(keyValue.first, keyValue.second)
100 protected fun SimpleFieldSet.parsePost(prefix: String) = parseFromSimpleFieldSet(prefix, "ID", "Sone", "Recipient", "Time", "Text")
101 protected fun SimpleFieldSet.parseReply(prefix: String) = parseFromSimpleFieldSet(prefix, "ID", "Sone", "Time", "Text")
102 protected fun SimpleFieldSet.parseSone(prefix: String) = parseFromSimpleFieldSet(prefix, "ID", "Name", "NiceName", "LastUpdated", "Followed") +
103 (0 until this["${prefix}Field.Count"].toInt()).map {
104 ("Field." + this["${prefix}Field.$it.Name"]) to this["${prefix}Field.$it.Value"]
107 private fun SimpleFieldSet.parseFromSimpleFieldSet(prefix: String, vararg fields: String): Map<String, String?> = fields
108 .associate { it to get(prefix + it) }
110 protected fun matchesPost(post: Post) = OneByOneMatcher<Map<String, String?>>().apply {
111 expect("ID", post.id) { it["ID"] }
112 expect("Sone", post.sone.id) { it["Sone"] }
113 expect("recipient", post.recipientId.orNull()) { it["Recipient"] }
114 expect("time", post.time.toString()) { it["Time"] }
115 expect("text", post.text.replace("\\", "\\\\").replace("\r", "\\r").replace("\n", "\\n")) { it["Text"] }
118 protected fun matchesReply(reply: PostReply) = OneByOneMatcher<Map<String, String?>>().apply {
119 expect("ID", reply.id) { it["ID"] }
120 expect("Sone", reply.sone.id) { it["Sone"] }
121 expect("time", reply.time.toString()) { it["Time"] }
122 expect("text", reply.text.replace("\\", "\\\\").replace("\r", "\\r").replace("\n", "\\n")) { it["Text"] }
125 protected fun matchesSone(sone: Sone) = OneByOneMatcher<Map<String, String?>>().apply {
126 expect("ID", sone.id) { it["ID"] }
127 expect("name", sone.name) { it["Name"] }
128 expect("last updated", sone.time.toString()) { it["LastUpdated"] }
129 expect("nice name", SoneAccessor.getNiceName(sone)) { it["NiceName"] }
130 sone.profile.fields.forEach { field ->
131 expect("field: ${field.name}", field.value) { it["Field.${field.name}"] }