Browse Source

Expose message time in events

tags/v0.1.0
Chris Smith 5 years ago
parent
commit
7e54d86956
25 changed files with 216 additions and 99 deletions
  1. 15
    16
      src/main/kotlin/com/dmdirc/ktirc/events/Events.kt
  2. 6
    5
      src/main/kotlin/com/dmdirc/ktirc/messages/CapabilityProcessor.kt
  3. 1
    1
      src/main/kotlin/com/dmdirc/ktirc/messages/ISupportProcessor.kt
  4. 3
    1
      src/main/kotlin/com/dmdirc/ktirc/messages/JoinProcessor.kt
  5. 2
    2
      src/main/kotlin/com/dmdirc/ktirc/messages/NamesProcessor.kt
  6. 1
    1
      src/main/kotlin/com/dmdirc/ktirc/messages/PartProcessor.kt
  7. 1
    1
      src/main/kotlin/com/dmdirc/ktirc/messages/PingProcessor.kt
  8. 1
    1
      src/main/kotlin/com/dmdirc/ktirc/messages/PrivmsgProcessor.kt
  9. 1
    1
      src/main/kotlin/com/dmdirc/ktirc/messages/QuitProcessor.kt
  10. 1
    1
      src/main/kotlin/com/dmdirc/ktirc/messages/WelcomeProcessor.kt
  11. 19
    2
      src/main/kotlin/com/dmdirc/ktirc/model/IrcMessage.kt
  12. 10
    7
      src/test/kotlin/com/dmdirc/ktirc/IrcClientTest.kt
  13. 7
    0
      src/test/kotlin/com/dmdirc/ktirc/TestConstants.kt
  14. 7
    6
      src/test/kotlin/com/dmdirc/ktirc/events/CapabilitiesHandlerTest.kt
  15. 19
    18
      src/test/kotlin/com/dmdirc/ktirc/events/ChannelStateHandlerTest.kt
  16. 2
    1
      src/test/kotlin/com/dmdirc/ktirc/events/PingHandlerTest.kt
  17. 3
    2
      src/test/kotlin/com/dmdirc/ktirc/events/ServerStateHandlerTest.kt
  18. 6
    5
      src/test/kotlin/com/dmdirc/ktirc/io/MessageHandlerTest.kt
  19. 3
    4
      src/test/kotlin/com/dmdirc/ktirc/io/MessageParserTest.kt
  20. 11
    2
      src/test/kotlin/com/dmdirc/ktirc/messages/JoinProcessorTest.kt
  21. 21
    7
      src/test/kotlin/com/dmdirc/ktirc/messages/PartProcessorTest.kt
  22. 15
    5
      src/test/kotlin/com/dmdirc/ktirc/messages/PrivmsgProcessorTest.kt
  23. 19
    7
      src/test/kotlin/com/dmdirc/ktirc/messages/QuitProcessorTest.kt
  24. 10
    3
      src/test/kotlin/com/dmdirc/ktirc/messages/WelcomeProcessorTest.kt
  25. 32
    0
      src/test/kotlin/com/dmdirc/ktirc/model/IrcMessageTest.kt

+ 15
- 16
src/main/kotlin/com/dmdirc/ktirc/events/Events.kt View File

@@ -1,49 +1,48 @@
1
-@file:Suppress("ArrayInDataClass")
2
-
3 1
 package com.dmdirc.ktirc.events
4 2
 
5 3
 import com.dmdirc.ktirc.model.Capability
6 4
 import com.dmdirc.ktirc.model.ServerFeatureMap
7 5
 import com.dmdirc.ktirc.model.User
6
+import java.time.LocalDateTime
8 7
 
9
-sealed class IrcEvent
8
+sealed class IrcEvent(val time: LocalDateTime)
10 9
 
11 10
 /** Raised when the server initially welcomes us to the IRC network. */
12
-data class ServerWelcome(val localNick: String) : IrcEvent()
11
+class ServerWelcome(time: LocalDateTime, val localNick: String) : IrcEvent(time)
13 12
 
14 13
 /** Raised when the features supported by the server have changed. This may occur numerous times. */
15
-data class ServerFeaturesUpdated(val serverFeatures: ServerFeatureMap) : IrcEvent()
14
+class ServerFeaturesUpdated(time: LocalDateTime, val serverFeatures: ServerFeatureMap) : IrcEvent(time)
16 15
 
17 16
 /** Raised when the connection to the server has been established, configuration information has been received, etc. */
18 17
 // TODO: Implement
19
-object ServerConnected : IrcEvent()
18
+class ServerConnected(time: LocalDateTime) : IrcEvent(time)
20 19
 
21 20
 /** Raised whenever a PING is received from the server. */
22
-data class PingReceived(val nonce: ByteArray) : IrcEvent()
21
+class PingReceived(time: LocalDateTime, val nonce: ByteArray) : IrcEvent(time)
23 22
 
24 23
 /** Raised when a user joins a channel. */
25
-data class ChannelJoined(val user: User, val channel: String) : IrcEvent()
24
+class ChannelJoined(time: LocalDateTime, val user: User, val channel: String) : IrcEvent(time)
26 25
 
27 26
 /** Raised when a user leaves a channel. */
28
-data class ChannelParted(val user: User, val channel: String, val reason: String = "") : IrcEvent()
27
+class ChannelParted(time: LocalDateTime, val user: User, val channel: String, val reason: String = "") : IrcEvent(time)
29 28
 
30 29
 /** Raised when a batch of the channel's member list has been received. More batches may follow. */
31
-data class ChannelNamesReceived(val channel: String, val names: List<String>) : IrcEvent()
30
+class ChannelNamesReceived(time: LocalDateTime, val channel: String, val names: List<String>) : IrcEvent(time)
32 31
 
33 32
 /** Raised when the entirety of the channel's member list has been received. */
34
-data class ChannelNamesFinished(val channel: String) : IrcEvent()
33
+class ChannelNamesFinished(time: LocalDateTime, val channel: String) : IrcEvent(time)
35 34
 
36 35
 /** Raised when a message is received. */
37
-data class MessageReceived(val user: User, val target: String, val message: String) : IrcEvent()
36
+class MessageReceived(time: LocalDateTime, val user: User, val target: String, val message: String) : IrcEvent(time)
38 37
 
39 38
 /** Raised when a user quits. */
40
-data class UserQuit(val user: User, val reason: String = "") : IrcEvent()
39
+class UserQuit(time: LocalDateTime, val user: User, val reason: String = "") : IrcEvent(time)
41 40
 
42 41
 /** Raised when available server capabilities are received. More batches may follow. */
43
-data class ServerCapabilitiesReceived(val capabilities: Map<Capability, String>): IrcEvent()
42
+class ServerCapabilitiesReceived(time: LocalDateTime, val capabilities: Map<Capability, String>) : IrcEvent(time)
44 43
 
45 44
 /** Raised when our requested capabilities are acknowledged. More batches may follow. */
46
-data class ServerCapabilitiesAcknowledged(val capabilities: Map<Capability, String>): IrcEvent()
45
+class ServerCapabilitiesAcknowledged(time: LocalDateTime, val capabilities: Map<Capability, String>) : IrcEvent(time)
47 46
 
48 47
 /** Raised when the server has finished sending us capabilities. */
49
-object ServerCapabilitiesFinished : IrcEvent()
48
+class ServerCapabilitiesFinished(time: LocalDateTime) : IrcEvent(time)

+ 6
- 5
src/main/kotlin/com/dmdirc/ktirc/messages/CapabilityProcessor.kt View File

@@ -6,6 +6,7 @@ import com.dmdirc.ktirc.events.ServerCapabilitiesReceived
6 6
 import com.dmdirc.ktirc.model.IrcMessage
7 7
 import com.dmdirc.ktirc.model.capabilities
8 8
 import com.dmdirc.ktirc.util.logger
9
+import java.time.LocalDateTime
9 10
 
10 11
 class CapabilityProcessor : MessageProcessor {
11 12
 
@@ -14,15 +15,15 @@ class CapabilityProcessor : MessageProcessor {
14 15
     override val commands = arrayOf("CAP")
15 16
 
16 17
     override fun process(message: IrcMessage) = when (message.subCommand) {
17
-        "LS" -> handleList(message.subCommandArguments)
18
-        "ACK" -> listOf(ServerCapabilitiesAcknowledged(message.params.capabilities))
18
+        "LS" -> handleList(message.time, message.subCommandArguments)
19
+        "ACK" -> listOf(ServerCapabilitiesAcknowledged(message.time, message.params.capabilities))
19 20
         else -> emptyList()
20 21
     }
21 22
 
22
-    private fun handleList(lsParams: List<ByteArray>) = sequence {
23
-        yield(ServerCapabilitiesReceived(lsParams.capabilities))
23
+    private fun handleList(time: LocalDateTime, lsParams: List<ByteArray>) = sequence {
24
+        yield(ServerCapabilitiesReceived(time, lsParams.capabilities))
24 25
         if (lsParams.size < 2 || String(lsParams[0]) != "*") {
25
-            yield(ServerCapabilitiesFinished)
26
+            yield(ServerCapabilitiesFinished(time))
26 27
         }
27 28
     }.toList()
28 29
 

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

@@ -15,7 +15,7 @@ internal class ISupportProcessor : MessageProcessor {
15 15
 
16 16
     override val commands = arrayOf("005")
17 17
 
18
-    override fun process(message: IrcMessage) = listOf(ServerFeaturesUpdated(ServerFeatureMap().apply {
18
+    override fun process(message: IrcMessage) = listOf(ServerFeaturesUpdated(message.time, ServerFeatureMap().apply {
19 19
         // Ignore the first (nickname) and last ("are supported by this server") params
20 20
         for (i in 1 until message.params.size - 1) {
21 21
             parseParam(message.params[i])

+ 3
- 1
src/main/kotlin/com/dmdirc/ktirc/messages/JoinProcessor.kt View File

@@ -8,6 +8,8 @@ internal class JoinProcessor : MessageProcessor {
8 8
 
9 9
     override val commands = arrayOf("JOIN")
10 10
 
11
-    override fun process(message: IrcMessage) = message.prefix?.let { listOf(ChannelJoined(it.asUser(), String(message.params[0]))) } ?: emptyList()
11
+    override fun process(message: IrcMessage) = message.prefix?.let {
12
+        listOf(ChannelJoined(message.time, it.asUser(), String(message.params[0])))
13
+    } ?: emptyList()
12 14
 
13 15
 }

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

@@ -9,8 +9,8 @@ internal class NamesProcessor : MessageProcessor {
9 9
     override val commands = arrayOf("353", "366")
10 10
 
11 11
     override fun process(message: IrcMessage) = when (message.command) {
12
-        "353" -> listOf(ChannelNamesReceived(String(message.params[2]), String(message.params[3]).split(' ')))
13
-        "366" -> listOf(ChannelNamesFinished(String(message.params[1])))
12
+        "353" -> listOf(ChannelNamesReceived(message.time, String(message.params[2]), String(message.params[3]).split(' ')))
13
+        "366" -> listOf(ChannelNamesFinished(message.time, String(message.params[1])))
14 14
         else -> emptyList()
15 15
     }
16 16
 

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

@@ -9,7 +9,7 @@ internal class PartProcessor : MessageProcessor {
9 9
     override val commands = arrayOf("PART")
10 10
 
11 11
     override fun process(message: IrcMessage) = message.prefix?.let {
12
-        listOf(ChannelParted(it.asUser(), message.channel, message.reason))
12
+        listOf(ChannelParted(message.time, it.asUser(), message.channel, message.reason))
13 13
     } ?: emptyList()
14 14
 
15 15
     private val IrcMessage.channel

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

@@ -7,6 +7,6 @@ internal class PingProcessor : MessageProcessor {
7 7
 
8 8
     override val commands = arrayOf("PING")
9 9
 
10
-    override fun process(message: IrcMessage) = listOf(PingReceived(message.params[0]))
10
+    override fun process(message: IrcMessage) = listOf(PingReceived(message.time, message.params[0]))
11 11
 
12 12
 }

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

@@ -9,7 +9,7 @@ internal class PrivmsgProcessor : MessageProcessor {
9 9
     override val commands = arrayOf("PRIVMSG")
10 10
 
11 11
     override fun process(message: IrcMessage) = message.prefix?.let {
12
-        listOf(MessageReceived(it.asUser(), String(message.params[0]), String(message.params[1])))
12
+        listOf(MessageReceived(message.time, it.asUser(), String(message.params[0]), String(message.params[1])))
13 13
     } ?: emptyList()
14 14
 
15 15
 }

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

@@ -9,7 +9,7 @@ internal class QuitProcessor : MessageProcessor {
9 9
     override val commands = arrayOf("QUIT")
10 10
 
11 11
     override fun process(message: IrcMessage) = message.prefix?.let {
12
-        listOf(UserQuit(it.asUser(), message.reason))
12
+        listOf(UserQuit(message.time, it.asUser(), message.reason))
13 13
     } ?: emptyList()
14 14
 
15 15
     private val IrcMessage.reason

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

@@ -7,6 +7,6 @@ internal class WelcomeProcessor : MessageProcessor {
7 7
 
8 8
     override val commands = arrayOf("001")
9 9
 
10
-    override fun process(message: IrcMessage) = listOf(ServerWelcome(String(message.params[0])))
10
+    override fun process(message: IrcMessage) = listOf(ServerWelcome(message.time, String(message.params[0])))
11 11
 
12 12
 }

+ 19
- 2
src/main/kotlin/com/dmdirc/ktirc/model/IrcMessage.kt View File

@@ -1,9 +1,26 @@
1 1
 package com.dmdirc.ktirc.model
2 2
 
3
-class IrcMessage(val tags: Map<MessageTag, String>, val prefix: ByteArray?, val command: String, val params: List<ByteArray>)
3
+import java.time.Instant
4
+import java.time.LocalDateTime
5
+import java.time.ZoneId
6
+
7
+class IrcMessage(val tags: Map<MessageTag, String>, val prefix: ByteArray?, val command: String, val params: List<ByteArray>) {
8
+
9
+    companion object {
10
+        internal var currentTimeZoneProvider = { ZoneId.systemDefault() }
11
+        internal var currentTimeProvider = { LocalDateTime.now(currentTimeZoneProvider()) }
12
+    }
13
+
14
+    val time: LocalDateTime = if (MessageTag.ServerTime in tags) {
15
+        LocalDateTime.ofInstant(Instant.parse(tags[MessageTag.ServerTime]), currentTimeZoneProvider())
16
+    } else {
17
+        currentTimeProvider()
18
+    }
19
+
20
+}
4 21
 
5 22
 sealed class MessageTag(val name: String) {
6
-    object AccountName: MessageTag("account")
23
+    object AccountName : MessageTag("account")
7 24
     object ServerTime : MessageTag("time")
8 25
 }
9 26
 

+ 10
- 7
src/test/kotlin/com/dmdirc/ktirc/IrcClientTest.kt View File

@@ -4,15 +4,13 @@ import com.dmdirc.ktirc.events.EventHandler
4 4
 import com.dmdirc.ktirc.events.ServerWelcome
5 5
 import com.dmdirc.ktirc.io.CaseMapping
6 6
 import com.dmdirc.ktirc.io.LineBufferedSocket
7
-import com.dmdirc.ktirc.model.Profile
8
-import com.dmdirc.ktirc.model.Server
9
-import com.dmdirc.ktirc.model.ServerFeature
10
-import com.dmdirc.ktirc.model.User
7
+import com.dmdirc.ktirc.model.*
11 8
 import com.nhaarman.mockitokotlin2.*
12 9
 import kotlinx.coroutines.channels.Channel
13 10
 import kotlinx.coroutines.launch
14 11
 import kotlinx.coroutines.runBlocking
15 12
 import org.junit.jupiter.api.Assertions.*
13
+import org.junit.jupiter.api.BeforeEach
16 14
 import org.junit.jupiter.api.Test
17 15
 import org.junit.jupiter.api.assertThrows
18 16
 
@@ -39,6 +37,11 @@ internal class IrcClientImplTest {
39 37
 
40 38
     private val mockEventHandler = mock<EventHandler>()
41 39
 
40
+    @BeforeEach
41
+    fun setUp() {
42
+        IrcMessage.currentTimeProvider = { TestConstants.time }
43
+    }
44
+
42 45
     @Test
43 46
     fun `IrcClientImpl uses socket factory to create a new socket on connect`() {
44 47
         runBlocking {
@@ -117,7 +120,7 @@ internal class IrcClientImplTest {
117 120
 
118 121
             client.connect()
119 122
 
120
-            verify(mockEventHandler).processEvent(client, ServerWelcome("acidBurn"))
123
+            verify(mockEventHandler).processEvent(same(client), isA<ServerWelcome>())
121 124
         }
122 125
     }
123 126
 
@@ -136,7 +139,7 @@ internal class IrcClientImplTest {
136 139
 
137 140
             client.connect()
138 141
 
139
-            verify(mockEventHandler, never()).processEvent(client, ServerWelcome("acidBurn"))
142
+            verify(mockEventHandler, never()).processEvent(client, ServerWelcome(TestConstants.time, "acidBurn"))
140 143
         }
141 144
     }
142 145
 
@@ -155,7 +158,7 @@ internal class IrcClientImplTest {
155 158
 
156 159
             client.connect()
157 160
 
158
-            verify(mockEventHandler, never()).processEvent(client, ServerWelcome("acidBurn"))
161
+            verify(mockEventHandler, never()).processEvent(client, ServerWelcome(TestConstants.time, "acidBurn"))
159 162
         }
160 163
     }
161 164
 

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

@@ -0,0 +1,7 @@
1
+package com.dmdirc.ktirc
2
+
3
+import java.time.LocalDateTime
4
+
5
+object TestConstants {
6
+    val time: LocalDateTime = LocalDateTime.parse("1995-09-15T09:00:00")
7
+}

+ 7
- 6
src/test/kotlin/com/dmdirc/ktirc/events/CapabilitiesHandlerTest.kt View File

@@ -1,6 +1,7 @@
1 1
 package com.dmdirc.ktirc.events
2 2
 
3 3
 import com.dmdirc.ktirc.IrcClient
4
+import com.dmdirc.ktirc.TestConstants
4 5
 import com.dmdirc.ktirc.model.CapabilitiesNegotiationState
5 6
 import com.dmdirc.ktirc.model.Capability
6 7
 import com.dmdirc.ktirc.model.ServerState
@@ -23,7 +24,7 @@ internal class CapabilitiesHandlerTest {
23 24
     @Test
24 25
     fun `CapabilitiesHandler adds new capabilities to the state`() {
25 26
         runBlocking {
26
-            handler.processEvent(ircClient, ServerCapabilitiesReceived(hashMapOf(
27
+            handler.processEvent(ircClient, ServerCapabilitiesReceived(TestConstants.time, hashMapOf(
27 28
                     Capability.EchoMessages to "",
28 29
                     Capability.HostsInNamesReply to "123"
29 30
             )))
@@ -37,7 +38,7 @@ internal class CapabilitiesHandlerTest {
37 38
     @Test
38 39
     fun `CapabilitiesHandler updates negotiation state when capabilities finished`() {
39 40
         runBlocking {
40
-            handler.processEvent(ircClient, ServerCapabilitiesFinished)
41
+            handler.processEvent(ircClient, ServerCapabilitiesFinished(TestConstants.time))
41 42
 
42 43
             assertEquals(CapabilitiesNegotiationState.AWAITING_ACK, serverState.capabilities.negotiationState)
43 44
         }
@@ -49,7 +50,7 @@ internal class CapabilitiesHandlerTest {
49 50
             serverState.capabilities.advertisedCapabilities[Capability.EchoMessages] = ""
50 51
             serverState.capabilities.advertisedCapabilities[Capability.AccountChangeMessages] = ""
51 52
 
52
-            handler.processEvent(ircClient, ServerCapabilitiesFinished)
53
+            handler.processEvent(ircClient, ServerCapabilitiesFinished(TestConstants.time))
53 54
 
54 55
             verify(ircClient).send(argThat { equals("CAP REQ :echo-message account-notify") || equals("CAP REQ :account-notify echo-message") })
55 56
         }
@@ -58,7 +59,7 @@ internal class CapabilitiesHandlerTest {
58 59
     @Test
59 60
     fun `CapabilitiesHandler sends END when capabilities acknowledged`() {
60 61
         runBlocking {
61
-            handler.processEvent(ircClient, ServerCapabilitiesAcknowledged(hashMapOf(
62
+            handler.processEvent(ircClient, ServerCapabilitiesAcknowledged(TestConstants.time, hashMapOf(
62 63
                     Capability.EchoMessages to "",
63 64
                     Capability.HostsInNamesReply to "123"
64 65
             )))
@@ -70,7 +71,7 @@ internal class CapabilitiesHandlerTest {
70 71
     @Test
71 72
     fun `CapabilitiesHandler updates negotiation state when capabilities acknowledged`() {
72 73
         runBlocking {
73
-            handler.processEvent(ircClient, ServerCapabilitiesAcknowledged(hashMapOf(
74
+            handler.processEvent(ircClient, ServerCapabilitiesAcknowledged(TestConstants.time, hashMapOf(
74 75
                     Capability.EchoMessages to "",
75 76
                     Capability.HostsInNamesReply to "123"
76 77
             )))
@@ -82,7 +83,7 @@ internal class CapabilitiesHandlerTest {
82 83
     @Test
83 84
     fun `CapabilitiesHandler stores enabled caps when capabilities acknowledged`() {
84 85
         runBlocking {
85
-            handler.processEvent(ircClient, ServerCapabilitiesAcknowledged(hashMapOf(
86
+            handler.processEvent(ircClient, ServerCapabilitiesAcknowledged(TestConstants.time, hashMapOf(
86 87
                     Capability.EchoMessages to "",
87 88
                     Capability.HostsInNamesReply to "123"
88 89
             )))

+ 19
- 18
src/test/kotlin/com/dmdirc/ktirc/events/ChannelStateHandlerTest.kt View File

@@ -1,6 +1,7 @@
1 1
 package com.dmdirc.ktirc.events
2 2
 
3 3
 import com.dmdirc.ktirc.IrcClient
4
+import com.dmdirc.ktirc.TestConstants
4 5
 import com.dmdirc.ktirc.io.CaseMapping
5 6
 import com.dmdirc.ktirc.model.*
6 7
 import com.nhaarman.mockitokotlin2.doReturn
@@ -22,13 +23,13 @@ internal class ChannelStateHandlerTest {
22 23
 
23 24
     @Test
24 25
     fun `ChannelStateHandler creates new state object for local joins`() = runBlocking {
25
-        handler.processEvent(ircClient, ChannelJoined(User("acidburn", "libby", "root.localhost"), "#thegibson"))
26
+        handler.processEvent(ircClient, ChannelJoined(TestConstants.time, User("acidburn", "libby", "root.localhost"), "#thegibson"))
26 27
         assertTrue("#thegibson" in channelStateMap)
27 28
     }
28 29
 
29 30
     @Test
30 31
     fun `ChannelStateHandler does not create new state object for remote joins`() = runBlocking {
31
-        handler.processEvent(ircClient, ChannelJoined(User("zerocool", "dade", "root.localhost"), "#thegibson"))
32
+        handler.processEvent(ircClient, ChannelJoined(TestConstants.time, User("zerocool", "dade", "root.localhost"), "#thegibson"))
32 33
         assertFalse("#thegibson" in channelStateMap)
33 34
     }
34 35
 
@@ -36,7 +37,7 @@ internal class ChannelStateHandlerTest {
36 37
     fun `ChannelStateHandler adds joiners to channel state`() = runBlocking {
37 38
         channelStateMap += ChannelState("#thegibson") { CaseMapping.Rfc }
38 39
 
39
-        handler.processEvent(ircClient, ChannelJoined(User("zerocool", "dade", "root.localhost"), "#thegibson"))
40
+        handler.processEvent(ircClient, ChannelJoined(TestConstants.time, User("zerocool", "dade", "root.localhost"), "#thegibson"))
40 41
 
41 42
         assertTrue("zerocool" in channelStateMap["#thegibson"]?.users!!)
42 43
     }
@@ -48,7 +49,7 @@ internal class ChannelStateHandlerTest {
48 49
         channel.users += ChannelUser("thePlague")
49 50
         channelStateMap += channel
50 51
 
51
-        handler.processEvent(ircClient, ChannelNamesReceived("#thegibson", listOf("zeroCool")))
52
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("zeroCool")))
52 53
 
53 54
         assertEquals(1, channel.users.count())
54 55
         assertNotNull(channel.users["zeroCool"])
@@ -59,9 +60,9 @@ internal class ChannelStateHandlerTest {
59 60
         val channel = ChannelState("#thegibson") { CaseMapping.Rfc }
60 61
         channelStateMap += channel
61 62
 
62
-        handler.processEvent(ircClient, ChannelNamesReceived("#thegibson", listOf("zeroCool")))
63
-        handler.processEvent(ircClient, ChannelNamesReceived("#thegibson", listOf("acidBurn")))
64
-        handler.processEvent(ircClient, ChannelNamesReceived("#thegibson", listOf("thePlague")))
63
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("zeroCool")))
64
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("acidBurn")))
65
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("thePlague")))
65 66
 
66 67
         assertEquals(3, channel.users.count())
67 68
         assertNotNull(channel.users["zeroCool"])
@@ -74,10 +75,10 @@ internal class ChannelStateHandlerTest {
74 75
         val channel = ChannelState("#thegibson") { CaseMapping.Rfc }
75 76
         channelStateMap += channel
76 77
 
77
-        handler.processEvent(ircClient, ChannelNamesReceived("#thegibson", listOf("zeroCool")))
78
-        handler.processEvent(ircClient, ChannelNamesFinished("#thegibson"))
79
-        handler.processEvent(ircClient, ChannelNamesReceived("#thegibson", listOf("acidBurn")))
80
-        handler.processEvent(ircClient, ChannelNamesReceived("#thegibson", listOf("thePlague")))
78
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("zeroCool")))
79
+        handler.processEvent(ircClient, ChannelNamesFinished(TestConstants.time, "#thegibson"))
80
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("acidBurn")))
81
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("thePlague")))
81 82
 
82 83
         assertEquals(2, channel.users.count())
83 84
         assertNotNull(channel.users["acidBurn"])
@@ -90,8 +91,8 @@ internal class ChannelStateHandlerTest {
90 91
         channelStateMap += channel
91 92
         serverState.features[ServerFeature.ModePrefixes] = ModePrefixMapping("ov", "@+")
92 93
 
93
-        handler.processEvent(ircClient, ChannelNamesReceived("#thegibson", listOf("@zeroCool", "@+acidBurn", "+thePlague", "cerealKiller")))
94
-        handler.processEvent(ircClient, ChannelNamesFinished("#thegibson"))
94
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("@zeroCool", "@+acidBurn", "+thePlague", "cerealKiller")))
95
+        handler.processEvent(ircClient, ChannelNamesFinished(TestConstants.time, "#thegibson"))
95 96
 
96 97
         assertEquals(4, channel.users.count())
97 98
         assertEquals("o", channel.users["zeroCool"]?.modes)
@@ -106,8 +107,8 @@ internal class ChannelStateHandlerTest {
106 107
         channelStateMap += channel
107 108
         serverState.features[ServerFeature.ModePrefixes] = ModePrefixMapping("ov", "@+")
108 109
 
109
-        handler.processEvent(ircClient, ChannelNamesReceived("#thegibson", listOf("@zeroCool!dade@root.localhost", "+acidBurn!libby@root.localhost")))
110
-        handler.processEvent(ircClient, ChannelNamesFinished("#thegibson"))
110
+        handler.processEvent(ircClient, ChannelNamesReceived(TestConstants.time, "#thegibson", listOf("@zeroCool!dade@root.localhost", "+acidBurn!libby@root.localhost")))
111
+        handler.processEvent(ircClient, ChannelNamesFinished(TestConstants.time, "#thegibson"))
111 112
 
112 113
         assertEquals(2, channel.users.count())
113 114
         assertEquals("o", channel.users["zeroCool"]?.modes)
@@ -119,7 +120,7 @@ internal class ChannelStateHandlerTest {
119 120
         val channel = ChannelState("#thegibson") { CaseMapping.Rfc }
120 121
         channelStateMap += channel
121 122
 
122
-        handler.processEvent(ircClient, ChannelParted(User("acidburn", "libby", "root.localhost"), "#thegibson"))
123
+        handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("acidburn", "libby", "root.localhost"), "#thegibson"))
123 124
 
124 125
         assertFalse("#thegibson" in channelStateMap)
125 126
     }
@@ -130,7 +131,7 @@ internal class ChannelStateHandlerTest {
130 131
         channel.users += ChannelUser("ZeroCool")
131 132
         channelStateMap += channel
132 133
 
133
-        handler.processEvent(ircClient, ChannelParted(User("zerocool", "dade", "root.localhost"), "#thegibson"))
134
+        handler.processEvent(ircClient, ChannelParted(TestConstants.time, User("zerocool", "dade", "root.localhost"), "#thegibson"))
134 135
 
135 136
         assertFalse("zerocool" in channel.users)
136 137
     }
@@ -152,7 +153,7 @@ internal class ChannelStateHandlerTest {
152 153
             channelStateMap += this
153 154
         }
154 155
 
155
-        handler.processEvent(ircClient, UserQuit(User("zerocool", "dade", "root.localhost")))
156
+        handler.processEvent(ircClient, UserQuit(TestConstants.time, User("zerocool", "dade", "root.localhost")))
156 157
 
157 158
         assertFalse("zerocool" in channelStateMap["#thegibson"]!!.users)
158 159
         assertFalse("zerocool" in channelStateMap["#dumpsterdiving"]!!.users)

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

@@ -1,6 +1,7 @@
1 1
 package com.dmdirc.ktirc.events
2 2
 
3 3
 import com.dmdirc.ktirc.IrcClient
4
+import com.dmdirc.ktirc.TestConstants
4 5
 import com.nhaarman.mockitokotlin2.mock
5 6
 import com.nhaarman.mockitokotlin2.verify
6 7
 import kotlinx.coroutines.runBlocking
@@ -14,7 +15,7 @@ internal class PingHandlerTest {
14 15
 
15 16
     @Test
16 17
     fun `PingHandler responses to pings with a pong`() = runBlocking {
17
-        handler.processEvent(ircClient, PingReceived("the_plague".toByteArray()))
18
+        handler.processEvent(ircClient, PingReceived(TestConstants.time, "the_plague".toByteArray()))
18 19
         verify(ircClient).send("PONG :the_plague")
19 20
     }
20 21
 

+ 3
- 2
src/test/kotlin/com/dmdirc/ktirc/events/ServerStateHandlerTest.kt View File

@@ -1,6 +1,7 @@
1 1
 package com.dmdirc.ktirc.events
2 2
 
3 3
 import com.dmdirc.ktirc.IrcClient
4
+import com.dmdirc.ktirc.TestConstants
4 5
 import com.dmdirc.ktirc.model.ServerFeature
5 6
 import com.dmdirc.ktirc.model.ServerFeatureMap
6 7
 import com.dmdirc.ktirc.model.ServerState
@@ -21,7 +22,7 @@ internal class ServerStateHandlerTest {
21 22
 
22 23
     @Test
23 24
     fun `ServerStateHandler sets local nickname on welcome event`() = runBlocking {
24
-        handler.processEvent(ircClient, ServerWelcome("acidBurn"))
25
+        handler.processEvent(ircClient, ServerWelcome(TestConstants.time, "acidBurn"))
25 26
         assertEquals("acidBurn", serverState.localNickname)
26 27
     }
27 28
 
@@ -31,7 +32,7 @@ internal class ServerStateHandlerTest {
31 32
         features[ServerFeature.ChannelModes] = "abc"
32 33
         features[ServerFeature.WhoxSupport] = true
33 34
 
34
-        handler.processEvent(ircClient, ServerFeaturesUpdated(features))
35
+        handler.processEvent(ircClient, ServerFeaturesUpdated(TestConstants.time, features))
35 36
 
36 37
         assertEquals("abc", serverState.features[ServerFeature.ChannelModes])
37 38
         assertEquals(true, serverState.features[ServerFeature.WhoxSupport])

+ 6
- 5
src/test/kotlin/com/dmdirc/ktirc/io/MessageHandlerTest.kt View File

@@ -1,6 +1,7 @@
1 1
 package com.dmdirc.ktirc.io
2 2
 
3 3
 import com.dmdirc.ktirc.IrcClient
4
+import com.dmdirc.ktirc.TestConstants
4 5
 import com.dmdirc.ktirc.events.EventHandler
5 6
 import com.dmdirc.ktirc.events.ServerConnected
6 7
 import com.dmdirc.ktirc.events.ServerWelcome
@@ -66,7 +67,7 @@ internal class MessageHandlerTest {
66 67
         val eventHandler2 = mock<EventHandler>()
67 68
         val handler = MessageHandler(listOf(joinProcessor, nickProcessor), mutableListOf(eventHandler1, eventHandler2))
68 69
         val joinMessage = IrcMessage(emptyMap(), null, "JOIN", emptyList())
69
-        whenever(joinProcessor.process(any())).thenReturn(listOf(ServerConnected, ServerWelcome("abc")))
70
+        whenever(joinProcessor.process(any())).thenReturn(listOf(ServerConnected(TestConstants.time), ServerWelcome(TestConstants.time, "abc")))
70 71
 
71 72
         with(Channel<IrcMessage>(1)) {
72 73
             send(joinMessage)
@@ -74,10 +75,10 @@ internal class MessageHandlerTest {
74 75
             handler.processMessages(ircClient, this)
75 76
         }
76 77
 
77
-        verify(eventHandler1).processEvent(ircClient, ServerConnected)
78
-        verify(eventHandler1).processEvent(ircClient, ServerWelcome("abc"))
79
-        verify(eventHandler2).processEvent(ircClient, ServerConnected)
80
-        verify(eventHandler2).processEvent(ircClient, ServerWelcome("abc"))
78
+        verify(eventHandler1).processEvent(same(ircClient), isA<ServerConnected>())
79
+        verify(eventHandler1).processEvent(same(ircClient), isA<ServerWelcome>())
80
+        verify(eventHandler2).processEvent(same(ircClient), isA<ServerConnected>())
81
+        verify(eventHandler2).processEvent(same(ircClient), isA<ServerWelcome>())
81 82
     }
82 83
 
83 84
 }

+ 3
- 4
src/test/kotlin/com/dmdirc/ktirc/io/MessageParserTest.kt View File

@@ -39,11 +39,10 @@ internal class MessageParserTest {
39 39
     }
40 40
 
41 41
     @Test
42
-    fun `Parses tags without values`() {
43
-        val parsed = MessageParser().parse("@time;account= :zeroCool!dade@root.localhost PRIVMSG #chat :Hack the planet!".toByteArray())
42
+    fun `Parses tag without values`() {
43
+        val parsed = MessageParser().parse("@account= :zeroCool!dade@root.localhost PRIVMSG #chat :Hack the planet!".toByteArray())
44 44
 
45
-        assertEquals(2, parsed.tags.size)
46
-        assertEquals("", parsed.tags[MessageTag.ServerTime])
45
+        assertEquals(1, parsed.tags.size)
47 46
         assertEquals("", parsed.tags[MessageTag.AccountName])
48 47
     }
49 48
 

+ 11
- 2
src/test/kotlin/com/dmdirc/ktirc/messages/JoinProcessorTest.kt View File

@@ -1,19 +1,28 @@
1 1
 package com.dmdirc.ktirc.messages
2 2
 
3
-import com.dmdirc.ktirc.events.ChannelJoined
3
+import com.dmdirc.ktirc.TestConstants
4 4
 import com.dmdirc.ktirc.model.IrcMessage
5 5
 import com.dmdirc.ktirc.model.User
6 6
 import org.junit.jupiter.api.Assertions.assertEquals
7
+import org.junit.jupiter.api.BeforeEach
7 8
 import org.junit.jupiter.api.Test
8 9
 
9 10
 internal class JoinProcessorTest {
10 11
 
12
+    @BeforeEach
13
+    fun setUp() {
14
+        IrcMessage.currentTimeProvider = { TestConstants.time }
15
+    }
16
+
11 17
     @Test
12 18
     fun `JoinProcessor raises join event`() {
13 19
         val events = JoinProcessor().process(
14 20
                 IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "JOIN", listOf("#crashandburn".toByteArray())))
15 21
         assertEquals(1, events.size)
16
-        assertEquals(ChannelJoined(User("acidburn", "libby", "root.localhost"), "#crashandburn"), events[0])
22
+
23
+        assertEquals(TestConstants.time, events[0].time)
24
+        assertEquals(User("acidburn", "libby", "root.localhost"), events[0].user)
25
+        assertEquals("#crashandburn", events[0].channel)
17 26
     }
18 27
 
19 28
     @Test

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

@@ -1,34 +1,48 @@
1 1
 package com.dmdirc.ktirc.messages
2 2
 
3
-import com.dmdirc.ktirc.events.ChannelParted
3
+import com.dmdirc.ktirc.TestConstants
4 4
 import com.dmdirc.ktirc.model.IrcMessage
5 5
 import com.dmdirc.ktirc.model.User
6
-import org.junit.jupiter.api.Assertions
6
+import org.junit.jupiter.api.Assertions.assertEquals
7
+import org.junit.jupiter.api.BeforeEach
7 8
 import org.junit.jupiter.api.Test
8 9
 
9 10
 internal class PartProcessorTest {
10 11
 
12
+    @BeforeEach
13
+    fun setUp() {
14
+        IrcMessage.currentTimeProvider = { TestConstants.time }
15
+    }
16
+
11 17
     @Test
12 18
     fun `PartProcessor raises part event without message`() {
13 19
         val events = PartProcessor().process(
14 20
                 IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "PART", listOf("#crashandburn".toByteArray())))
15
-        Assertions.assertEquals(1, events.size)
16
-        Assertions.assertEquals(ChannelParted(User("acidburn", "libby", "root.localhost"), "#crashandburn"), events[0])
21
+        assertEquals(1, events.size)
22
+
23
+        assertEquals(TestConstants.time, events[0].time)
24
+        assertEquals(User("acidburn", "libby", "root.localhost"), events[0].user)
25
+        assertEquals("#crashandburn", events[0].channel)
26
+        assertEquals("", events[0].reason)
17 27
     }
18 28
 
19 29
     @Test
20 30
     fun `PartProcessor raises part event with message`() {
21 31
         val events = PartProcessor().process(
22 32
                 IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "PART", listOf("#crashandburn".toByteArray(), "Hack the planet!".toByteArray())))
23
-        Assertions.assertEquals(1, events.size)
24
-        Assertions.assertEquals(ChannelParted(User("acidburn", "libby", "root.localhost"), "#crashandburn", "Hack the planet!"), events[0])
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("#crashandburn", events[0].channel)
38
+        assertEquals("Hack the planet!", events[0].reason)
25 39
     }
26 40
 
27 41
     @Test
28 42
     fun `PartProcessor does nothing if prefix missing`() {
29 43
         val events = JoinProcessor().process(
30 44
                 IrcMessage(emptyMap(), null, "PART", listOf("#crashandburn".toByteArray())))
31
-        Assertions.assertEquals(0, events.size)
45
+        assertEquals(0, events.size)
32 46
     }
33 47
 
34 48
 }

+ 15
- 5
src/test/kotlin/com/dmdirc/ktirc/messages/PrivmsgProcessorTest.kt View File

@@ -1,25 +1,35 @@
1 1
 package com.dmdirc.ktirc.messages
2 2
 
3
-import com.dmdirc.ktirc.events.MessageReceived
3
+import com.dmdirc.ktirc.TestConstants
4 4
 import com.dmdirc.ktirc.model.IrcMessage
5 5
 import com.dmdirc.ktirc.model.User
6
-import org.junit.jupiter.api.Assertions
6
+import org.junit.jupiter.api.Assertions.assertEquals
7
+import org.junit.jupiter.api.BeforeEach
7 8
 import org.junit.jupiter.api.Test
8 9
 
9 10
 internal class PrivmsgProcessorTest {
10 11
 
12
+    @BeforeEach
13
+    fun setUp() {
14
+        IrcMessage.currentTimeProvider = { TestConstants.time }
15
+    }
16
+
11 17
     @Test
12 18
     fun `PrivsgProcessor raises message received event`() {
13 19
         val events = PrivmsgProcessor().process(
14 20
                 IrcMessage(emptyMap(), "acidburn!libby@root.localhost".toByteArray(), "PRIVMSG", listOf("#crashandburn".toByteArray(), "hack the planet!".toByteArray())))
15
-        Assertions.assertEquals(1, events.size)
16
-        Assertions.assertEquals(MessageReceived(User("acidburn", "libby", "root.localhost"), "#crashandburn", "hack the planet!"), events[0])
21
+        assertEquals(1, events.size)
22
+
23
+        assertEquals(TestConstants.time, events[0].time)
24
+        assertEquals(User("acidburn", "libby", "root.localhost"), events[0].user)
25
+        assertEquals("#crashandburn", events[0].target)
26
+        assertEquals("hack the planet!", events[0].message)
17 27
     }
18 28
 
19 29
     @Test
20 30
     fun `PrivsgProcessor does nothing if prefix missing`() {
21 31
         val events = PrivmsgProcessor().process(
22 32
                 IrcMessage(emptyMap(), null, "PRIVMSG", listOf("#crashandburn".toByteArray(), "hack the planet!".toByteArray())))
23
-        Assertions.assertEquals(0, events.size)
33
+        assertEquals(0, events.size)
24 34
     }
25 35
 }

+ 19
- 7
src/test/kotlin/com/dmdirc/ktirc/messages/QuitProcessorTest.kt View File

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

+ 10
- 3
src/test/kotlin/com/dmdirc/ktirc/messages/WelcomeProcessorTest.kt View File

@@ -1,16 +1,21 @@
1 1
 package com.dmdirc.ktirc.messages
2 2
 
3
-import com.dmdirc.ktirc.events.IrcEvent
4
-import com.dmdirc.ktirc.events.ServerWelcome
3
+import com.dmdirc.ktirc.TestConstants
5 4
 import com.dmdirc.ktirc.model.IrcMessage
6 5
 import org.junit.jupiter.api.Assertions.assertEquals
7 6
 import org.junit.jupiter.api.Assertions.assertTrue
7
+import org.junit.jupiter.api.BeforeEach
8 8
 import org.junit.jupiter.api.Test
9 9
 
10 10
 internal class WelcomeProcessorTest {
11 11
 
12 12
     private val processor = WelcomeProcessor()
13 13
 
14
+    @BeforeEach
15
+    fun setUp() {
16
+        IrcMessage.currentTimeProvider = { TestConstants.time }
17
+    }
18
+
14 19
     @Test
15 20
     fun `WelcomeProcessor can handle 001s`() {
16 21
         assertTrue(processor.commands.contains("001")) { "WelcomeProcessor should handle 001 messages" }
@@ -21,7 +26,9 @@ internal class WelcomeProcessorTest {
21 26
         val events = processor.process(IrcMessage(emptyMap(), ":thegibson.com".toByteArray(), "001", listOf(
22 27
                 "acidBurn".toByteArray(),
23 28
                 "Welcome to the Internet Relay Network, acidBurn!burn@hacktheplanet.com".toByteArray())))
24
-        assertEquals(listOf<IrcEvent>(ServerWelcome("acidBurn")), events)
29
+        assertEquals(1, events.size)
30
+        assertEquals(TestConstants.time, events[0].time)
31
+        assertEquals("acidBurn", events[0].localNick)
25 32
     }
26 33
 
27 34
 }

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

@@ -0,0 +1,32 @@
1
+package com.dmdirc.ktirc.model
2
+
3
+import com.dmdirc.ktirc.TestConstants
4
+import org.junit.jupiter.api.Assertions.assertEquals
5
+import org.junit.jupiter.api.Test
6
+import java.time.LocalDateTime
7
+import java.time.ZoneId
8
+
9
+internal class IrcMessageTest {
10
+
11
+    @Test
12
+    fun `Gets UTC time from ServerTime tag if present`() {
13
+        IrcMessage.currentTimeZoneProvider = { ZoneId.of("Z") }
14
+        val message = IrcMessage(hashMapOf(MessageTag.ServerTime to "1995-09-15T09:00:00.0000Z"), null, "", emptyList())
15
+        assertEquals(LocalDateTime.parse("1995-09-15T09:00:00"), message.time)
16
+    }
17
+
18
+    @Test
19
+    fun `Converts time in ServerTime tag to local timezone`() {
20
+        IrcMessage.currentTimeZoneProvider = { ZoneId.of("America/New_York") }
21
+        val message = IrcMessage(hashMapOf(MessageTag.ServerTime to "1995-09-15T09:00:00.0000Z"), null, "", emptyList())
22
+        assertEquals(LocalDateTime.parse("1995-09-15T05:00:00"), message.time)
23
+    }
24
+
25
+    @Test
26
+    fun `Uses current local time if no tag present`() {
27
+        IrcMessage.currentTimeProvider = { TestConstants.time }
28
+        val message = IrcMessage(emptyMap(), null, "", emptyList())
29
+        assertEquals(LocalDateTime.parse("1995-09-15T09:00:00"), message.time)
30
+    }
31
+
32
+}

Loading…
Cancel
Save