Browse Source

Move messageId to metadata

tags/v0.9.0
Chris Smith 5 years ago
parent
commit
e707bbdff3

+ 2
- 0
CHANGELOG View File

@@ -6,6 +6,8 @@ vNEXT (in development)
6 6
    * requestModesOnJoin - automatically sends a MODE request when joining a channel
7 7
  * Events now have a `metadata` property instead of a `time` (and time is available in metadata)
8 8
    * IrcEvent.time is now deprecated but will remain until after v1.0.0.
9
+   * Metadata now contains the message ID, if any.
10
+     * ActionReceived.messageId and MessageReceived.messageId are now deprecated, to be removed after v1.0.0.
9 11
    * Metadata now contains the event's batch ID, if any.
10 12
  * Added support for batches
11 13
    * All events in a batch are buffered until the batch is finished

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

@@ -28,9 +28,9 @@ internal fun ChannelNamesReceived.toModesAndUsers(client: IrcClient) = sequence
28 28
  */
29 29
 fun IrcClient.reply(message: MessageReceived, response: String, prefixWithNickname: Boolean = false) {
30 30
     if (isToMe(message)) {
31
-        sendMessage(message.user.nickname, response, message.messageId)
31
+        sendMessage(message.user.nickname, response, message.metadata.messageId)
32 32
     } else {
33
-        sendMessage(message.target, if (prefixWithNickname) "${message.user.nickname}: $response" else response, message.messageId)
33
+        sendMessage(message.target, if (prefixWithNickname) "${message.user.nickname}: $response" else response, message.metadata.messageId)
34 34
     }
35 35
 }
36 36
 
@@ -40,7 +40,7 @@ fun IrcClient.reply(message: MessageReceived, response: String, prefixWithNickna
40 40
 fun IrcClient.react(message: MessageReceived, reaction: String) = sendTagMessage(
41 41
         if (isToMe(message)) message.user.nickname else message.target,
42 42
         mapOf(MessageTag.React to reaction),
43
-        message.messageId)
43
+        message.metadata.messageId)
44 44
 
45 45
 /**
46 46
  * Utility to determine whether the given message is to our local user or not.

+ 19
- 4
src/main/kotlin/com/dmdirc/ktirc/events/Events.kt View File

@@ -11,14 +11,15 @@ import java.time.LocalDateTime
11 11
  *
12 12
  * @param time The best-guess time at which the event occurred.
13 13
  * @param batchId The ID of the batch this event is part of, if any.
14
+ * @param messageId The unique ID of this message, if any.
14 15
  */
15
-data class EventMetadata(val time: LocalDateTime, val batchId: String? = null)
16
+data class EventMetadata(val time: LocalDateTime, val batchId: String? = null, val messageId: String? = null)
16 17
 
17 18
 /** Base class for all events. */
18 19
 sealed class IrcEvent(val metadata: EventMetadata) {
19 20
 
20 21
     /** The time at which the event occurred. */
21
-    @Deprecated("Only for backwards compatibility; to be removed post-1.0.0", replaceWith = ReplaceWith("metadata.time"))
22
+    @Deprecated("Moved to metadata; to be removed post-1.0.0", replaceWith = ReplaceWith("metadata.time"))
22 23
     val time: LocalDateTime
23 24
         get() = metadata.time
24 25
 
@@ -83,7 +84,14 @@ class ChannelTopicMetadataDiscovered(metadata: EventMetadata, val channel: Strin
83 84
 class ChannelTopicChanged(metadata: EventMetadata, val user: User, val channel: String, val topic: String?) : IrcEvent(metadata)
84 85
 
85 86
 /** Raised when a message is received. */
86
-class MessageReceived(metadata: EventMetadata, val user: User, val target: String, val message: String, val messageId: String? = null) : IrcEvent(metadata)
87
+class MessageReceived(metadata: EventMetadata, val user: User, val target: String, val message: String) : IrcEvent(metadata) {
88
+
89
+    /** The message ID of this message. */
90
+    @Deprecated("Moved to metadata; to be removed post-1.0.0", replaceWith = ReplaceWith("metadata.messageId"))
91
+    val messageId: String?
92
+        get() = metadata.messageId
93
+
94
+}
87 95
 
88 96
 /**
89 97
  * Raised when a notice is received.
@@ -93,7 +101,14 @@ class MessageReceived(metadata: EventMetadata, val user: User, val target: Strin
93 101
 class NoticeReceived(metadata: EventMetadata, val user: User, val target: String, val message: String) : IrcEvent(metadata)
94 102
 
95 103
 /** Raised when an action is received. */
96
-class ActionReceived(metadata: EventMetadata, val user: User, val target: String, val action: String, val messageId: String? = null) : IrcEvent(metadata)
104
+class ActionReceived(metadata: EventMetadata, val user: User, val target: String, val action: String) : IrcEvent(metadata) {
105
+
106
+    /** The message ID of this action. */
107
+    @Deprecated("Moved to metadata; to be removed post-1.0.0", replaceWith = ReplaceWith("metadata.messageId"))
108
+    val messageId: String?
109
+        get() = metadata.messageId
110
+
111
+}
97 112
 
98 113
 /** Raised when a CTCP is received. */
99 114
 class CtcpReceived(metadata: EventMetadata, val user: User, val target: String, val type: String, val content: String) : IrcEvent(metadata)

+ 2
- 6
src/main/kotlin/com/dmdirc/ktirc/messages/PrivmsgProcessor.kt View File

@@ -5,7 +5,6 @@ import com.dmdirc.ktirc.events.CtcpReceived
5 5
 import com.dmdirc.ktirc.events.IrcEvent
6 6
 import com.dmdirc.ktirc.events.MessageReceived
7 7
 import com.dmdirc.ktirc.model.IrcMessage
8
-import com.dmdirc.ktirc.model.MessageTag
9 8
 import com.dmdirc.ktirc.model.User
10 9
 
11 10
 internal class PrivmsgProcessor : MessageProcessor {
@@ -15,7 +14,7 @@ internal class PrivmsgProcessor : MessageProcessor {
15 14
     override fun process(message: IrcMessage) = message.sourceUser?.let { user ->
16 15
         listOf(when {
17 16
             message.isCtcp() -> handleCtcp(message, user)
18
-            else -> MessageReceived(message.metadata, user, String(message.params[0]), String(message.params[1]), message.messageId)
17
+            else -> MessageReceived(message.metadata, user, String(message.params[0]), String(message.params[1]))
19 18
         })
20 19
     } ?: emptyList()
21 20
 
@@ -24,14 +23,11 @@ internal class PrivmsgProcessor : MessageProcessor {
24 23
         val parts = content.split(' ', limit=2)
25 24
         val body = if (parts.size == 2) parts[1] else ""
26 25
         return when (parts[0].toUpperCase()) {
27
-            "ACTION" -> ActionReceived(message.metadata, user, String(message.params[0]), body, message.messageId)
26
+            "ACTION" -> ActionReceived(message.metadata, user, String(message.params[0]), body)
28 27
             else -> CtcpReceived(message.metadata, user, String(message.params[0]), parts[0], body)
29 28
         }
30 29
     }
31 30
 
32 31
     private fun IrcMessage.isCtcp() = params[1].size > 2 && params[1][0] == CTCP_BYTE && params[1][params[1].size - 1] == CTCP_BYTE
33 32
 
34
-    private val IrcMessage.messageId
35
-        get() = tags[MessageTag.MessageId]
36
-
37 33
 }

+ 7
- 5
src/main/kotlin/com/dmdirc/ktirc/model/IrcMessage.kt View File

@@ -12,7 +12,7 @@ import java.time.LocalDateTime
12 12
 internal class IrcMessage(val tags: Map<MessageTag, String>, val prefix: ByteArray?, val command: String, val params: List<ByteArray>) {
13 13
 
14 14
     /** The time at which the message was sent, or our best guess at it. */
15
-    val metadata = EventMetadata(time, batchId)
15
+    val metadata = EventMetadata(time, batchId, messageId)
16 16
 
17 17
     /** The user that generated the message, if any. */
18 18
     val sourceUser by lazy {
@@ -22,15 +22,17 @@ internal class IrcMessage(val tags: Map<MessageTag, String>, val prefix: ByteArr
22 22
     }
23 23
 
24 24
     private val time
25
-        get() = if (MessageTag.ServerTime in tags) {
26
-            LocalDateTime.ofInstant(Instant.parse(tags[MessageTag.ServerTime]), currentTimeZoneProvider())
27
-        } else {
28
-            currentTimeProvider()
25
+        get() = when (MessageTag.ServerTime in tags) {
26
+            true -> LocalDateTime.ofInstant(Instant.parse(tags[MessageTag.ServerTime]), currentTimeZoneProvider())
27
+            false -> currentTimeProvider()
29 28
         }
30 29
 
31 30
     private val batchId
32 31
         get() = tags[MessageTag.Batch]
33 32
 
33
+    private val messageId
34
+        get() = tags[MessageTag.MessageId]
35
+
34 36
 }
35 37
 
36 38
 /**

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

@@ -94,7 +94,7 @@ internal class EventUtilsTest {
94 94
     @Test
95 95
     fun `reply sends response with message ID to user when message is private`() {
96 96
         serverState.localNickname = "zeroCool"
97
-        val message = MessageReceived(EventMetadata(TestConstants.time), User("acidBurn"), "Zerocool", "Hack the planet!", "abc123")
97
+        val message = MessageReceived(EventMetadata(TestConstants.time, messageId = "abc123"), User("acidBurn"), "Zerocool", "Hack the planet!")
98 98
 
99 99
         ircClient.reply(message, "OK")
100 100
         verify(ircClient).send("@+draft/reply=abc123 PRIVMSG acidBurn :OK")
@@ -102,7 +102,7 @@ internal class EventUtilsTest {
102 102
 
103 103
     @Test
104 104
     fun `reply sends unprefixed response with message ID to user when message is in a channel`() {
105
-        val message = MessageReceived(EventMetadata(TestConstants.time), User("acidBurn"), "#TheGibson", "Hack the planet!", "abc123")
105
+        val message = MessageReceived(EventMetadata(TestConstants.time, messageId = "abc123"), User("acidBurn"), "#TheGibson", "Hack the planet!")
106 106
 
107 107
         ircClient.reply(message, "OK")
108 108
         verify(ircClient).send("@+draft/reply=abc123 PRIVMSG #TheGibson :OK")
@@ -110,7 +110,7 @@ internal class EventUtilsTest {
110 110
 
111 111
     @Test
112 112
     fun `reply sends prefixed response with message ID to user when message is in a channel`() {
113
-        val message = MessageReceived(EventMetadata(TestConstants.time), User("acidBurn"), "#TheGibson", "Hack the planet!", "abc123")
113
+        val message = MessageReceived(EventMetadata(TestConstants.time, messageId = "abc123"), User("acidBurn"), "#TheGibson", "Hack the planet!")
114 114
 
115 115
         ircClient.reply(message, "OK", prefixWithNickname = true)
116 116
         verify(ircClient).send("@+draft/reply=abc123 PRIVMSG #TheGibson :acidBurn: OK")
@@ -120,7 +120,7 @@ internal class EventUtilsTest {
120 120
     @Test
121 121
     fun `react sends response to user when message is private`() {
122 122
         serverState.localNickname = "zeroCool"
123
-        val message = MessageReceived(EventMetadata(TestConstants.time), User("acidBurn"), "Zerocool", "Hack the planet!", "msgId")
123
+        val message = MessageReceived(EventMetadata(TestConstants.time, messageId = "msgId"), User("acidBurn"), "Zerocool", "Hack the planet!")
124 124
 
125 125
         ircClient.react(message, ":P")
126 126
         verify(ircClient).send("@+draft/react=:P;+draft/reply=msgId TAGMSG acidBurn")
@@ -128,7 +128,7 @@ internal class EventUtilsTest {
128 128
 
129 129
     @Test
130 130
     fun `react sends unprefixed response to user when message is in a channel`() {
131
-        val message = MessageReceived(EventMetadata(TestConstants.time), User("acidBurn"), "#TheGibson", "Hack the planet!", "msgId")
131
+        val message = MessageReceived(EventMetadata(TestConstants.time, messageId = "msgId"), User("acidBurn"), "#TheGibson", "Hack the planet!")
132 132
 
133 133
         ircClient.react(message, ":P")
134 134
         verify(ircClient).send("@+draft/react=:P;+draft/reply=msgId TAGMSG #TheGibson")

+ 8
- 42
src/test/kotlin/com/dmdirc/ktirc/messages/PrivmsgProcessorTest.kt View File

@@ -5,12 +5,10 @@ import com.dmdirc.ktirc.events.ActionReceived
5 5
 import com.dmdirc.ktirc.events.CtcpReceived
6 6
 import com.dmdirc.ktirc.events.MessageReceived
7 7
 import com.dmdirc.ktirc.model.IrcMessage
8
-import com.dmdirc.ktirc.model.MessageTag
9 8
 import com.dmdirc.ktirc.model.User
10 9
 import com.dmdirc.ktirc.params
11 10
 import com.dmdirc.ktirc.util.currentTimeProvider
12 11
 import org.junit.jupiter.api.Assertions.assertEquals
13
-import org.junit.jupiter.api.Assertions.assertNull
14 12
 import org.junit.jupiter.api.BeforeEach
15 13
 import org.junit.jupiter.api.Test
16 14
 
@@ -22,7 +20,7 @@ internal class PrivmsgProcessorTest {
22 20
     }
23 21
 
24 22
     @Test
25
-    fun `PrivsgProcessor raises message received event`() {
23
+    fun `raises message received event`() {
26 24
         val events = PrivmsgProcessor().process(
27 25
                 IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "PRIVMSG", params("#crashandburn", "hack the planet!")))
28 26
         assertEquals(1, events.size)
@@ -32,25 +30,10 @@ internal class PrivmsgProcessorTest {
32 30
         assertEquals(User("acidburn", "libby", "root.localhost"), event.user)
33 31
         assertEquals("#crashandburn", event.target)
34 32
         assertEquals("hack the planet!", event.message)
35
-        assertNull(event.messageId)
36 33
     }
37 34
 
38 35
     @Test
39
-    fun `PrivsgProcessor raises message received event with message ID`() {
40
-        val events = PrivmsgProcessor().process(
41
-                IrcMessage(mapOf(MessageTag.MessageId to "abc123"), "acidburn!libby@root.localhost".toByteArray(), "PRIVMSG", params("#crashandburn", "hack the planet!")))
42
-        assertEquals(1, events.size)
43
-
44
-        val event = events[0] as MessageReceived
45
-        assertEquals(TestConstants.time, event.metadata.time)
46
-        assertEquals(User("acidburn", "libby", "root.localhost"), event.user)
47
-        assertEquals("#crashandburn", event.target)
48
-        assertEquals("hack the planet!", event.message)
49
-        assertEquals("abc123", event.messageId)
50
-    }
51
-
52
-    @Test
53
-    fun `PrivsgProcessor raises action received event with content`() {
36
+    fun `raises action received event with content`() {
54 37
         val events = PrivmsgProcessor().process(
55 38
                 IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "PRIVMSG", params("#crashandburn", "\u0001ACTION hacks the planet\u0001")))
56 39
         assertEquals(1, events.size)
@@ -60,25 +43,10 @@ internal class PrivmsgProcessorTest {
60 43
         assertEquals(User("acidburn", "libby", "root.localhost"), event.user)
61 44
         assertEquals("#crashandburn", event.target)
62 45
         assertEquals("hacks the planet", event.action)
63
-        assertNull(event.messageId)
64
-    }
65
-
66
-    @Test
67
-    fun `PrivsgProcessor raises action received event with message ID`() {
68
-        val events = PrivmsgProcessor().process(
69
-                IrcMessage(mapOf(MessageTag.MessageId to "abc123"), "acidburn!libby@root.localhost".toByteArray(), "PRIVMSG", params("#crashandburn", "\u0001ACTION hacks the planet\u0001")))
70
-        assertEquals(1, events.size)
71
-
72
-        val event = events[0] as ActionReceived
73
-        assertEquals(TestConstants.time, event.metadata.time)
74
-        assertEquals(User("acidburn", "libby", "root.localhost"), event.user)
75
-        assertEquals("#crashandburn", event.target)
76
-        assertEquals("hacks the planet", event.action)
77
-        assertEquals("abc123", event.messageId)
78 46
     }
79 47
 
80 48
     @Test
81
-    fun `PrivsgProcessor raises action received event without content`() {
49
+    fun `raises action received event without content`() {
82 50
         val events = PrivmsgProcessor().process(
83 51
                 IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "PRIVMSG", params("#crashandburn", "\u0001ACTION\u0001")))
84 52
         assertEquals(1, events.size)
@@ -88,11 +56,10 @@ internal class PrivmsgProcessorTest {
88 56
         assertEquals(User("acidburn", "libby", "root.localhost"), event.user)
89 57
         assertEquals("#crashandburn", event.target)
90 58
         assertEquals("", event.action)
91
-        assertNull(event.messageId)
92 59
     }
93 60
 
94 61
     @Test
95
-    fun `PrivsgProcessor raises action received event with lowercase type`() {
62
+    fun `raises action received event with lowercase type`() {
96 63
         val events = PrivmsgProcessor().process(
97 64
                 IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "PRIVMSG", params("#crashandburn", "\u0001action hacks the planet\u0001")))
98 65
         assertEquals(1, events.size)
@@ -102,11 +69,10 @@ internal class PrivmsgProcessorTest {
102 69
         assertEquals(User("acidburn", "libby", "root.localhost"), event.user)
103 70
         assertEquals("#crashandburn", event.target)
104 71
         assertEquals("hacks the planet", event.action)
105
-        assertNull(event.messageId)
106 72
     }
107 73
 
108 74
     @Test
109
-    fun `PrivsgProcessor raises CTCP received event with content`() {
75
+    fun `raises CTCP received event with content`() {
110 76
         val events = PrivmsgProcessor().process(
111 77
                 IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "PRIVMSG", params("#crashandburn", "\u0001PING 12345\u0001")))
112 78
         assertEquals(1, events.size)
@@ -120,7 +86,7 @@ internal class PrivmsgProcessorTest {
120 86
     }
121 87
 
122 88
     @Test
123
-    fun `PrivsgProcessor raises CTCP received event without content`() {
89
+    fun `raises CTCP received event without content`() {
124 90
         val events = PrivmsgProcessor().process(
125 91
                 IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "PRIVMSG", params("#crashandburn", "\u0001PING\u0001")))
126 92
         assertEquals(1, events.size)
@@ -134,9 +100,9 @@ internal class PrivmsgProcessorTest {
134 100
     }
135 101
 
136 102
     @Test
137
-    fun `PrivsgProcessor does nothing if prefix missing`() {
103
+    fun `does nothing if prefix missing`() {
138 104
         val events = PrivmsgProcessor().process(
139 105
                 IrcMessage(emptyMap(), null, "PRIVMSG", params("#crashandburn", "hack the planet!")))
140 106
         assertEquals(0, events.size)
141 107
     }
142
-}
108
+}

+ 7
- 0
src/test/kotlin/com/dmdirc/ktirc/model/IrcMessageTest.kt View File

@@ -39,6 +39,13 @@ internal class IrcMessageTest {
39 39
         assertEquals("abc123", message.metadata.batchId)
40 40
     }
41 41
 
42
+    @Test
43
+    fun `populates message id if present`() {
44
+        currentTimeProvider = { TestConstants.time }
45
+        val message = IrcMessage(hashMapOf(MessageTag.MessageId to "abc123"), null, "", emptyList())
46
+        assertEquals("abc123", message.metadata.messageId)
47
+    }
48
+
42 49
     @Test
43 50
     fun `Can parse the prefix as a source user`() {
44 51
         val message = IrcMessage(emptyMap(), "acidBurn!libby@root.localhost".toByteArray(), "", emptyList())

Loading…
Cancel
Save