Browse Source

Add UserAccountChanged event

tags/v0.5.0
Chris Smith 5 years ago
parent
commit
e92fe57d64

+ 1
- 0
CHANGELOG View File

@@ -1,6 +1,7 @@
1 1
 vNEXT (in development)
2 2
 
3 3
  * Added MotdFinished event
4
+ * Added UserAccountChanged event
4 5
  * Improved some documentation
5 6
 
6 7
 v0.4.0

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

@@ -50,6 +50,13 @@ class CtcpReceived(time: LocalDateTime, val user: User, val target: String, val
50 50
 /** Raised when a user quits. */
51 51
 class UserQuit(time: LocalDateTime, val user: User, val reason: String = "") : IrcEvent(time)
52 52
 
53
+/**
54
+ * Raised when a user's account changes (i.e., they auth'd or deauth'd with services).
55
+ *
56
+ * This event is only raised if the server supports the `account-notify` capability.
57
+ */
58
+class UserAccountChanged(time: LocalDateTime, val user: User, val newAccount: String?): IrcEvent(time)
59
+
53 60
 /** Raised when available server capabilities are received. More batches may follow. */
54 61
 class ServerCapabilitiesReceived(time: LocalDateTime, val capabilities: Map<Capability, String>) : IrcEvent(time)
55 62
 

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

@@ -10,6 +10,7 @@ internal class UserStateHandler : EventHandler {
10 10
             is ChannelJoined -> handleJoin(client.userState, event)
11 11
             is ChannelParted -> handlePart(client, event)
12 12
             is ChannelNamesReceived  -> handleNamesReceived(client, event)
13
+            is UserAccountChanged -> handleAccountChanged(client, event)
13 14
             is UserQuit -> handleQuit(client.userState, event)
14 15
         }
15 16
         return emptyList()
@@ -42,6 +43,10 @@ internal class UserStateHandler : EventHandler {
42 43
         }
43 44
     }
44 45
 
46
+    private fun handleAccountChanged(client: IrcClient, event: UserAccountChanged) {
47
+        client.userState[event.user]?.details?.account = event.newAccount
48
+    }
49
+
45 50
     private fun handleQuit(state: UserState, event: UserQuit) {
46 51
         state -= event.user
47 52
     }

+ 17
- 0
src/main/kotlin/com/dmdirc/ktirc/messages/AccountProcessor.kt View File

@@ -0,0 +1,17 @@
1
+package com.dmdirc.ktirc.messages
2
+
3
+import com.dmdirc.ktirc.events.UserAccountChanged
4
+import com.dmdirc.ktirc.model.IrcMessage
5
+
6
+internal class AccountProcessor : MessageProcessor {
7
+
8
+    override val commands = arrayOf("ACCOUNT")
9
+
10
+    override fun process(message: IrcMessage) = message.sourceUser?.let { user ->
11
+        listOf(UserAccountChanged(message.time, user, message.accountName))
12
+    } ?: emptyList()
13
+
14
+    private val IrcMessage.accountName
15
+        get() = with(String(params[0])) { if (this == "*") null else this }
16
+
17
+}

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

@@ -18,6 +18,7 @@ internal interface MessageProcessor {
18 18
 }
19 19
 
20 20
 internal val messageProcessors = setOf(
21
+        AccountProcessor(),
21 22
         CapabilityProcessor(),
22 23
         ISupportProcessor(),
23 24
         JoinProcessor(),

+ 12
- 0
src/test/kotlin/com/dmdirc/ktirc/events/UserStateHandlerTest.kt View File

@@ -158,4 +158,16 @@ internal class UserStateHandlerTest {
158 158
             assertEquals("root.localhost", details.hostname)
159 159
         }
160 160
     }
161
+
162
+    @Test
163
+    fun `updates user info on account change`() {
164
+        runBlocking {
165
+            userState += User("acidBurn")
166
+
167
+            handler.processEvent(ircClient, UserAccountChanged(TestConstants.time, User("acidBurn", "libby", "root.localhost"), "acidBurn"))
168
+
169
+            val details = userState["acidBurn"]?.details!!
170
+            assertEquals("acidBurn", details.account)
171
+        }
172
+    }
161 173
 }

+ 47
- 0
src/test/kotlin/com/dmdirc/ktirc/messages/AccountProcessorTest.kt View File

@@ -0,0 +1,47 @@
1
+package com.dmdirc.ktirc.messages
2
+
3
+import com.dmdirc.ktirc.TestConstants
4
+import com.dmdirc.ktirc.model.IrcMessage
5
+import com.dmdirc.ktirc.model.User
6
+import com.dmdirc.ktirc.util.currentTimeProvider
7
+import org.junit.jupiter.api.Assertions.assertEquals
8
+import org.junit.jupiter.api.BeforeEach
9
+import org.junit.jupiter.api.Test
10
+
11
+internal class AccountProcessorTest {
12
+
13
+    @BeforeEach
14
+    fun setUp() {
15
+        currentTimeProvider = { TestConstants.time }
16
+    }
17
+
18
+    @Test
19
+    fun `AccountProcessor raises account changed event with account name`() {
20
+        val events = AccountProcessor().process(
21
+                IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "ACCOUNT", listOf("acidBurn".toByteArray())))
22
+        assertEquals(1, events.size)
23
+
24
+        assertEquals(TestConstants.time, events[0].time)
25
+        assertEquals(User("acidburn", "libby", "root.localhost"), events[0].user)
26
+        assertEquals("acidBurn", events[0].newAccount)
27
+    }
28
+
29
+    @Test
30
+    fun `AccountProcessor raises account changed event when account removed`() {
31
+        val events = AccountProcessor().process(
32
+                IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "ACCOUNT", listOf("*".toByteArray())))
33
+        assertEquals(1, events.size)
34
+
35
+        assertEquals(TestConstants.time, events[0].time)
36
+        assertEquals(User("acidburn", "libby", "root.localhost"), events[0].user)
37
+        assertEquals(null, events[0].newAccount)
38
+    }
39
+
40
+    @Test
41
+    fun `AccountProcessor does nothing if prefix missing`() {
42
+        val events = AccountProcessor().process(
43
+                IrcMessage(emptyMap(), null, "ACCOUNT", listOf("*".toByteArray())))
44
+        assertEquals(0, events.size)
45
+    }
46
+
47
+}

+ 1
- 1
src/test/kotlin/com/dmdirc/ktirc/messages/PartProcessorTest.kt View File

@@ -41,7 +41,7 @@ internal class PartProcessorTest {
41 41
 
42 42
     @Test
43 43
     fun `PartProcessor does nothing if prefix missing`() {
44
-        val events = JoinProcessor().process(
44
+        val events = PartProcessor().process(
45 45
                 IrcMessage(emptyMap(), null, "PART", listOf("#crashandburn".toByteArray())))
46 46
         assertEquals(0, events.size)
47 47
     }

Loading…
Cancel
Save