Browse Source

Support for nick change errors

tags/v0.10.1
Chris Smith 5 years ago
parent
commit
4881cb05f5

+ 1
- 0
CHANGELOG View File

@@ -1,5 +1,6 @@
1 1
 vNEXT (in development)
2 2
 
3
+* Added NickChangeFailed event for when nicknames are in use, banned, etc
3 4
  * (Internal) Moved message processors into their own package
4 5
 
5 6
 v0.10.0

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

@@ -194,3 +194,23 @@ class BatchFinished(metadata: EventMetadata, val referenceId: String) : IrcEvent
194 194
 
195 195
 /** A batch of events that should be handled together. */
196 196
 class BatchReceived(metadata: EventMetadata, val type: String, val params: Array<String>, val events: List<IrcEvent>) : IrcEvent(metadata)
197
+
198
+/**
199
+ * Raised when attempting to set or change our nickname fails.
200
+ *
201
+ * If this happens before {ServerReady], the nickname must be changed for registration to continue.
202
+ */
203
+class NicknameChangeFailed(metadata: EventMetadata, val cause: NicknameChangeError): IrcEvent(metadata) {
204
+    /** Reasons a nick change may fail. */
205
+    enum class NicknameChangeError {
206
+        /** The nickname is not allowed by the server. */
207
+        ErroneousNickname,
208
+        /** The nickname is already in use. */
209
+        AlreadyInUse,
210
+        /** The nickname has collided with another somehow. */
211
+        Collision,
212
+        /** No nickname was provided. */
213
+        NoNicknameGiven
214
+    }
215
+}
216
+

+ 4
- 0
src/main/kotlin/com/dmdirc/ktirc/messages/NumericConstants.kt View File

@@ -16,6 +16,10 @@ internal const val RPL_MOTDSTART = "375"
16 16
 internal const val RPL_ENDOFMOTD = "376"
17 17
 
18 18
 internal const val ERR_NOMOTD = "422"
19
+internal const val ERR_NONICKNAMEGIVEN = "431"
20
+internal const val ERR_ERRONEUSNICKNAME = "432"
21
+internal const val ERR_NICKNAMEINUSE = "433"
22
+internal const val ERR_NICKCOLLISION = "436"
19 23
 
20 24
 internal const val RPL_SASLSUCCESS = "903"
21 25
 internal const val ERR_SASLFAIL = "904"

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

@@ -29,6 +29,7 @@ internal val messageProcessors = listOf(
29 29
         ModeProcessor(),
30 30
         MotdProcessor(),
31 31
         NamesProcessor(),
32
+        NickChangeErrorProcessor(),
32 33
         NickProcessor(),
33 34
         NoticeProcessor(),
34 35
         PartProcessor(),

+ 24
- 0
src/main/kotlin/com/dmdirc/ktirc/messages/processors/NickChangeErrorProcessor.kt View File

@@ -0,0 +1,24 @@
1
+package com.dmdirc.ktirc.messages.processors
2
+
3
+import com.dmdirc.ktirc.events.NicknameChangeFailed
4
+import com.dmdirc.ktirc.messages.ERR_ERRONEUSNICKNAME
5
+import com.dmdirc.ktirc.messages.ERR_NICKCOLLISION
6
+import com.dmdirc.ktirc.messages.ERR_NICKNAMEINUSE
7
+import com.dmdirc.ktirc.messages.ERR_NONICKNAMEGIVEN
8
+import com.dmdirc.ktirc.model.IrcMessage
9
+
10
+internal class NickChangeErrorProcessor : MessageProcessor {
11
+
12
+    override val commands = arrayOf(ERR_ERRONEUSNICKNAME, ERR_NICKCOLLISION, ERR_NICKNAMEINUSE, ERR_NONICKNAMEGIVEN)
13
+
14
+    override fun process(message: IrcMessage) = listOf(NicknameChangeFailed(message.metadata, message.command.toNicknameChangeError()))
15
+
16
+    private fun String.toNicknameChangeError(): NicknameChangeFailed.NicknameChangeError = when(this) {
17
+        ERR_ERRONEUSNICKNAME -> NicknameChangeFailed.NicknameChangeError.ErroneousNickname
18
+        ERR_NICKCOLLISION -> NicknameChangeFailed.NicknameChangeError.Collision
19
+        ERR_NICKNAMEINUSE -> NicknameChangeFailed.NicknameChangeError.AlreadyInUse
20
+        ERR_NONICKNAMEGIVEN -> NicknameChangeFailed.NicknameChangeError.NoNicknameGiven
21
+        else -> throw IllegalArgumentException("Unknown nick change error")
22
+    }
23
+
24
+}

+ 67
- 0
src/test/kotlin/com/dmdirc/ktirc/messages/processors/NickChangeErrorProcessorTest.kt View File

@@ -0,0 +1,67 @@
1
+package com.dmdirc.ktirc.messages.processors
2
+
3
+import com.dmdirc.ktirc.TestConstants
4
+import com.dmdirc.ktirc.events.NicknameChangeFailed
5
+import com.dmdirc.ktirc.messages.tagMap
6
+import com.dmdirc.ktirc.model.IrcMessage
7
+import com.dmdirc.ktirc.model.MessageTag
8
+import com.dmdirc.ktirc.params
9
+import com.dmdirc.ktirc.util.currentTimeProvider
10
+import org.junit.jupiter.api.Assertions.assertEquals
11
+import org.junit.jupiter.api.BeforeEach
12
+import org.junit.jupiter.api.Test
13
+import org.junit.jupiter.api.assertThrows
14
+
15
+internal class NickChangeErrorProcessorTest {
16
+
17
+    private val processor = NickChangeErrorProcessor()
18
+
19
+    @BeforeEach
20
+    fun setup() {
21
+        currentTimeProvider = { TestConstants.time }
22
+    }
23
+
24
+    @Test
25
+    fun `raises error event when nick in use`() {
26
+        val events = processor.process(IrcMessage(tagMap(), null, "433", params("Nickname already in use")))
27
+        assertEquals(1, events.size)
28
+        assertEquals(NicknameChangeFailed.NicknameChangeError.AlreadyInUse, events[0].cause)
29
+    }
30
+
31
+    @Test
32
+    fun `raises error event when nick is erroneous`() {
33
+        val events = processor.process(IrcMessage(tagMap(), null, "432", params("Nickname not allowed")))
34
+        assertEquals(1, events.size)
35
+        assertEquals(NicknameChangeFailed.NicknameChangeError.ErroneousNickname, events[0].cause)
36
+    }
37
+
38
+    @Test
39
+    fun `raises error event when nick collides`() {
40
+        val events = processor.process(IrcMessage(tagMap(), null, "436", params("Nick collision")))
41
+        assertEquals(1, events.size)
42
+        assertEquals(NicknameChangeFailed.NicknameChangeError.Collision, events[0].cause)
43
+    }
44
+
45
+    @Test
46
+    fun `raises error event when nick not provided`() {
47
+        val events = processor.process(IrcMessage(tagMap(), null, "431", params("No nickname given")))
48
+        assertEquals(1, events.size)
49
+        assertEquals(NicknameChangeFailed.NicknameChangeError.NoNicknameGiven, events[0].cause)
50
+    }
51
+
52
+    @Test
53
+    fun `throws if invoked with other numeric`() {
54
+        assertThrows<IllegalArgumentException> {
55
+            processor.process(IrcMessage(tagMap(), null, "123", params("Hack the planet!")))
56
+        }
57
+    }
58
+
59
+    @Test
60
+    fun `raises error event with correct metadata`() {
61
+        val events = processor.process(IrcMessage(tagMap(MessageTag.Label to "abc"), null, "433", params("Nickname already in use")))
62
+        assertEquals(1, events.size)
63
+        assertEquals(TestConstants.time, events[0].metadata.time)
64
+        assertEquals("abc", events[0].metadata.label)
65
+    }
66
+
67
+}

Loading…
Cancel
Save