You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

IrcClientTest.kt 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package com.dmdirc.ktirc
  2. import com.dmdirc.ktirc.io.CaseMapping
  3. import com.dmdirc.ktirc.io.LineBufferedSocket
  4. import com.dmdirc.ktirc.model.Profile
  5. import com.dmdirc.ktirc.model.Server
  6. import com.dmdirc.ktirc.model.ServerFeature
  7. import com.dmdirc.ktirc.model.User
  8. import com.nhaarman.mockitokotlin2.*
  9. import kotlinx.coroutines.channels.Channel
  10. import kotlinx.coroutines.runBlocking
  11. import org.junit.jupiter.api.Assertions.*
  12. import org.junit.jupiter.api.Test
  13. import org.junit.jupiter.api.assertThrows
  14. internal class IrcClientImplTest {
  15. companion object {
  16. private const val HOST = "thegibson.com"
  17. private const val PORT = 12345
  18. private const val NICK = "AcidBurn"
  19. private const val REAL_NAME = "Kate Libby"
  20. private const val USER_NAME = "acidb"
  21. private const val PASSWORD = "HackThePlanet"
  22. }
  23. private val readLineChannel = Channel<ByteArray>(10)
  24. private val mockSocket = mock<LineBufferedSocket> {
  25. on { readLines(any()) } doReturn readLineChannel
  26. }
  27. private val mockSocketFactory = mock<(String, Int) -> LineBufferedSocket> {
  28. on { invoke(HOST, PORT) } doReturn mockSocket
  29. }
  30. @Test
  31. fun `IrcClientImpl uses socket factory to create a new socket on connect`() {
  32. runBlocking {
  33. val client = IrcClientImpl(Server(HOST, PORT), Profile(NICK, REAL_NAME, USER_NAME))
  34. client.socketFactory = mockSocketFactory
  35. readLineChannel.close()
  36. client.connect()
  37. verify(mockSocketFactory).invoke(HOST, PORT)
  38. }
  39. }
  40. @Test
  41. fun `IrcClientImpl throws if socket already exists`() {
  42. runBlocking {
  43. val client = IrcClientImpl(Server(HOST, PORT), Profile(NICK, REAL_NAME, USER_NAME))
  44. client.socketFactory = mockSocketFactory
  45. readLineChannel.close()
  46. client.connect()
  47. assertThrows<IllegalStateException> {
  48. runBlocking {
  49. client.connect()
  50. }
  51. }
  52. }
  53. }
  54. @Test
  55. fun `IrcClientImpl sends basic connection strings`() {
  56. runBlocking {
  57. val client = IrcClientImpl(Server(HOST, PORT), Profile(NICK, REAL_NAME, USER_NAME))
  58. client.socketFactory = mockSocketFactory
  59. readLineChannel.close()
  60. client.connect()
  61. with(inOrder(mockSocket).verify(mockSocket)) {
  62. sendLine("NICK :$NICK")
  63. sendLine("USER $USER_NAME localhost $HOST :$REAL_NAME")
  64. }
  65. }
  66. }
  67. @Test
  68. fun `IrcClientImpl sends password first, when present`() {
  69. runBlocking {
  70. val client = IrcClientImpl(Server(HOST, PORT, password = PASSWORD), Profile(NICK, REAL_NAME, USER_NAME))
  71. client.socketFactory = mockSocketFactory
  72. readLineChannel.close()
  73. client.connect()
  74. with(inOrder(mockSocket).verify(mockSocket)) {
  75. sendLine("PASS :$PASSWORD")
  76. sendLine("NICK :$NICK")
  77. }
  78. }
  79. }
  80. @Test
  81. fun `IrcClient gets case mapping from server features`() {
  82. val client = IrcClientImpl(Server(HOST, PORT), Profile(NICK, REAL_NAME, USER_NAME))
  83. client.serverState.features[ServerFeature.ServerCaseMapping] = CaseMapping.RfcStrict
  84. assertEquals(CaseMapping.RfcStrict, client.caseMapping)
  85. }
  86. @Test
  87. fun `IrcClient indicates if user is local user or not`() {
  88. val client = IrcClientImpl(Server(HOST, PORT), Profile(NICK, REAL_NAME, USER_NAME))
  89. client.serverState.localNickname = "[acidBurn]"
  90. assertTrue(client.isLocalUser(User("{acidBurn}", "libby", "root.localhost")))
  91. assertFalse(client.isLocalUser(User("acid-Burn", "libby", "root.localhost")))
  92. }
  93. @Test
  94. fun `IrcClient uses current case mapping to check local user`() {
  95. val client = IrcClientImpl(Server(HOST, PORT), Profile(NICK, REAL_NAME, USER_NAME))
  96. client.serverState.localNickname = "[acidBurn]"
  97. client.serverState.features[ServerFeature.ServerCaseMapping] = CaseMapping.Ascii
  98. assertFalse(client.isLocalUser(User("{acidBurn}", "libby", "root.localhost")))
  99. }
  100. }