Browse Source

Support for nick changes

tags/v0.7.0
Chris Smith 5 years ago
parent
commit
de180b1d47

+ 1
- 0
CHANGELOG View File

@@ -8,6 +8,7 @@ vNEXT (in development)
8 8
    * The enabled mechanisms can now be configured (in the SASL DSL)
9 9
    * Added support for EXTERNAL mechanism, disabled by default
10 10
    * Now attempts to renegotiate if the server doesn't recognise the SASL mechanism that was tried
11
+ * Added UserNickChanged and corresponding ChannelNickChanged events
11 12
  * (Internal) Minor version updates for Gradle, Kotlin and JUnit
12 13
 
13 14
 v0.6.0

+ 24
- 14
src/main/kotlin/com/dmdirc/ktirc/events/ChannelStateHandler.kt View File

@@ -18,6 +18,7 @@ internal class ChannelStateHandler : EventHandler {
18 18
             is ChannelUserKicked -> handleKick(client, event)
19 19
             is ModeChanged -> handleModeChanged(client, event)
20 20
             is UserQuit -> return handleQuit(client, event)
21
+            is UserNickChanged -> return handleNickChanged(client, event)
21 22
         }
22 23
         return emptyList()
23 24
     }
@@ -87,29 +88,28 @@ internal class ChannelStateHandler : EventHandler {
87 88
             when (char) {
88 89
                 '+' -> adding = true
89 90
                 '-' -> adding = false
90
-                else -> argumentOffset += adjustMode(client, chan, char, event.arguments, argumentOffset, adding)
91
+                else -> argumentOffset += if (client.serverState.isChannelUserMode(char)) {
92
+                    adjustUserMode(client, chan, char, adding, event.arguments[argumentOffset])
93
+                } else {
94
+                    adjustMode(client, chan, char, event.arguments, argumentOffset, adding)
95
+                }
91 96
             }
92 97
         }
93 98
     }
94 99
 
95 100
     private fun adjustMode(client: IrcClient, chan: ChannelState, mode: Char, arguments: Array<String>, argumentOffset: Int, adding: Boolean): Int {
96
-        return if (client.serverState.isChannelUserMode(mode)) {
97
-            adjustUserMode(client, chan, mode, adding, arguments[argumentOffset])
98
-            1
101
+        val type = client.serverState.channelModeType(mode)
102
+        val takesParam = if (adding) type.needsParameterToSet else type.needsParameterToUnset
103
+        val param = if (takesParam) arguments[argumentOffset] else ""
104
+        if (adding) {
105
+            chan.modes[mode] = param
99 106
         } else {
100
-            val type = client.serverState.channelModeType(mode)
101
-            val takesParam = if (adding) type.needsParameterToSet else type.needsParameterToUnset
102
-            val param = if (takesParam) arguments[argumentOffset] else ""
103
-            if (adding) {
104
-                chan.modes[mode] = param
105
-            } else {
106
-                chan.modes.remove(mode)
107
-            }
108
-            if (takesParam) 1 else 0
107
+            chan.modes.remove(mode)
109 108
         }
109
+        return if (takesParam) 1 else 0
110 110
     }
111 111
 
112
-    private fun adjustUserMode(client: IrcClient, chan: ChannelState, mode: Char, adding: Boolean, user: String) {
112
+    private fun adjustUserMode(client: IrcClient, chan: ChannelState, mode: Char, adding: Boolean, user: String): Int {
113 113
         chan.users[user]?.let { channelUser ->
114 114
             // Filter from the master list of mode prefixes so that ordering is consistent
115 115
             channelUser.modes = client.serverState.channelModePrefixes.modes.filter {
@@ -120,6 +120,7 @@ internal class ChannelStateHandler : EventHandler {
120 120
                 }
121 121
             }
122 122
         }
123
+        return 1
123 124
     }
124 125
 
125 126
     private fun handleQuit(client: IrcClient, event: UserQuit) = sequence {
@@ -131,4 +132,13 @@ internal class ChannelStateHandler : EventHandler {
131 132
         }
132 133
     }.toList()
133 134
 
135
+    private fun handleNickChanged(client: IrcClient, event: UserNickChanged) = sequence {
136
+        client.channelState.forEach {
137
+            it.users[event.user.nickname]?.let { chanUser ->
138
+                chanUser.nickname = event.newNick
139
+                yield(ChannelNickChanged(event.time, event.user, it.name, event.newNick))
140
+            }
141
+        }
142
+    }.toList()
143
+
134 144
 }

+ 6
- 0
src/main/kotlin/com/dmdirc/ktirc/events/Events.kt View File

@@ -41,6 +41,9 @@ class ChannelUserKicked(time: LocalDateTime, val user: User, val channel: String
41 41
 /** Raised when a user quits, and is in a channel. */
42 42
 class ChannelQuit(time: LocalDateTime, val user: User, val channel: String, val reason: String = "") : IrcEvent(time)
43 43
 
44
+/** Raised when a user changes nickname, and is in a channel. */
45
+class ChannelNickChanged(time: LocalDateTime, val user: User, val channel: String, val newNick: String) : IrcEvent(time)
46
+
44 47
 /** Raised when a batch of the channel's member list has been received. More batches may follow. */
45 48
 class ChannelNamesReceived(time: LocalDateTime, val channel: String, val names: List<String>) : IrcEvent(time)
46 49
 
@@ -69,6 +72,9 @@ class CtcpReplyReceived(time: LocalDateTime, val user: User, val target: String,
69 72
 /** Raised when a user quits. */
70 73
 class UserQuit(time: LocalDateTime, val user: User, val reason: String = "") : IrcEvent(time)
71 74
 
75
+/** Raised when a user changes nickname. */
76
+class UserNickChanged(time: LocalDateTime, val user: User, val newNick: String) : IrcEvent(time)
77
+
72 78
 /**
73 79
  * Raised when a user's account changes (i.e., they auth'd or deauth'd with services).
74 80
  *

+ 8
- 0
src/main/kotlin/com/dmdirc/ktirc/events/UserStateHandler.kt View File

@@ -12,6 +12,7 @@ internal class UserStateHandler : EventHandler {
12 12
             is ChannelUserKicked -> handleKick(client, event)
13 13
             is ChannelNamesReceived  -> handleNamesReceived(client, event)
14 14
             is UserAccountChanged -> handleAccountChanged(client, event)
15
+            is UserNickChanged -> handleNickChanged(client, event)
15 16
             is UserQuit -> handleQuit(client.userState, event)
16 17
         }
17 18
         return emptyList()
@@ -63,6 +64,13 @@ internal class UserStateHandler : EventHandler {
63 64
         client.userState[event.user]?.details?.account = event.newAccount
64 65
     }
65 66
 
67
+    private fun handleNickChanged(client: IrcClient, event: UserNickChanged) {
68
+        client.userState[event.user]?.details?.nickname = event.newNick
69
+        if (client.isLocalUser(event.user)) {
70
+            client.serverState.localNickname = event.newNick
71
+        }
72
+    }
73
+
66 74
     private fun handleQuit(state: UserState, event: UserQuit) {
67 75
         state -= event.user
68 76
     }

+ 1
- 0
src/main/kotlin/com/dmdirc/ktirc/messages/MessageProcessor.kt View File

@@ -27,6 +27,7 @@ internal val messageProcessors = setOf(
27 27
         ModeProcessor(),
28 28
         MotdProcessor(),
29 29
         NamesProcessor(),
30
+        NickProcessor(),
30 31
         NoticeProcessor(),
31 32
         PartProcessor(),
32 33
         PingProcessor(),

+ 14
- 0
src/main/kotlin/com/dmdirc/ktirc/messages/NickProcessor.kt View File

@@ -0,0 +1,14 @@
1
+package com.dmdirc.ktirc.messages
2
+
3
+import com.dmdirc.ktirc.events.UserNickChanged
4
+import com.dmdirc.ktirc.model.IrcMessage
5
+
6
+internal class NickProcessor : MessageProcessor {
7
+
8
+    override val commands = arrayOf("NICK")
9
+
10
+    override fun process(message: IrcMessage) =
11
+            message.sourceUser?.let { listOf(UserNickChanged(message.time, it, String(message.params[0]))) }
12
+                    ?: emptyList()
13
+
14
+}

+ 47
- 0
src/test/kotlin/com/dmdirc/ktirc/events/ChannelStateHandlerTest.kt View File

@@ -217,6 +217,53 @@ internal class ChannelStateHandlerTest {
217 217
         assertTrue("#dumpsterdiving" in names)
218 218
     }
219 219
 
220
+    @Test
221
+    fun `renames user in channel member list for nick changes`() {
222
+        val channel = ChannelState("#thegibson") { CaseMapping.Rfc }
223
+        channel.users += ChannelUser("acidBurn")
224
+        channelStateMap += channel
225
+
226
+        handler.processEvent(ircClient, UserNickChanged(TestConstants.time, User("acidburn", "libby", "root.localhost"), "acidB"))
227
+
228
+        assertFalse("acidBurn" in channel.users)
229
+        assertTrue("acidB" in channel.users)
230
+        assertEquals("acidB", channel.users["acidB"]?.nickname)
231
+    }
232
+
233
+    @Test
234
+    fun `raises ChannelNickChanged event for each channel a user changes nicks in`() {
235
+        with (ChannelState("#thegibson") { CaseMapping.Rfc }) {
236
+            users += ChannelUser("ZeroCool")
237
+            channelStateMap += this
238
+        }
239
+
240
+        with (ChannelState("#dumpsterdiving") { CaseMapping.Rfc }) {
241
+            users += ChannelUser("ZeroCool")
242
+            channelStateMap += this
243
+        }
244
+
245
+        with (ChannelState("#chat") { CaseMapping.Rfc }) {
246
+            users += ChannelUser("AcidBurn")
247
+            channelStateMap += this
248
+        }
249
+
250
+        val events = handler.processEvent(ircClient, UserNickChanged(TestConstants.time, User("zerocool", "dade", "root.localhost"), "zer0c00l"))
251
+
252
+        val names = mutableListOf<String>()
253
+        assertEquals(2, events.size)
254
+        events.forEach { event ->
255
+            (event as ChannelNickChanged).let {
256
+                assertEquals(TestConstants.time, it.time)
257
+                assertEquals("zerocool", it.user.nickname)
258
+                assertEquals("zer0c00l", it.newNick)
259
+                names.add(it.channel)
260
+            }
261
+        }
262
+
263
+        assertTrue("#thegibson" in names)
264
+        assertTrue("#dumpsterdiving" in names)
265
+    }
266
+
220 267
     @Test
221 268
     fun `sets mode discovered flag when discovered mode event received`() {
222 269
         val channel = ChannelState("#thegibson") { CaseMapping.Rfc }

+ 102
- 112
src/test/kotlin/com/dmdirc/ktirc/events/UserStateHandlerTest.kt View File

@@ -7,7 +7,7 @@ import com.dmdirc.ktirc.model.*
7 7
 import com.nhaarman.mockitokotlin2.argForWhich
8 8
 import com.nhaarman.mockitokotlin2.doReturn
9 9
 import com.nhaarman.mockitokotlin2.mock
10
-import kotlinx.coroutines.runBlocking
10
+import com.nhaarman.mockitokotlin2.whenever
11 11
 import org.junit.jupiter.api.Assertions.*
12 12
 import org.junit.jupiter.api.BeforeEach
13 13
 import org.junit.jupiter.api.Test
@@ -33,210 +33,200 @@ internal class UserStateHandlerTest {
33 33
 
34 34
     @Test
35 35
     fun `adds channel to user on join`() {
36
-        runBlocking {
37
-            userState += User("acidBurn")
36
+        userState += User("acidBurn")
38 37
 
39
-            handler.processEvent(ircClient, ChannelJoined(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "#thegibson"))
38
+        handler.processEvent(ircClient, ChannelJoined(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "#thegibson"))
40 39
 
41
-            assertEquals(listOf("#thegibson"), userState["acidBurn"]?.channels?.toList())
42
-        }
40
+        assertEquals(listOf("#thegibson"), userState["acidBurn"]?.channels?.toList())
43 41
     }
44 42
 
45 43
     @Test
46 44
     fun `updates user info on join`() {
47
-        runBlocking {
48
-            userState += User("acidBurn")
45
+        userState += User("acidBurn")
49 46
 
50
-            handler.processEvent(ircClient, ChannelJoined(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "#thegibson"))
47
+        handler.processEvent(ircClient, ChannelJoined(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "#thegibson"))
51 48
 
52
-            val details = userState["acidBurn"]?.details!!
53
-            assertEquals("libby", details.ident)
54
-            assertEquals("root.localhost", details.hostname)
55
-        }
49
+        val details = userState["acidBurn"]?.details!!
50
+        assertEquals("libby", details.ident)
51
+        assertEquals("root.localhost", details.hostname)
56 52
     }
57 53
 
58 54
     @Test
59 55
     fun `removes channel from user on part`() {
60
-        runBlocking {
61
-            userState += User("acidBurn")
62
-            userState.addToChannel(User("acidBurn"), "#thegibson")
63
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
56
+        userState += User("acidBurn")
57
+        userState.addToChannel(User("acidBurn"), "#thegibson")
58
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
64 59
 
65
-            handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "#dumpsterdiving"))
60
+        handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "#dumpsterdiving"))
66 61
 
67
-            assertEquals(listOf("#thegibson"), userState["acidBurn"]?.channels?.toList())
68
-        }
62
+        assertEquals(listOf("#thegibson"), userState["acidBurn"]?.channels?.toList())
69 63
     }
70 64
 
71 65
     @Test
72 66
     fun `removes user on part from last channel`() {
73
-        runBlocking {
74
-            userState += User("acidBurn")
75
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
67
+        userState += User("acidBurn")
68
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
76 69
 
77
-            handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "#dumpsterdiving"))
70
+        handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "#dumpsterdiving"))
78 71
 
79
-            assertNull(userState["acidBurn"])
80
-        }
72
+        assertNull(userState["acidBurn"])
81 73
     }
82 74
 
83 75
     @Test
84 76
     fun `removes channel from all users on local part`() {
85
-        runBlocking {
86
-            userState += User("acidBurn")
87
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
88
-            userState.addToChannel(User("acidBurn"), "#thegibson")
77
+        userState += User("acidBurn")
78
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
79
+        userState.addToChannel(User("acidBurn"), "#thegibson")
89 80
 
90
-            userState += User("zeroCool")
91
-            userState.addToChannel(User("zeroCool"), "#dumpsterdiving")
92
-            userState.addToChannel(User("zeroCool"), "#thegibson")
81
+        userState += User("zeroCool")
82
+        userState.addToChannel(User("zeroCool"), "#dumpsterdiving")
83
+        userState.addToChannel(User("zeroCool"), "#thegibson")
93 84
 
94
-            handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("zeroCool", "dade", "root.localhost"), "#dumpsterdiving"))
85
+        handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("zeroCool", "dade", "root.localhost"), "#dumpsterdiving"))
95 86
 
96
-            assertEquals(listOf("#thegibson"), userState["acidBurn"]?.channels?.toList())
97
-            assertEquals(listOf("#thegibson"), userState["zeroCool"]?.channels?.toList())
98
-        }
87
+        assertEquals(listOf("#thegibson"), userState["acidBurn"]?.channels?.toList())
88
+        assertEquals(listOf("#thegibson"), userState["zeroCool"]?.channels?.toList())
99 89
     }
100 90
 
101 91
     @Test
102 92
     fun `removes remote users with no remaining channels on local part`() {
103
-        runBlocking {
104
-            userState += User("acidBurn")
105
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
93
+        userState += User("acidBurn")
94
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
106 95
 
107
-            handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("zeroCool", "dade", "root.localhost"), "#dumpsterdiving"))
96
+        handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("zeroCool", "dade", "root.localhost"), "#dumpsterdiving"))
108 97
 
109
-            assertNull(userState["acidBurn"])
110
-        }
98
+        assertNull(userState["acidBurn"])
111 99
     }
112 100
 
113 101
     @Test
114 102
     fun `keeps local user with no remaining channels after local part`() {
115
-        runBlocking {
116
-            userState += User("zeroCool")
117
-            userState.addToChannel(User("zeroCool"), "#dumpsterdiving")
103
+        userState += User("zeroCool")
104
+        userState.addToChannel(User("zeroCool"), "#dumpsterdiving")
118 105
 
119
-            handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("zeroCool", "dade", "root.localhost"), "#dumpsterdiving"))
106
+        handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("zeroCool", "dade", "root.localhost"), "#dumpsterdiving"))
120 107
 
121
-            assertNotNull(userState["zeroCool"])
122
-        }
108
+        assertNotNull(userState["zeroCool"])
123 109
     }
124 110
 
125 111
 
126 112
     @Test
127 113
     fun `removes channel from user on kick`() {
128
-        runBlocking {
129
-            userState += User("acidBurn")
130
-            userState.addToChannel(User("acidBurn"), "#thegibson")
131
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
114
+        userState += User("acidBurn")
115
+        userState.addToChannel(User("acidBurn"), "#thegibson")
116
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
132 117
 
133
-            handler.processEvent(ircClient, ChannelUserKicked(TestConstants.time, User("thePlague"), "#dumpsterdiving", "acidBurn"))
118
+        handler.processEvent(ircClient, ChannelUserKicked(TestConstants.time, User("thePlague"), "#dumpsterdiving", "acidBurn"))
134 119
 
135
-            assertEquals(listOf("#thegibson"), userState["acidBurn"]?.channels?.toList())
136
-        }
120
+        assertEquals(listOf("#thegibson"), userState["acidBurn"]?.channels?.toList())
137 121
     }
138 122
 
139 123
     @Test
140 124
     fun `removes user on kick from last channel`() {
141
-        runBlocking {
142
-            userState += User("acidBurn")
143
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
125
+        userState += User("acidBurn")
126
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
144 127
 
145
-            handler.processEvent(ircClient, ChannelUserKicked(TestConstants.time, User("thePlague"), "#dumpsterdiving", "acidBurn"))
128
+        handler.processEvent(ircClient, ChannelUserKicked(TestConstants.time, User("thePlague"), "#dumpsterdiving", "acidBurn"))
146 129
 
147
-            assertNull(userState["acidBurn"])
148
-        }
130
+        assertNull(userState["acidBurn"])
149 131
     }
150 132
 
151 133
     @Test
152 134
     fun `removes channel from all users on local kick`() {
153
-        runBlocking {
154
-            userState += User("acidBurn")
155
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
156
-            userState.addToChannel(User("acidBurn"), "#thegibson")
135
+        userState += User("acidBurn")
136
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
137
+        userState.addToChannel(User("acidBurn"), "#thegibson")
157 138
 
158
-            userState += User("zeroCool")
159
-            userState.addToChannel(User("zeroCool"), "#dumpsterdiving")
160
-            userState.addToChannel(User("zeroCool"), "#thegibson")
139
+        userState += User("zeroCool")
140
+        userState.addToChannel(User("zeroCool"), "#dumpsterdiving")
141
+        userState.addToChannel(User("zeroCool"), "#thegibson")
161 142
 
162
-            handler.processEvent(ircClient, ChannelUserKicked(TestConstants.time, User("thePlague"), "#dumpsterdiving", "zeroCool"))
143
+        handler.processEvent(ircClient, ChannelUserKicked(TestConstants.time, User("thePlague"), "#dumpsterdiving", "zeroCool"))
163 144
 
164
-            assertEquals(listOf("#thegibson"), userState["acidBurn"]?.channels?.toList())
165
-            assertEquals(listOf("#thegibson"), userState["zeroCool"]?.channels?.toList())
166
-        }
145
+        assertEquals(listOf("#thegibson"), userState["acidBurn"]?.channels?.toList())
146
+        assertEquals(listOf("#thegibson"), userState["zeroCool"]?.channels?.toList())
167 147
     }
168 148
 
169 149
     @Test
170 150
     fun `removes remote users with no remaining channels on local kick`() {
171
-        runBlocking {
172
-            userState += User("acidBurn")
173
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
151
+        userState += User("acidBurn")
152
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
174 153
 
175
-            handler.processEvent(ircClient, ChannelUserKicked(TestConstants.time, User("thePlague"), "#dumpsterdiving", "zeroCool"))
154
+        handler.processEvent(ircClient, ChannelUserKicked(TestConstants.time, User("thePlague"), "#dumpsterdiving", "zeroCool"))
176 155
 
177
-            assertNull(userState["acidBurn"])
178
-        }
156
+        assertNull(userState["acidBurn"])
179 157
     }
180 158
 
181 159
     @Test
182 160
     fun `keeps local user with no remaining channels after local kick`() {
183
-        runBlocking {
184
-            userState += User("zeroCool")
185
-            userState.addToChannel(User("zeroCool"), "#dumpsterdiving")
161
+        userState += User("zeroCool")
162
+        userState.addToChannel(User("zeroCool"), "#dumpsterdiving")
186 163
 
187
-            handler.processEvent(ircClient, ChannelUserKicked(TestConstants.time, User("thePlague"), "#dumpsterdiving", "zeroCool"))
164
+        handler.processEvent(ircClient, ChannelUserKicked(TestConstants.time, User("thePlague"), "#dumpsterdiving", "zeroCool"))
188 165
 
189
-            assertNotNull(userState["zeroCool"])
190
-        }
166
+        assertNotNull(userState["zeroCool"])
191 167
     }
192 168
 
193 169
     @Test
194 170
     fun `removes user entirely on quit`() {
195
-        runBlocking {
196
-            userState += User("acidBurn")
197
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
171
+        userState += User("acidBurn")
172
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
198 173
 
199
-            handler.processEvent(ircClient, UserQuit(TestConstants.time, User("acidBurn", "libby", "root.localhost")))
174
+        handler.processEvent(ircClient, UserQuit(TestConstants.time, User("acidBurn", "libby", "root.localhost")))
200 175
 
201
-            assertNull(userState["acidBurn"])
202
-        }
176
+        assertNull(userState["acidBurn"])
203 177
     }
204 178
 
205 179
     @Test
206 180
     fun `adds users to channels on names received`() {
207
-        runBlocking {
208
-            userState += User("acidBurn")
209
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
181
+        userState += User("acidBurn")
182
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
210 183
 
211
-            handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("@acidBurn")))
184
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("@acidBurn")))
212 185
 
213
-            assertEquals(listOf("#dumpsterdiving", "#thegibson"), userState["acidBurn"]?.channels?.toList())
214
-        }
186
+        assertEquals(listOf("#dumpsterdiving", "#thegibson"), userState["acidBurn"]?.channels?.toList())
215 187
     }
216 188
 
217 189
     @Test
218 190
     fun `updates user details on names received`() {
219
-        runBlocking {
220
-            userState += User("acidBurn")
221
-            userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
191
+        userState += User("acidBurn")
192
+        userState.addToChannel(User("acidBurn"), "#dumpsterdiving")
222 193
 
223
-            handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("@acidBurn!libby@root.localhost")))
194
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("@acidBurn!libby@root.localhost")))
224 195
 
225
-            val details = userState["acidBurn"]?.details!!
226
-            assertEquals("libby", details.ident)
227
-            assertEquals("root.localhost", details.hostname)
228
-        }
196
+        val details = userState["acidBurn"]?.details!!
197
+        assertEquals("libby", details.ident)
198
+        assertEquals("root.localhost", details.hostname)
229 199
     }
230 200
 
231 201
     @Test
232 202
     fun `updates user info on account change`() {
233
-        runBlocking {
234
-            userState += User("acidBurn")
203
+        userState += User("acidBurn")
235 204
 
236
-            handler.processEvent(ircClient, UserAccountChanged(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "acidBurn"))
205
+        handler.processEvent(ircClient, UserAccountChanged(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "acidBurn"))
237 206
 
238
-            val details = userState["acidBurn"]?.details!!
239
-            assertEquals("acidBurn", details.account)
240
-        }
207
+        val details = userState["acidBurn"]?.details!!
208
+        assertEquals("acidBurn", details.account)
241 209
     }
242
-}
210
+
211
+    @Test
212
+    fun `updates local nickname for local nick changes`() {
213
+        val user = User("acidBurn", "libby", "root.localhost")
214
+        whenever(ircClient.isLocalUser(user)).doReturn(true)
215
+
216
+        handler.processEvent(ircClient, UserNickChanged(TestConstants.time, user, "acid~"))
217
+
218
+        assertEquals("acid~", serverState.localNickname)
219
+    }
220
+
221
+    @Test
222
+    fun `updates nickname for remote nick changes`() {
223
+        val user = User("acidBurn", "libby", "root.localhost")
224
+        userState += User("AcidBurn")
225
+
226
+        handler.processEvent(ircClient, UserNickChanged(TestConstants.time, user, "acid~"))
227
+
228
+        assertNotNull(userState["acid~"])
229
+        assertNull(userState["AcidBurn"])
230
+        assertEquals("acid~", userState["acid~"]?.details?.nickname)
231
+    }
232
+}

+ 31
- 0
src/test/kotlin/com/dmdirc/ktirc/messages/NickProcessorTest.kt View File

@@ -0,0 +1,31 @@
1
+package com.dmdirc.ktirc.messages
2
+
3
+import com.dmdirc.ktirc.model.IrcMessage
4
+import com.dmdirc.ktirc.params
5
+import org.junit.jupiter.api.Assertions.assertEquals
6
+import org.junit.jupiter.api.Assertions.assertTrue
7
+import org.junit.jupiter.api.Test
8
+
9
+internal class NickProcessorTest {
10
+
11
+    @Test
12
+    fun `raises UserChangedNick event if prefix is valid`() {
13
+        val processor = NickProcessor()
14
+        val events = processor.process(IrcMessage(emptyMap(), "acidBurn!acidb@localhost".toByteArray(), "NICK", params("acidB")))
15
+
16
+        assertEquals(1, events.size)
17
+        val event = events[0]
18
+        assertEquals("acidBurn", event.user.nickname)
19
+        assertEquals("acidb", event.user.ident)
20
+        assertEquals("localhost", event.user.hostname)
21
+        assertEquals("acidB", event.newNick)
22
+    }
23
+
24
+    @Test
25
+    fun `does nothing if prefix is missing`() {
26
+        val processor = NickProcessor()
27
+        val events = processor.process(IrcMessage(emptyMap(), null, "NICK", params("acidB")))
28
+        assertTrue(events.isEmpty())
29
+    }
30
+
31
+}

Loading…
Cancel
Save