Browse Source

Add structured send methods

tags/v0.10.0
Chris Smith 5 years ago
parent
commit
e91342edc9

+ 6
- 0
CHANGELOG View File

@@ -3,6 +3,12 @@ vNEXT (in development)
3 3
  * Batch start and end events are no longer included in BatchReceived events
4 4
  * Batches now expose complete metadata from their start event
5 5
  * Added support for labelled-replies capability and label message tags
6
+ * Added new methods for sending raw lines to the IRC server
7
+   * send(tagMap(...), command, arguments) replaces send(line)
8
+   * send(command, arguments) is available if no tags are to be sent
9
+   * the line is built automatically (with spaces/' :' added appropriately)
10
+   * send(line) is deprecated and will be removed after v1.0.0
11
+ * (Internal) Added annotation to track removal of deprecated methods
6 12
 
7 13
 v0.9.0
8 14
 

+ 26
- 0
src/main/kotlin/com/dmdirc/ktirc/IrcClient.kt View File

@@ -4,6 +4,7 @@ import com.dmdirc.ktirc.events.IrcEvent
4 4
 import com.dmdirc.ktirc.io.CaseMapping
5 5
 import com.dmdirc.ktirc.messages.sendJoin
6 6
 import com.dmdirc.ktirc.model.*
7
+import com.dmdirc.ktirc.util.RemoveIn
7 8
 
8 9
 /**
9 10
  * Primary interface for interacting with KtIrc.
@@ -54,8 +55,33 @@ interface IrcClient {
54 55
      *
55 56
      * @param message The line to be sent to the IRC server.
56 57
      */
58
+    @Deprecated("Use structured send instead", ReplaceWith("send(command, arguments)"))
59
+    @RemoveIn("2.0.0")
57 60
     fun send(message: String)
58 61
 
62
+    /**
63
+     * Sends the given command to the IRC server.
64
+     *
65
+     * This should only be needed to send raw/custom commands; standard messages can be sent using the
66
+     * extension methods in [com.dmdirc.ktirc.messages] such as [sendJoin].
67
+     *
68
+     * @param tags The IRCv3 tags to prefix the message with, if any.
69
+     * @param command The command to be sent
70
+     * @param arguments The arguments to the command.
71
+     */
72
+    fun send(tags: Map<MessageTag, String>, command: String, vararg arguments: String)
73
+
74
+    /**
75
+     * Sends the given command to the IRC server.
76
+     *
77
+     * This should only be needed to send raw/custom commands; standard messages can be sent using the
78
+     * extension methods in [com.dmdirc.ktirc.messages] such as [sendJoin].
79
+     *
80
+     * @param command The command to be sent
81
+     * @param arguments The arguments to the command.
82
+     */
83
+    fun send(command: String, vararg arguments: String) = send(emptyMap(), command, *arguments)
84
+
59 85
     /**
60 86
      * Registers a new handler for all events on this connection.
61 87
      *

+ 12
- 11
src/main/kotlin/com/dmdirc/ktirc/IrcClientImpl.kt View File

@@ -40,6 +40,7 @@ internal class IrcClientImpl(private val config: IrcClientConfig) : IrcClient, C
40 40
     override val userState = UserState { caseMapping }
41 41
 
42 42
     private val messageHandler = MessageHandler(messageProcessors, eventMutators, eventHandlers)
43
+    private val messageBuilder = MessageBuilder()
43 44
 
44 45
     private val parser = MessageParser()
45 46
     private var socket: LineBufferedSocket? = null
@@ -50,20 +51,20 @@ internal class IrcClientImpl(private val config: IrcClientConfig) : IrcClient, C
50 51
         socket?.sendChannel?.offer(message.toByteArray()) ?: log.warning { "No send channel for message: $message" }
51 52
     }
52 53
 
54
+    override fun send(tags: Map<MessageTag, String>, command: String, vararg arguments: String) {
55
+        socket?.sendChannel?.offer(messageBuilder.build(tags, command, arguments))
56
+                ?: log.warning { "No send channel for command: $command" }
57
+    }
58
+
53 59
     // TODO: This will become sendAsync and return a Deferred<IrcEvent>
54
-    // TODO: Refactor so that send takes a map of tags and arguments; build the string separately
55
-    internal fun sendWithLabel(message: String) {
56
-        val messageToSend = if (Capability.LabeledResponse in serverState.capabilities.enabledCapabilities) {
57
-            val label = generateLabel(this)
58
-            "@draft/label=$label" + if (message.startsWith('@')) {
59
-                ";${message.substring(1)}"
60
-            } else {
61
-                " $message"
62
-            }
60
+    internal fun sendWithLabel(tags: Map<MessageTag, String>, command: String, vararg arguments: String) {
61
+        val tagseToSend = if (Capability.LabeledResponse in serverState.capabilities.enabledCapabilities) {
62
+            tags + (MessageTag.Label to generateLabel(this))
63 63
         } else {
64
-            message
64
+            tags
65 65
         }
66
-        socket?.sendChannel?.offer(messageToSend.toByteArray()) ?: log.warning { "No send channel for message: $message" }
66
+        socket?.sendChannel?.offer(messageBuilder.build(tagseToSend, command, arguments))
67
+                ?: log.warning { "No send channel for command: $command" }
67 68
     }
68 69
 
69 70
     override fun connect() {

+ 7
- 3
src/main/kotlin/com/dmdirc/ktirc/events/Events.kt View File

@@ -4,6 +4,7 @@ import com.dmdirc.ktirc.model.Capability
4 4
 import com.dmdirc.ktirc.model.ConnectionError
5 5
 import com.dmdirc.ktirc.model.ServerFeatureMap
6 6
 import com.dmdirc.ktirc.model.User
7
+import com.dmdirc.ktirc.util.RemoveIn
7 8
 import java.time.LocalDateTime
8 9
 
9 10
 /**
@@ -24,7 +25,8 @@ data class EventMetadata(
24 25
 sealed class IrcEvent(val metadata: EventMetadata) {
25 26
 
26 27
     /** The time at which the event occurred. */
27
-    @Deprecated("Moved to metadata; to be removed post-1.0.0", replaceWith = ReplaceWith("metadata.time"))
28
+    @Deprecated("Moved to metadata", replaceWith = ReplaceWith("metadata.time"))
29
+    @RemoveIn("2.0.0")
28 30
     val time: LocalDateTime
29 31
         get() = metadata.time
30 32
 
@@ -92,7 +94,8 @@ class ChannelTopicChanged(metadata: EventMetadata, val user: User, val channel:
92 94
 class MessageReceived(metadata: EventMetadata, val user: User, val target: String, val message: String) : IrcEvent(metadata) {
93 95
 
94 96
     /** The message ID of this message. */
95
-    @Deprecated("Moved to metadata; to be removed post-1.0.0", replaceWith = ReplaceWith("metadata.messageId"))
97
+    @Deprecated("Moved to metadata", replaceWith = ReplaceWith("metadata.messageId"))
98
+    @RemoveIn("2.0.0")
96 99
     val messageId: String?
97 100
         get() = metadata.messageId
98 101
 
@@ -109,7 +112,8 @@ class NoticeReceived(metadata: EventMetadata, val user: User, val target: String
109 112
 class ActionReceived(metadata: EventMetadata, val user: User, val target: String, val action: String) : IrcEvent(metadata) {
110 113
 
111 114
     /** The message ID of this action. */
112
-    @Deprecated("Moved to metadata; to be removed post-1.0.0", replaceWith = ReplaceWith("metadata.messageId"))
115
+    @Deprecated("Moved to metadata", replaceWith = ReplaceWith("metadata.messageId"))
116
+    @RemoveIn("2.0.0")
113 117
     val messageId: String?
114 118
         get() = metadata.messageId
115 119
 

+ 41
- 0
src/main/kotlin/com/dmdirc/ktirc/messages/MessageBuilder.kt View File

@@ -0,0 +1,41 @@
1
+package com.dmdirc.ktirc.messages
2
+
3
+import com.dmdirc.ktirc.model.MessageTag
4
+
5
+internal class MessageBuilder {
6
+
7
+    fun build(tags: Map<MessageTag, String>, command: String, arguments: Array<out String>) =
8
+            // TODO: Check line length
9
+            buildString {
10
+                append(tags.toPrefix())
11
+                append(command)
12
+                append(arguments.toSuffix())
13
+            }.toByteArray()
14
+
15
+    private fun Map<MessageTag, String>.toPrefix() = when {
16
+        isEmpty() -> ""
17
+        // TODO: Check if the server actually understands tags here
18
+        // TODO: Check maximum length of tags
19
+        else ->
20
+            map { "${it.key.name}=${it.value.escapeTagValue()}" }
21
+                    .joinToString(separator = ";", prefix = "@", postfix = " ")
22
+    }
23
+
24
+    private fun Array<out String>.toSuffix() = when (size) {
25
+        0 -> ""
26
+        1 -> this[0].asLastParam()
27
+        else -> dropLast(1).joinToString(separator = " ", prefix = " ") + last().asLastParam()
28
+    }
29
+
30
+    private fun String.asLastParam() = when {
31
+        contains(' ') || startsWith(':') -> " :$this"
32
+        else -> " $this"
33
+    }
34
+
35
+    private fun String.escapeTagValue() = replace("\\", "\\\\")
36
+            .replace("\n", "\\n")
37
+            .replace("\r", "\\r")
38
+            .replace(";", "\\:")
39
+            .replace(" ", "\\s")
40
+
41
+}

+ 18
- 29
src/main/kotlin/com/dmdirc/ktirc/messages/MessageBuilders.kt View File

@@ -4,28 +4,28 @@ import com.dmdirc.ktirc.IrcClient
4 4
 import com.dmdirc.ktirc.model.MessageTag
5 5
 
6 6
 /** Sends a message to ask the server to list capabilities. */
7
-internal fun IrcClient.sendCapabilityList() = send("CAP LS 302")
7
+internal fun IrcClient.sendCapabilityList() = send("CAP", "LS", "302")
8 8
 
9 9
 /** Sends a message indicating the end of capability negotiation. */
10
-internal fun IrcClient.sendCapabilityEnd() = send("CAP END")
10
+internal fun IrcClient.sendCapabilityEnd() = send("CAP", "END")
11 11
 
12 12
 /** Sends a message requesting the specified caps are enabled. */
13
-internal fun IrcClient.sendCapabilityRequest(capabilities: List<String>) = send("CAP REQ :${capabilities.joinToString(" ")}")
13
+internal fun IrcClient.sendCapabilityRequest(capabilities: List<String>) = send("CAP", "REQ", capabilities.joinToString(" "))
14 14
 
15 15
 /** Sends a request to join the given channel. */
16
-fun IrcClient.sendJoin(channel: String) = send("JOIN :$channel")
16
+fun IrcClient.sendJoin(channel: String) = send("JOIN", channel)
17 17
 
18 18
 /** Sends a request to see the modes of a given target. */
19
-fun IrcClient.sendModeRequest(target: String) = send("MODE :$target")
19
+fun IrcClient.sendModeRequest(target: String) = send("MODE", target)
20 20
 
21 21
 /** Sends a request to change to the given nickname. */
22
-fun IrcClient.sendNickChange(nick: String) = send("NICK :$nick")
22
+fun IrcClient.sendNickChange(nick: String) = send("NICK", nick)
23 23
 
24 24
 /** Sends the connection password to the server. */
25
-internal fun IrcClient.sendPassword(password: String) = send("PASS :$password")
25
+internal fun IrcClient.sendPassword(password: String) = send("PASS", password)
26 26
 
27 27
 /** Sends a response to a PING event. */
28
-internal fun IrcClient.sendPong(nonce: ByteArray) = send("PONG :${String(nonce)}")
28
+internal fun IrcClient.sendPong(nonce: ByteArray) = send("PONG", String(nonce))
29 29
 
30 30
 /** Sends a CTCP message of the specified [type] and with optional [data] to [target] (a user or a channel). */
31 31
 fun IrcClient.sendCtcp(target: String, type: String, data: String? = null) =
@@ -36,7 +36,11 @@ fun IrcClient.sendAction(target: String, action: String) = sendCtcp(target, "ACT
36 36
 
37 37
 /** Sends a private message to a user or channel. */
38 38
 fun IrcClient.sendMessage(target: String, message: String, inReplyTo: String? = null) =
39
-        sendWithTags(mapOf(MessageTag.Reply to inReplyTo), "PRIVMSG $target :$message")
39
+        send(
40
+                inReplyTo?.let { tagMap(MessageTag.Reply to inReplyTo) } ?: emptyMap(),
41
+                "PRIVMSG",
42
+                target,
43
+                message)
40 44
 
41 45
 /**
42 46
  * Sends a tag-only message.
@@ -44,31 +48,16 @@ fun IrcClient.sendMessage(target: String, message: String, inReplyTo: String? =
44 48
  * If [inReplyTo] is specified then the [MessageTag.Reply] tag will be automatically added.
45 49
  */
46 50
 fun IrcClient.sendTagMessage(target: String, tags: Map<MessageTag, String>, inReplyTo: String? = null) {
47
-    sendWithTags(inReplyTo?.let { tags + (MessageTag.Reply to inReplyTo) } ?: tags, "TAGMSG $target")
51
+    send(inReplyTo?.let { tags + (MessageTag.Reply to inReplyTo) } ?: tags, "TAGMSG", target)
48 52
 }
49 53
 
50 54
 /** Sends a message to register a user with the server. */
51
-internal fun IrcClient.sendUser(userName: String, realName: String) = send("USER $userName 0 * :$realName")
55
+internal fun IrcClient.sendUser(userName: String, realName: String) = send("USER", userName, "0", "*", realName)
52 56
 
53 57
 /** Starts an authentication request. */
54
-internal fun IrcClient.sendAuthenticationMessage(data: String = "+") = send("AUTHENTICATE $data")
58
+internal fun IrcClient.sendAuthenticationMessage(data: String = "+") = send("AUTHENTICATE", data)
55 59
 
56 60
 /**
57
- * Sends a message prefixed with some IRCv3 tags.
58
- *
59
- * For convenience, if the value of a tag is `null`, the tag will be omitted. If no tags are present the
60
- * message is sent directly with no prefix.
61
+ * Utility method for creating a map of tags to avoid type inference problems.
61 62
  */
62
-internal fun IrcClient.sendWithTags(tags: Map<MessageTag, String?>, message: String) = tags
63
-        .filterValues { it != null }
64
-        .map { (key, value) -> "${key.name}=${value?.escapeTagValue()}" }
65
-        .joinToString(";")
66
-        .let {
67
-            if (it.isEmpty()) send(message) else send("@$it $message")
68
-        }
69
-
70
-internal fun String.escapeTagValue() = replace("\\", "\\\\")
71
-        .replace("\n", "\\n")
72
-        .replace("\r", "\\r")
73
-        .replace(";", "\\:")
74
-        .replace(" ", "\\s")
63
+fun tagMap(vararg tags: Pair<MessageTag, String>) = mapOf(*tags)

+ 10
- 0
src/main/kotlin/com/dmdirc/ktirc/util/RemoveIn.kt View File

@@ -0,0 +1,10 @@
1
+package com.dmdirc.ktirc.util
2
+
3
+/**
4
+ * Documents when a deprecated feature will be removed.
5
+ */
6
+@MustBeDocumented
7
+@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.ANNOTATION_CLASS,
8
+        AnnotationTarget.CONSTRUCTOR, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.PROPERTY_GETTER,
9
+        AnnotationTarget.TYPEALIAS)
10
+annotation class RemoveIn(val version: String)

+ 30
- 7
src/test/kotlin/com/dmdirc/ktirc/IrcClientImplTest.kt View File

@@ -3,6 +3,7 @@ package com.dmdirc.ktirc
3 3
 import com.dmdirc.ktirc.events.*
4 4
 import com.dmdirc.ktirc.io.CaseMapping
5 5
 import com.dmdirc.ktirc.io.LineBufferedSocket
6
+import com.dmdirc.ktirc.messages.tagMap
6 7
 import com.dmdirc.ktirc.model.*
7 8
 import com.dmdirc.ktirc.util.currentTimeProvider
8 9
 import com.dmdirc.ktirc.util.generateLabel
@@ -122,7 +123,7 @@ internal class IrcClientImplTest {
122 123
         client.connect()
123 124
 
124 125
         assertEquals("CAP LS 302", String(sendLineChannel.receive()))
125
-        assertEquals("NICK :$NICK", String(sendLineChannel.receive()))
126
+        assertEquals("NICK $NICK", String(sendLineChannel.receive()))
126 127
         assertEquals("USER $USER_NAME 0 * :$REAL_NAME", String(sendLineChannel.receive()))
127 128
     }
128 129
 
@@ -137,7 +138,7 @@ internal class IrcClientImplTest {
137 138
         client.connect()
138 139
 
139 140
         assertEquals("CAP LS 302", String(sendLineChannel.receive()))
140
-        assertEquals("PASS :$PASSWORD", String(sendLineChannel.receive()))
141
+        assertEquals("PASS $PASSWORD", String(sendLineChannel.receive()))
141 142
     }
142 143
 
143 144
     @Test
@@ -199,13 +200,35 @@ internal class IrcClientImplTest {
199 200
         assertLineReceived("testing 123")
200 201
     }
201 202
 
203
+    @Test
204
+    fun `sends structured text to socket`() = runBlocking {
205
+        val client = IrcClientImpl(normalConfig)
206
+        client.socketFactory = mockSocketFactory
207
+        client.connect()
208
+
209
+        client.send("testing", "123", "456")
210
+
211
+        assertLineReceived("testing 123 456")
212
+    }
213
+
214
+    @Test
215
+    fun `sends structured text to socket with tags`() = runBlocking {
216
+        val client = IrcClientImpl(normalConfig)
217
+        client.socketFactory = mockSocketFactory
218
+        client.connect()
219
+
220
+        client.send(tagMap(MessageTag.AccountName to "acidB"), "testing", "123", "456")
221
+
222
+        assertLineReceived("@account=acidB testing 123 456")
223
+    }
224
+
202 225
     @Test
203 226
     fun `sends text to socket without label if cap is missing`() = runBlocking {
204 227
         val client = IrcClientImpl(normalConfig)
205 228
         client.socketFactory = mockSocketFactory
206 229
         client.connect()
207 230
 
208
-        client.sendWithLabel("testing 123")
231
+        client.sendWithLabel(tagMap(), "testing", "123")
209 232
 
210 233
         assertLineReceived("testing 123")
211 234
     }
@@ -218,7 +241,7 @@ internal class IrcClientImplTest {
218 241
         client.serverState.capabilities.enabledCapabilities[Capability.LabeledResponse] = ""
219 242
         client.connect()
220 243
 
221
-        client.sendWithLabel("testing 123")
244
+        client.sendWithLabel(tagMap(), "testing", "123")
222 245
 
223 246
         assertLineReceived("@draft/label=abc123 testing 123")
224 247
     }
@@ -231,9 +254,9 @@ internal class IrcClientImplTest {
231 254
         client.serverState.capabilities.enabledCapabilities[Capability.LabeledResponse] = ""
232 255
         client.connect()
233 256
 
234
-        client.sendWithLabel("@+test=x testing 123")
257
+        client.sendWithLabel(tagMap(MessageTag.AccountName to "x"), "testing", "123")
235 258
 
236
-        assertLineReceived("@draft/label=abc123;+test=x testing 123")
259
+        assertLineReceived("@account=x;draft/label=abc123 testing 123")
237 260
     }
238 261
 
239 262
     @Test
@@ -254,7 +277,7 @@ internal class IrcClientImplTest {
254 277
         client.socketFactory = mockSocketFactory
255 278
         client.connect()
256 279
 
257
-        (0..100).forEach { client.send("TEST $it") }
280
+        (0..100).forEach { client.send("TEST", "$it") }
258 281
 
259 282
         assertEquals(100, withTimeoutOrNull(500) {
260 283
             var next = 0

+ 10
- 12
src/test/kotlin/com/dmdirc/ktirc/events/EventUtilsTest.kt View File

@@ -3,10 +3,8 @@ package com.dmdirc.ktirc.events
3 3
 import com.dmdirc.ktirc.IrcClient
4 4
 import com.dmdirc.ktirc.TestConstants
5 5
 import com.dmdirc.ktirc.io.CaseMapping
6
-import com.dmdirc.ktirc.model.ModePrefixMapping
7
-import com.dmdirc.ktirc.model.ServerFeature
8
-import com.dmdirc.ktirc.model.ServerState
9
-import com.dmdirc.ktirc.model.User
6
+import com.dmdirc.ktirc.messages.tagMap
7
+import com.dmdirc.ktirc.model.*
10 8
 import com.nhaarman.mockitokotlin2.doReturn
11 9
 import com.nhaarman.mockitokotlin2.mock
12 10
 import com.nhaarman.mockitokotlin2.verify
@@ -72,7 +70,7 @@ internal class EventUtilsTest {
72 70
         val message = MessageReceived(EventMetadata(TestConstants.time), User("acidBurn"), "Zerocool", "Hack the planet!")
73 71
 
74 72
         ircClient.reply(message, "OK")
75
-        verify(ircClient).send("PRIVMSG acidBurn :OK")
73
+        verify(ircClient).send(tagMap(), "PRIVMSG", "acidBurn", "OK")
76 74
     }
77 75
 
78 76
     @Test
@@ -80,7 +78,7 @@ internal class EventUtilsTest {
80 78
         val message = MessageReceived(EventMetadata(TestConstants.time), User("acidBurn"), "#TheGibson", "Hack the planet!")
81 79
 
82 80
         ircClient.reply(message, "OK")
83
-        verify(ircClient).send("PRIVMSG #TheGibson :OK")
81
+        verify(ircClient).send(tagMap(), "PRIVMSG", "#TheGibson", "OK")
84 82
     }
85 83
 
86 84
     @Test
@@ -88,7 +86,7 @@ internal class EventUtilsTest {
88 86
         val message = MessageReceived(EventMetadata(TestConstants.time), User("acidBurn"), "#TheGibson", "Hack the planet!")
89 87
 
90 88
         ircClient.reply(message, "OK", prefixWithNickname = true)
91
-        verify(ircClient).send("PRIVMSG #TheGibson :acidBurn: OK")
89
+        verify(ircClient).send(tagMap(), "PRIVMSG", "#TheGibson", "acidBurn: OK")
92 90
     }
93 91
 
94 92
     @Test
@@ -97,7 +95,7 @@ internal class EventUtilsTest {
97 95
         val message = MessageReceived(EventMetadata(TestConstants.time, messageId = "abc123"), User("acidBurn"), "Zerocool", "Hack the planet!")
98 96
 
99 97
         ircClient.reply(message, "OK")
100
-        verify(ircClient).send("@+draft/reply=abc123 PRIVMSG acidBurn :OK")
98
+        verify(ircClient).send(tagMap(MessageTag.Reply to "abc123"), "PRIVMSG", "acidBurn", "OK")
101 99
     }
102 100
 
103 101
     @Test
@@ -105,7 +103,7 @@ internal class EventUtilsTest {
105 103
         val message = MessageReceived(EventMetadata(TestConstants.time, messageId = "abc123"), User("acidBurn"), "#TheGibson", "Hack the planet!")
106 104
 
107 105
         ircClient.reply(message, "OK")
108
-        verify(ircClient).send("@+draft/reply=abc123 PRIVMSG #TheGibson :OK")
106
+        verify(ircClient).send(tagMap(MessageTag.Reply to "abc123"), "PRIVMSG", "#TheGibson", "OK")
109 107
     }
110 108
 
111 109
     @Test
@@ -113,7 +111,7 @@ internal class EventUtilsTest {
113 111
         val message = MessageReceived(EventMetadata(TestConstants.time, messageId = "abc123"), User("acidBurn"), "#TheGibson", "Hack the planet!")
114 112
 
115 113
         ircClient.reply(message, "OK", prefixWithNickname = true)
116
-        verify(ircClient).send("@+draft/reply=abc123 PRIVMSG #TheGibson :acidBurn: OK")
114
+        verify(ircClient).send(tagMap(MessageTag.Reply to "abc123"), "PRIVMSG", "#TheGibson", "acidBurn: OK")
117 115
     }
118 116
 
119 117
 
@@ -123,7 +121,7 @@ internal class EventUtilsTest {
123 121
         val message = MessageReceived(EventMetadata(TestConstants.time, messageId = "msgId"), User("acidBurn"), "Zerocool", "Hack the planet!")
124 122
 
125 123
         ircClient.react(message, ":P")
126
-        verify(ircClient).send("@+draft/react=:P;+draft/reply=msgId TAGMSG acidBurn")
124
+        verify(ircClient).send(tagMap(MessageTag.React to ":P", MessageTag.Reply to "msgId"), "TAGMSG", "acidBurn")
127 125
     }
128 126
 
129 127
     @Test
@@ -131,7 +129,7 @@ internal class EventUtilsTest {
131 129
         val message = MessageReceived(EventMetadata(TestConstants.time, messageId = "msgId"), User("acidBurn"), "#TheGibson", "Hack the planet!")
132 130
 
133 131
         ircClient.react(message, ":P")
134
-        verify(ircClient).send("@+draft/react=:P;+draft/reply=msgId TAGMSG #TheGibson")
132
+        verify(ircClient).send(tagMap(MessageTag.React to ":P", MessageTag.Reply to "msgId"), "TAGMSG", "#TheGibson")
135 133
     }
136 134
 
137 135
 }

+ 11
- 11
src/test/kotlin/com/dmdirc/ktirc/events/handlers/CapabilitiesHandlerTest.kt View File

@@ -64,14 +64,14 @@ internal class CapabilitiesHandlerTest {
64 64
 
65 65
         handler.processEvent(ircClient, ServerCapabilitiesFinished(EventMetadata(TestConstants.time)))
66 66
 
67
-        verify(ircClient).send(argThat { equals("CAP REQ :echo-message account-notify") || equals("CAP REQ :account-notify echo-message") })
67
+        verify(ircClient).send(eq("CAP"), eq("REQ"), argThat { equals("echo-message account-notify") || equals("account-notify echo-message") })
68 68
     }
69 69
 
70 70
     @Test
71 71
     fun `sends END when blank capabilities received`() {
72 72
         handler.processEvent(ircClient, ServerCapabilitiesFinished(EventMetadata(TestConstants.time)))
73 73
 
74
-        verify(ircClient).send("CAP END")
74
+        verify(ircClient).send("CAP", "END")
75 75
     }
76 76
 
77 77
     @Test
@@ -88,7 +88,7 @@ internal class CapabilitiesHandlerTest {
88 88
                 Capability.HostsInNamesReply to ""
89 89
         )))
90 90
 
91
-        verify(ircClient).send("CAP END")
91
+        verify(ircClient).send("CAP", "END")
92 92
     }
93 93
 
94 94
     @Test
@@ -99,7 +99,7 @@ internal class CapabilitiesHandlerTest {
99 99
                 Capability.HostsInNamesReply to ""
100 100
         )))
101 101
 
102
-        verify(ircClient).send("CAP END")
102
+        verify(ircClient).send("CAP", "END")
103 103
     }
104 104
 
105 105
     @Test
@@ -111,7 +111,7 @@ internal class CapabilitiesHandlerTest {
111 111
                 Capability.HostsInNamesReply to ""
112 112
         )))
113 113
 
114
-        verify(ircClient).send("CAP END")
114
+        verify(ircClient).send("CAP", "END")
115 115
     }
116 116
 
117 117
     @Test
@@ -147,7 +147,7 @@ internal class CapabilitiesHandlerTest {
147 147
                 Capability.HostsInNamesReply to ""
148 148
         )))
149 149
 
150
-        verify(ircClient).send("AUTHENTICATE mech1")
150
+        verify(ircClient).send("AUTHENTICATE", "mech1")
151 151
     }
152 152
 
153 153
     @Test
@@ -159,7 +159,7 @@ internal class CapabilitiesHandlerTest {
159 159
                 Capability.HostsInNamesReply to ""
160 160
         )))
161 161
 
162
-        verify(ircClient).send("AUTHENTICATE mech3")
162
+        verify(ircClient).send("AUTHENTICATE", "mech3")
163 163
     }
164 164
 
165 165
     @Test
@@ -201,7 +201,7 @@ internal class CapabilitiesHandlerTest {
201 201
         serverState.sasl.currentMechanism = null
202 202
         handler.processEvent(ircClient, AuthenticationMessage(EventMetadata(TestConstants.time), "+"))
203 203
 
204
-        verify(ircClient).send("AUTHENTICATE *")
204
+        verify(ircClient).send("AUTHENTICATE", "*")
205 205
     }
206 206
 
207 207
     @Test
@@ -267,7 +267,7 @@ internal class CapabilitiesHandlerTest {
267 267
     fun `sends END when SASL auth finished`() {
268 268
         handler.processEvent(ircClient, SaslFinished(EventMetadata(TestConstants.time), true))
269 269
 
270
-        verify(ircClient).send("CAP END")
270
+        verify(ircClient).send("CAP", "END")
271 271
     }
272 272
 
273 273
     @Test
@@ -299,7 +299,7 @@ internal class CapabilitiesHandlerTest {
299 299
         serverState.sasl.mechanisms.addAll(listOf(saslMech1, saslMech2, saslMech3))
300 300
         handler.processEvent(ircClient, SaslMechanismNotAvailableError(EventMetadata(TestConstants.time), listOf("mech1", "fake2")))
301 301
 
302
-        verify(ircClient).send("AUTHENTICATE mech1")
302
+        verify(ircClient).send("AUTHENTICATE", "mech1")
303 303
     }
304 304
 
305 305
     @Test
@@ -307,7 +307,7 @@ internal class CapabilitiesHandlerTest {
307 307
         serverState.sasl.mechanisms.addAll(listOf(saslMech1, saslMech2, saslMech3))
308 308
         handler.processEvent(ircClient, SaslMechanismNotAvailableError(EventMetadata(TestConstants.time), listOf("fake1", "fake2")))
309 309
 
310
-        verify(ircClient).send("CAP END")
310
+        verify(ircClient).send("CAP", "END")
311 311
     }
312 312
 
313 313
     @Test

+ 3
- 3
src/test/kotlin/com/dmdirc/ktirc/events/handlers/ChannelStateHandlerTest.kt View File

@@ -145,7 +145,7 @@ internal class ChannelStateHandlerTest {
145 145
 
146 146
         handler.processEvent(ircClient, ChannelNamesFinished(EventMetadata(TestConstants.time), "#thegibson"))
147 147
 
148
-        verify(ircClient).send("MODE :#thegibson")
148
+        verify(ircClient).send("MODE", "#thegibson")
149 149
     }
150 150
 
151 151
     @Test
@@ -158,7 +158,7 @@ internal class ChannelStateHandlerTest {
158 158
 
159 159
         handler.processEvent(ircClient, ChannelNamesFinished(EventMetadata(TestConstants.time), "#thegibson"))
160 160
 
161
-        verify(ircClient, never()).send("MODE :#thegibson")
161
+        verify(ircClient, never()).send("MODE", "#thegibson")
162 162
     }
163 163
 
164 164
     @Test
@@ -170,7 +170,7 @@ internal class ChannelStateHandlerTest {
170 170
 
171 171
         handler.processEvent(ircClient, ChannelNamesFinished(EventMetadata(TestConstants.time), "#thegibson"))
172 172
 
173
-        verify(ircClient, never()).send("MODE :#thegibson")
173
+        verify(ircClient, never()).send("MODE", "#thegibson")
174 174
     }
175 175
 
176 176
     @Test

+ 1
- 1
src/test/kotlin/com/dmdirc/ktirc/events/handlers/PingHandlerTest.kt View File

@@ -18,7 +18,7 @@ internal class PingHandlerTest {
18 18
     @Test
19 19
     fun `PingHandler responses to pings with a pong`() = runBlocking {
20 20
         handler.processEvent(ircClient, PingReceived(EventMetadata(TestConstants.time), "the_plague".toByteArray()))
21
-        verify(ircClient).send("PONG :the_plague")
21
+        verify(ircClient).send("PONG", "the_plague")
22 22
     }
23 23
 
24 24
 }

+ 62
- 0
src/test/kotlin/com/dmdirc/ktirc/messages/MessageBuilderTest.kt View File

@@ -0,0 +1,62 @@
1
+package com.dmdirc.ktirc.messages
2
+
3
+import com.dmdirc.ktirc.model.MessageTag
4
+import org.junit.jupiter.api.Assertions.assertEquals
5
+import org.junit.jupiter.api.Test
6
+
7
+internal class MessageBuilderTest {
8
+
9
+    private val builder = MessageBuilder()
10
+
11
+    @Test
12
+    fun `builds a command on its own`() =
13
+            assertEquals("TEST", String(builder.build(emptyMap(), "TEST", emptyArray())))
14
+
15
+    @Test
16
+    fun `handles a single argument`() =
17
+            assertEquals("TEST foo", String(builder.build(emptyMap(), "TEST", arrayOf("foo"))))
18
+
19
+    @Test
20
+    fun `handles a single argument starting with a colon`() =
21
+            assertEquals("TEST ::foo", String(builder.build(emptyMap(), "TEST", arrayOf(":foo"))))
22
+
23
+    @Test
24
+    fun `handles a single argument with spaces`() =
25
+            assertEquals("TEST :foo bar", String(builder.build(emptyMap(), "TEST", arrayOf("foo bar"))))
26
+
27
+    @Test
28
+    fun `handles many arguments`() =
29
+            assertEquals("TEST foo bar baz", String(builder.build(emptyMap(), "TEST", arrayOf("foo", "bar", "baz"))))
30
+
31
+    @Test
32
+    fun `handles many arguments with spaces in the last`() =
33
+            assertEquals("TEST foo bar :baz quux", String(builder.build(emptyMap(), "TEST", arrayOf("foo", "bar", "baz quux"))))
34
+
35
+    @Test
36
+    fun `handles single tag`() =
37
+            assertEquals(
38
+                    "@draft/label=abc TEST foo bar",
39
+                    String(builder.build(
40
+                            mapOf(MessageTag.Label to "abc"),
41
+                            "TEST",
42
+                            arrayOf("foo", "bar"))))
43
+
44
+    @Test
45
+    fun `handles multiple tags`() =
46
+            assertEquals(
47
+                    "@draft/label=abc;account=acidB TEST foo bar",
48
+                    String(builder.build(
49
+                            mapOf(MessageTag.Label to "abc", MessageTag.AccountName to "acidB"),
50
+                            "TEST",
51
+                            arrayOf("foo", "bar"))))
52
+
53
+    @Test
54
+    fun `escapes tag values`() =
55
+            assertEquals(
56
+                    "@draft/label=\\\\hack\\sthe\\r\\nplanet\\: TEST foo bar",
57
+                    String(builder.build(
58
+                            mapOf(MessageTag.Label to "\\hack the\r\nplanet;"),
59
+                            "TEST",
60
+                            arrayOf("foo", "bar"))))
61
+
62
+}

+ 21
- 49
src/test/kotlin/com/dmdirc/ktirc/messages/MessageBuildersTest.kt View File

@@ -4,7 +4,6 @@ import com.dmdirc.ktirc.IrcClient
4 4
 import com.dmdirc.ktirc.model.MessageTag
5 5
 import com.nhaarman.mockitokotlin2.mock
6 6
 import com.nhaarman.mockitokotlin2.verify
7
-import org.junit.jupiter.api.Assertions.assertEquals
8 7
 import org.junit.jupiter.api.Test
9 8
 
10 9
 internal class MessageBuildersTest {
@@ -14,132 +13,105 @@ internal class MessageBuildersTest {
14 13
     @Test
15 14
     fun `sendCapabilityRequest sends CAP REQ message with single argument`() {
16 15
         mockClient.sendCapabilityRequest(listOf("a"))
17
-        verify(mockClient).send("CAP REQ :a")
16
+        verify(mockClient).send("CAP", "REQ", "a")
18 17
     }
19 18
 
20 19
     @Test
21 20
     fun `sendCapabilityRequest sends CAP REQ message with multiple args`() {
22 21
         mockClient.sendCapabilityRequest(listOf("a b c"))
23
-        verify(mockClient).send("CAP REQ :a b c")
22
+        verify(mockClient).send("CAP", "REQ", "a b c")
24 23
     }
25 24
 
26 25
     @Test
27 26
     fun `sendJoin sends correct JOIN message`() {
28 27
         mockClient.sendJoin("#TheGibson")
29
-        verify(mockClient).send("JOIN :#TheGibson")
28
+        verify(mockClient).send("JOIN", "#TheGibson")
30 29
     }
31 30
 
32 31
     @Test
33 32
     fun `sendModeRequest sends correct MODE message`() {
34 33
         mockClient.sendModeRequest("#TheGibson")
35
-        verify(mockClient).send("MODE :#TheGibson")
34
+        verify(mockClient).send("MODE", "#TheGibson")
36 35
     }
37 36
 
38 37
     @Test
39 38
     fun `sendNickChange sends correct NICK message`() {
40 39
         mockClient.sendNickChange("AcidBurn")
41
-        verify(mockClient).send("NICK :AcidBurn")
40
+        verify(mockClient).send("NICK", "AcidBurn")
42 41
     }
43 42
 
44 43
     @Test
45 44
     fun `sendPassword sends correct PASS message`() {
46 45
         mockClient.sendPassword("hacktheplanet")
47
-        verify(mockClient).send("PASS :hacktheplanet")
46
+        verify(mockClient).send("PASS", "hacktheplanet")
48 47
     }
49 48
 
50 49
     @Test
51 50
     fun `sendPong sends correct PONG message`() {
52 51
         mockClient.sendPong("abcdef".toByteArray())
53
-        verify(mockClient).send("PONG :abcdef")
52
+        verify(mockClient).send("PONG", "abcdef")
54 53
     }
55 54
 
56 55
     @Test
57 56
     fun `sendMessage sends correct PRIVMSG message`() {
58 57
         mockClient.sendMessage("acidBurn", "Hack the planet!")
59
-        verify(mockClient).send("PRIVMSG acidBurn :Hack the planet!")
58
+        verify(mockClient).send(tagMap(), "PRIVMSG", "acidBurn", "Hack the planet!")
60 59
     }
61 60
 
62 61
     @Test
63 62
     fun `sendMessage sends correct PRIVMSG message with reply to tag`() {
64 63
         mockClient.sendMessage("acidBurn", "Hack the planet!", "abc123")
65
-        verify(mockClient).send("@+draft/reply=abc123 PRIVMSG acidBurn :Hack the planet!")
64
+        verify(mockClient).send(tagMap(MessageTag.Reply to "abc123"), "PRIVMSG", "acidBurn", "Hack the planet!")
66 65
     }
67 66
 
68 67
     @Test
69 68
     fun `sendCtcp sends correct CTCP message with no arguments`() {
70 69
         mockClient.sendCtcp("acidBurn", "ping")
71
-        verify(mockClient).send("PRIVMSG acidBurn :\u0001PING\u0001")
70
+        verify(mockClient).send(tagMap(), "PRIVMSG", "acidBurn", "\u0001PING\u0001")
72 71
     }
73 72
 
74 73
     @Test
75 74
     fun `sendCtcp sends correct CTCP message with arguments`() {
76 75
         mockClient.sendCtcp("acidBurn", "ping", "12345")
77
-        verify(mockClient).send("PRIVMSG acidBurn :\u0001PING 12345\u0001")
76
+        verify(mockClient).send(tagMap(), "PRIVMSG", "acidBurn", "\u0001PING 12345\u0001")
78 77
     }
79 78
 
80 79
     @Test
81 80
     fun `sendAction sends correct action`() {
82 81
         mockClient.sendAction("acidBurn", "hacks the planet")
83
-        verify(mockClient).send("PRIVMSG acidBurn :\u0001ACTION hacks the planet\u0001")
82
+        verify(mockClient).send(tagMap(), "PRIVMSG", "acidBurn", "\u0001ACTION hacks the planet\u0001")
84 83
     }
85 84
 
86 85
     @Test
87 86
     fun `sendUser sends correct USER message`() {
88 87
         mockClient.sendUser("AcidBurn","Kate")
89
-        verify(mockClient).send("USER AcidBurn 0 * :Kate")
88
+        verify(mockClient).send("USER", "AcidBurn", "0", "*", "Kate")
90 89
     }
91 90
 
92 91
     @Test
93 92
     fun `sendUser sends correct AUTHENTICATE message`() {
94 93
         mockClient.sendAuthenticationMessage("SCRAM-MD5")
95
-        verify(mockClient).send("AUTHENTICATE SCRAM-MD5")
94
+        verify(mockClient).send("AUTHENTICATE", "SCRAM-MD5")
96 95
     }
97 96
 
98 97
     @Test
99 98
     fun `sendUser sends correct blank AUTHENTICATE message`() {
100 99
         mockClient.sendAuthenticationMessage()
101
-        verify(mockClient).send("AUTHENTICATE +")
102
-    }
103
-
104
-    @Test
105
-    fun `sendWithTag sends message without tags`() {
106
-        mockClient.sendWithTags(emptyMap(), "PING")
107
-        verify(mockClient).send("PING")
108
-    }
109
-
110
-    @Test
111
-    fun `sendWithTag sends message with single tag`() {
112
-        mockClient.sendWithTags(mapOf(MessageTag.MessageId to "abc"), "PING")
113
-        verify(mockClient).send("@draft/msgid=abc PING")
114
-    }
115
-
116
-    @Test
117
-    fun `sendWithTag sends message with multiple tag`() {
118
-        mockClient.sendWithTags(mapOf(MessageTag.MessageId to "abc", MessageTag.AccountName to "foo"), "PING")
119
-        verify(mockClient).send("@draft/msgid=abc;account=foo PING")
120
-    }
121
-
122
-    @Test
123
-    fun `sendWithTag ignores tags with null values`() {
124
-        mockClient.sendWithTags(mapOf(MessageTag.MessageId to null, MessageTag.AccountName to "foo"), "PING")
125
-        verify(mockClient).send("@account=foo PING")
100
+        verify(mockClient).send("AUTHENTICATE", "+")
126 101
     }
127 102
 
128 103
     @Test
129 104
     fun `sendTagMessage sends tags`() {
130
-        mockClient.sendTagMessage("#thegibson", mapOf(MessageTag.MessageId to "id", MessageTag.AccountName to "foo"))
131
-        verify(mockClient).send("@draft/msgid=id;account=foo TAGMSG #thegibson")
105
+        val tags = mapOf(MessageTag.MessageId to "id", MessageTag.AccountName to "foo")
106
+        mockClient.sendTagMessage("#thegibson", tags)
107
+        verify(mockClient).send(tags, "TAGMSG", "#thegibson")
132 108
     }
133 109
 
134 110
     @Test
135 111
     fun `sendTagMessage sends tags with reply ID`() {
136
-        mockClient.sendTagMessage("#thegibson", mapOf(MessageTag.MessageId to "id", MessageTag.AccountName to "foo"), "otherid")
137
-        verify(mockClient).send("@draft/msgid=id;account=foo;+draft/reply=otherid TAGMSG #thegibson")
138
-    }
139
-
140
-    @Test
141
-    fun `escapes tag values`() {
142
-        assertEquals("\\\\hack\\sthe\\r\\nplanet\\:", "\\hack the\r\nplanet;".escapeTagValue())
112
+        val tags = mapOf(MessageTag.MessageId to "id", MessageTag.AccountName to "foo")
113
+        mockClient.sendTagMessage("#thegibson", tags, "otherId")
114
+        verify(mockClient).send(tags + (MessageTag.Reply to "otherId"), "TAGMSG", "#thegibson")
143 115
     }
144 116
 
145 117
 }

+ 1
- 1
src/test/kotlin/com/dmdirc/ktirc/sasl/ExternalMechanismTest.kt View File

@@ -14,7 +14,7 @@ internal class ExternalMechanismTest {
14 14
 
15 15
         mechanism.handleAuthenticationEvent(client, null)
16 16
 
17
-        verify(client).send("AUTHENTICATE +")
17
+        verify(client).send("AUTHENTICATE", "+")
18 18
     }
19 19
 
20 20
 }

+ 3
- 9
src/test/kotlin/com/dmdirc/ktirc/sasl/PlainMechanismTest.kt View File

@@ -3,10 +3,7 @@ package com.dmdirc.ktirc.sasl
3 3
 import com.dmdirc.ktirc.IrcClient
4 4
 import com.dmdirc.ktirc.SaslConfig
5 5
 import com.dmdirc.ktirc.model.ServerState
6
-import com.nhaarman.mockitokotlin2.argumentCaptor
7
-import com.nhaarman.mockitokotlin2.doReturn
8
-import com.nhaarman.mockitokotlin2.mock
9
-import com.nhaarman.mockitokotlin2.verify
6
+import com.nhaarman.mockitokotlin2.*
10 7
 import org.junit.jupiter.api.Assertions.assertEquals
11 8
 import org.junit.jupiter.api.Test
12 9
 
@@ -27,11 +24,8 @@ internal class PlainMechanismTest {
27 24
         mechanism.handleAuthenticationEvent(ircClient, null)
28 25
 
29 26
         val captor = argumentCaptor<String>()
30
-        verify(ircClient).send(captor.capture())
31
-        val parts = captor.firstValue.split(' ')
32
-        assertEquals("AUTHENTICATE", parts[0])
33
-
34
-        val data = String(parts[1].fromBase64()).split('\u0000')
27
+        verify(ircClient).send(eq("AUTHENTICATE"), captor.capture())
28
+        val data = String(captor.firstValue.fromBase64()).split('\u0000')
35 29
         assertEquals("acidB", data[0])
36 30
         assertEquals("acidB", data[1])
37 31
         assertEquals("HackThePlan3t!", data[2])

+ 5
- 5
src/test/kotlin/com/dmdirc/ktirc/sasl/SaslMechanismTest.kt View File

@@ -31,7 +31,7 @@ internal class SaslMechanismTest {
31 31
     fun `base64 encodes authentication data`() {
32 32
         val client = mock<IrcClient>()
33 33
         client.sendAuthenticationData("abcdef")
34
-        verify(client).send("AUTHENTICATE YWJjZGVm")
34
+        verify(client).send("AUTHENTICATE", "YWJjZGVm")
35 35
     }
36 36
 
37 37
     @Test
@@ -39,8 +39,8 @@ internal class SaslMechanismTest {
39 39
         val client = mock<IrcClient>()
40 40
         client.sendAuthenticationData("abcdef".repeat(120))
41 41
         with (inOrder(client)) {
42
-            verify(client, times(2)).send("AUTHENTICATE ${"YWJjZGVm".repeat(50)}")
43
-            verify(client).send("AUTHENTICATE ${"YWJjZGVm".repeat(20)}")
42
+            verify(client, times(2)).send("AUTHENTICATE", "YWJjZGVm".repeat(50))
43
+            verify(client).send("AUTHENTICATE", "YWJjZGVm".repeat(20))
44 44
         }
45 45
     }
46 46
 
@@ -49,8 +49,8 @@ internal class SaslMechanismTest {
49 49
         val client = mock<IrcClient>()
50 50
         client.sendAuthenticationData("abcdef".repeat(50))
51 51
         with (inOrder(client)) {
52
-            verify(client).send("AUTHENTICATE ${"YWJjZGVm".repeat(50)}")
53
-            verify(client).send("AUTHENTICATE +")
52
+            verify(client).send("AUTHENTICATE", "YWJjZGVm".repeat(50))
53
+            verify(client).send("AUTHENTICATE", "+")
54 54
         }
55 55
     }
56 56
 

+ 13
- 13
src/test/kotlin/com/dmdirc/ktirc/sasl/ScramMechanismTest.kt View File

@@ -26,7 +26,7 @@ internal class ScramMechanismTest {
26 26
         mechanism.handleAuthenticationEvent(ircClient, "+".toByteArray())
27 27
 
28 28
         val nonce = (serverState.sasl.mechanismState as ScramState).clientNonce
29
-        verify(ircClient).send("AUTHENTICATE ${"n,,n=user,r=$nonce".toByteArray().toBase64()}")
29
+        verify(ircClient).send("AUTHENTICATE", "n,,n=user,r=$nonce".toByteArray().toBase64())
30 30
     }
31 31
 
32 32
     @Test
@@ -40,7 +40,7 @@ internal class ScramMechanismTest {
40 40
 
41 41
         mechanism.handleAuthenticationEvent(ircClient, "m=future".toByteArray())
42 42
 
43
-        verify(ircClient).send("AUTHENTICATE *")
43
+        verify(ircClient).send("AUTHENTICATE", "*")
44 44
     }
45 45
 
46 46
     @Test
@@ -54,7 +54,7 @@ internal class ScramMechanismTest {
54 54
 
55 55
         mechanism.handleAuthenticationEvent(ircClient, "e=whoops".toByteArray())
56 56
 
57
-        verify(ircClient).send("AUTHENTICATE *")
57
+        verify(ircClient).send("AUTHENTICATE", "*")
58 58
     }
59 59
 
60 60
     @Test
@@ -68,7 +68,7 @@ internal class ScramMechanismTest {
68 68
 
69 69
         mechanism.handleAuthenticationEvent(ircClient, "r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92".toByteArray())
70 70
 
71
-        verify(ircClient).send("AUTHENTICATE *")
71
+        verify(ircClient).send("AUTHENTICATE", "*")
72 72
     }
73 73
 
74 74
     @Test
@@ -82,7 +82,7 @@ internal class ScramMechanismTest {
82 82
 
83 83
         mechanism.handleAuthenticationEvent(ircClient, "r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=leet".toByteArray())
84 84
 
85
-        verify(ircClient).send("AUTHENTICATE *")
85
+        verify(ircClient).send("AUTHENTICATE", "*")
86 86
     }
87 87
 
88 88
     @Test
@@ -96,7 +96,7 @@ internal class ScramMechanismTest {
96 96
 
97 97
         mechanism.handleAuthenticationEvent(ircClient, "rs=QSXCR+Q6sek8bf92,i=4096".toByteArray())
98 98
 
99
-        verify(ircClient).send("AUTHENTICATE *")
99
+        verify(ircClient).send("AUTHENTICATE", "*")
100 100
     }
101 101
 
102 102
     @Test
@@ -110,7 +110,7 @@ internal class ScramMechanismTest {
110 110
 
111 111
         mechanism.handleAuthenticationEvent(ircClient, "r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,i=4096".toByteArray())
112 112
 
113
-        verify(ircClient).send("AUTHENTICATE *")
113
+        verify(ircClient).send("AUTHENTICATE", "*")
114 114
     }
115 115
 
116 116
     @Test
@@ -145,7 +145,7 @@ internal class ScramMechanismTest {
145 145
 
146 146
         mechanism.handleAuthenticationEvent(ircClient, "r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,s=QSXCR+Q6sek8bf92,i=4096".toByteArray())
147 147
 
148
-        verify(ircClient).send("AUTHENTICATE ${"c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=".toByteArray().toBase64()}")
148
+        verify(ircClient).send("AUTHENTICATE", "c=biws,r=fyko+d2lbbFgONRv9qkxdawL3rfcNHYJY1ZVvWVs7j,p=v0X8v3Bz2T0CJGbJQyF0X+HI4Ts=".toByteArray().toBase64())
149 149
     }
150 150
 
151 151
     @Test
@@ -159,7 +159,7 @@ internal class ScramMechanismTest {
159 159
 
160 160
         mechanism.handleAuthenticationEvent(ircClient, "m=future".toByteArray())
161 161
 
162
-        verify(ircClient).send("AUTHENTICATE *")
162
+        verify(ircClient).send("AUTHENTICATE", "*")
163 163
     }
164 164
 
165 165
     @Test
@@ -173,7 +173,7 @@ internal class ScramMechanismTest {
173 173
 
174 174
         mechanism.handleAuthenticationEvent(ircClient, "e=whoops".toByteArray())
175 175
 
176
-        verify(ircClient).send("AUTHENTICATE *")
176
+        verify(ircClient).send("AUTHENTICATE", "*")
177 177
     }
178 178
 
179 179
     @Test
@@ -190,7 +190,7 @@ internal class ScramMechanismTest {
190 190
 
191 191
         mechanism.handleAuthenticationEvent(ircClient, "".toByteArray())
192 192
 
193
-        verify(ircClient).send("AUTHENTICATE *")
193
+        verify(ircClient).send("AUTHENTICATE", "*")
194 194
     }
195 195
 
196 196
     @Test
@@ -207,7 +207,7 @@ internal class ScramMechanismTest {
207 207
 
208 208
         mechanism.handleAuthenticationEvent(ircClient, "v=rmF9pqV8S7suAoZWja4dJRkF=".toByteArray())
209 209
 
210
-        verify(ircClient).send("AUTHENTICATE *")
210
+        verify(ircClient).send("AUTHENTICATE", "*")
211 211
     }
212 212
 
213 213
     @Test
@@ -224,7 +224,7 @@ internal class ScramMechanismTest {
224 224
 
225 225
         mechanism.handleAuthenticationEvent(ircClient, "v=rmF9pqV8S7suAoZWja4dJRkFsKQ=".toByteArray())
226 226
 
227
-        verify(ircClient).send("AUTHENTICATE +")
227
+        verify(ircClient).send("AUTHENTICATE", "+")
228 228
     }
229 229
 
230 230
 }

Loading…
Cancel
Save