Mirror of github.com/gissleh/irc
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.

239 lines
9.8 KiB

  1. package irc_test
  2. import (
  3. "context"
  4. "errors"
  5. "testing"
  6. "git.aiterp.net/gisle/irc"
  7. "git.aiterp.net/gisle/irc/handlers"
  8. "git.aiterp.net/gisle/irc/internal/irctest"
  9. )
  10. func TestClient(t *testing.T) {
  11. irc.Handle(handlers.Input)
  12. irc.Handle(handlers.MRoleplay)
  13. client := irc.New(context.Background(), irc.Config{
  14. Nick: "Test",
  15. User: "Tester",
  16. RealName: "...",
  17. Alternatives: []string{"Test2", "Test3", "Test4", "Test768"},
  18. })
  19. t.Logf("Client.ID = %#+v", client.ID())
  20. if client.ID() == "" {
  21. t.Fail()
  22. }
  23. interaction := irctest.Interaction{
  24. Strict: false,
  25. Lines: []irctest.InteractionLine{
  26. {Kind: 'C', Data: "CAP LS 302"},
  27. {Kind: 'C', Data: "NICK Test"},
  28. {Kind: 'C', Data: "USER Tester 8 * :..."},
  29. {Kind: 'S', Data: ":testserver.example.com CAP * LS :multi-prefix userhost-in-names"},
  30. {Kind: 'C', Data: "CAP REQ :multi-prefix userhost-in-names"},
  31. {Kind: 'S', Data: ":testserver.example.com CAP * ACK :multi-prefix userhost-in-names"},
  32. {Kind: 'C', Data: "CAP END"},
  33. {Kind: 'S', Data: ":testserver.example.com 443 * Test :Nick is not available"},
  34. {Kind: 'C', Data: "NICK Test2"},
  35. {Kind: 'S', Data: ":testserver.example.com 443 * Test2 :Nick is not available"},
  36. {Kind: 'C', Data: "NICK Test3"},
  37. {Kind: 'S', Data: ":testserver.example.com 443 * Test3 :Nick is not available"},
  38. {Kind: 'C', Data: "NICK Test4"},
  39. {Kind: 'S', Data: ":testserver.example.com 443 * Test4 :Nick is not available"},
  40. {Kind: 'C', Data: "NICK Test768"},
  41. {Kind: 'S', Data: ":testserver.example.com 001 Test768 :Welcome to the TestServer Internet Relay Chat Network test"},
  42. {Kind: 'C', Data: "WHO Test768*"},
  43. {Kind: 'S', Data: ":testserver.example.com 002 Test768 :Your host is testserver.example.com[testserver.example.com/6667], running version charybdis-4-rc3"},
  44. {Kind: 'S', Data: ":testserver.example.com 003 Test768 :This server was created Fri Nov 25 2016 at 17:28:20 CET"},
  45. {Kind: 'S', Data: ":testserver.example.com 004 Test768 testserver.example.com charybdis-4-rc3 DQRSZagiloswxz CFILNPQbcefgijklmnopqrstvz bkloveqjfI"},
  46. {Kind: 'S', Data: ":testserver.example.com 005 Test768 FNC SAFELIST ELIST=CTU MONITOR=100 WHOX ETRACE KNOCK CHANTYPES=#& EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLNPQcgimnprstz CHANLIMIT=#&:15 :are supported by this server"},
  47. {Kind: 'S', Data: ":testserver.example.com 005 Test768 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=TestServer STATUSMSG=@+ CALLERID=g CASEMAPPING=rfc1459 NICKLEN=30 MAXNICKLEN=31 CHANNELLEN=50 TOPICLEN=390 DEAF=D :are supported by this server"},
  48. {Kind: 'S', Data: ":testserver.example.com 005 Test768 TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: EXTBAN=$,&acjmorsuxz| CLIENTVER=3.0 :are supported by this server"},
  49. {Kind: 'S', Data: ":testserver.example.com 251 Test768 :There are 0 users and 2 invisible on 1 servers"},
  50. {Kind: 'S', Data: ":testserver.example.com 254 Test768 1 :channels formed"},
  51. {Kind: 'S', Data: ":testserver.example.com 255 Test768 :I have 2 clients and 0 servers"},
  52. {Kind: 'S', Data: ":testserver.example.com 265 Test768 2 2 :Current local users 2, max 2"},
  53. {Kind: 'S', Data: ":testserver.example.com 266 Test768 2 2 :Current global users 2, max 2"},
  54. {Kind: 'S', Data: ":testserver.example.com 250 Test768 :Highest connection count: 2 (2 clients) (8 connections received)"},
  55. {Kind: 'S', Data: ":testserver.example.com 352 Test768 * ~Tester testclient.example.com testserver.example.com Test768 H :0 ..."},
  56. {Kind: 'S', Data: ":testserver.example.com 375 Test768 :- testserver.example.com Message of the Day - "},
  57. {Kind: 'S', Data: ":testserver.example.com 372 Test768 :- This server is only for testing irce, not chatting. If you happen"},
  58. {Kind: 'S', Data: ":testserver.example.com 372 Test768 :- to connect to it by accident, please disconnect immediately."},
  59. {Kind: 'S', Data: ":testserver.example.com 372 Test768 :- "},
  60. {Kind: 'S', Data: ":testserver.example.com 372 Test768 :- - #Test :: Test Channel"},
  61. {Kind: 'S', Data: ":testserver.example.com 372 Test768 :- - #Test2 :: Other Test Channel"},
  62. {Kind: 'S', Data: ":testserver.example.com 376 Test768 :End of /MOTD command."},
  63. {Kind: 'S', Data: ":Test768 MODE Test768 :+i"},
  64. {Kind: 'C', Data: "JOIN #Test"},
  65. {Kind: 'S', Data: ":Test768!~test@127.0.0.1 JOIN #Test *"},
  66. {Kind: 'S', Data: ":testserver.example.com 353 Test768 = #Test :Test768!~test@127.0.0.1 @+Gisle!gisle@gisle.me"},
  67. {Kind: 'S', Data: ":testserver.example.com 366 Test768 #Test :End of /NAMES list."},
  68. {Kind: 'S', Data: ":Gisle!~irce@10.32.0.1 MODE #Test +osv Test768 Test768"},
  69. {Kind: 'S', Data: ":Gisle!~irce@10.32.0.1 MODE #Test +N-s "},
  70. {Kind: 'S', Data: ":Test1234!~test2@172.17.37.1 JOIN #Test Test1234"},
  71. {Kind: 'S', Data: ":Gisle!~irce@10.32.0.1 MODE #Test +v Test1234"},
  72. {Kind: 'S', Data: "PING :testserver.example.com"}, // Ping/Pong to sync.
  73. {Kind: 'C', Data: "PONG :testserver.example.com"},
  74. {Callback: func() error {
  75. channel := client.Channel("#Test")
  76. if channel == nil {
  77. return errors.New("Channel #Test not found")
  78. }
  79. err := irctest.AssertUserlist(t, channel, "@Gisle", "@Test768", "+Test1234")
  80. if err != nil {
  81. return err
  82. }
  83. userTest1234, ok := channel.UserList().User("Test1234")
  84. if !ok {
  85. return errors.New("Test1234 not found")
  86. }
  87. if userTest1234.Account != "Test1234" {
  88. return errors.New("Test1234 did not get account from extended-join")
  89. }
  90. return nil
  91. }},
  92. {Kind: 'S', Data: ":Test1234!~test2@172.17.37.1 NICK Hunter2"},
  93. {Kind: 'S', Data: ":Hunter2!~test2@172.17.37.1 AWAY :Doing stuff"},
  94. {Kind: 'S', Data: ":Gisle!~irce@10.32.0.1 AWAY"},
  95. {Kind: 'S', Data: ":Gisle!~irce@10.32.0.1 PART #Test :Leaving the channel"},
  96. {Kind: 'S', Data: "PING :testserver.example.com"}, // Ping/Pong to sync.
  97. {Kind: 'C', Data: "PONG :testserver.example.com"},
  98. {Callback: func() error {
  99. channel := client.Channel("#Test")
  100. if channel == nil {
  101. return errors.New("Channel #Test not found")
  102. }
  103. err := irctest.AssertUserlist(t, channel, "@Test768", "+Hunter2")
  104. if err != nil {
  105. return err
  106. }
  107. _, ok := channel.UserList().User("Test1234")
  108. if ok {
  109. return errors.New("Test1234 is still there")
  110. }
  111. userHunter2, ok := channel.UserList().User("Hunter2")
  112. if !ok {
  113. return errors.New("Test1234 not found")
  114. }
  115. if userHunter2.Account != "Test1234" {
  116. return errors.New("Hunter2 did not persist account post nick change")
  117. }
  118. if !userHunter2.IsAway() {
  119. return errors.New("Hunter2 should be away")
  120. }
  121. if userHunter2.Away != "Doing stuff" {
  122. return errors.New("Hunter2 has the wrong away message: " + userHunter2.Away)
  123. }
  124. return nil
  125. }},
  126. {Kind: 'S', Data: ":Hunter2!~test2@172.17.37.1 PRIVMSG Test768 :Hello, World"},
  127. {Kind: 'S', Data: "PING :testserver.example.com"}, // Ping/Pong to sync.
  128. {Kind: 'C', Data: "PONG :testserver.example.com"},
  129. {Callback: func() error {
  130. query := client.Query("Hunter2")
  131. if query == nil {
  132. return errors.New("Did not find query")
  133. }
  134. return nil
  135. }},
  136. {Kind: 'S', Data: ":Hunter2!~test2@172.17.37.1 NICK SevenAsterisks"},
  137. {Kind: 'S', Data: "PING :testserver.example.com"}, // Ping/Pong to sync.
  138. {Kind: 'C', Data: "PONG :testserver.example.com"},
  139. {Callback: func() error {
  140. oldQuerry := client.Query("Hunter2")
  141. if oldQuerry != nil {
  142. return errors.New("Did find query by old name")
  143. }
  144. query := client.Query("SevenAsterisks")
  145. if query == nil {
  146. return errors.New("Did not find query by new name")
  147. }
  148. return nil
  149. }},
  150. {Callback: func() error {
  151. client.EmitInput("/invalidcommand stuff and things", nil)
  152. return nil
  153. }},
  154. {Kind: 'C', Data: "INVALIDCOMMAND stuff and things"},
  155. {Kind: 'S', Data: ":testserver.example.com 421 Test768 INVALIDCOMMAND :Unknown command"},
  156. {Callback: func() error {
  157. channel := client.Channel("#Test")
  158. if channel == nil {
  159. return errors.New("Channel #Test not found")
  160. }
  161. client.EmitInput("/me does stuff", channel)
  162. client.EmitInput("/describe #Test describes stuff", channel)
  163. client.EmitInput("/text Hello, World", channel)
  164. client.EmitInput("Hello again", channel)
  165. return nil
  166. }},
  167. {Kind: 'C', Data: "PRIVMSG #Test :\x01ACTION does stuff\x01"},
  168. {Kind: 'C', Data: "PRIVMSG #Test :\x01ACTION describes stuff\x01"},
  169. {Kind: 'C', Data: "PRIVMSG #Test :Hello, World"},
  170. {Kind: 'C', Data: "PRIVMSG #Test :Hello again"},
  171. {Kind: 'S', Data: ":Test768!~test@127.0.0.1 PRIVMSG #Test :\x01ACTION does stuff\x01"},
  172. {Kind: 'S', Data: ":Test768!~test@127.0.0.1 PRIVMSG #Test :\x01ACTION describes stuff\x01"},
  173. {Kind: 'S', Data: ":Test768!~test@127.0.0.1 PRIVMSG #Test :Hello, World"},
  174. {Kind: 'S', Data: ":Test768!~test@127.0.0.1 PRIVMSG #Test :Hello again"},
  175. },
  176. }
  177. addr, err := interaction.Listen()
  178. if err != nil {
  179. t.Fatal("Listen:", err)
  180. }
  181. irc.Handle(func(event *irc.Event, client *irc.Client) {
  182. if event.Name() == "packet.376" {
  183. client.SendQueued("JOIN #Test")
  184. }
  185. })
  186. err = client.Connect(addr, false)
  187. if err != nil {
  188. t.Fatal("Connect:", err)
  189. return
  190. }
  191. interaction.Wait()
  192. fail := interaction.Failure
  193. if fail != nil {
  194. t.Error("Index:", fail.Index)
  195. t.Error("NetErr:", fail.NetErr)
  196. t.Error("CBErr:", fail.CBErr)
  197. t.Error("Result:", fail.Result)
  198. if fail.Index >= 0 {
  199. t.Error("Line.Kind:", interaction.Lines[fail.Index].Kind)
  200. t.Error("Line.Data:", interaction.Lines[fail.Index].Data)
  201. }
  202. }
  203. if client.Nick() != "Test768" {
  204. t.Errorf("Nick: %#+v != %#+v (Expectation)", client.Nick(), "Test768")
  205. }
  206. if client.User() != "~Tester" {
  207. t.Errorf("User: %#+v != %#+v (Expectation)", client.User(), "~Tester")
  208. }
  209. if client.Host() != "testclient.example.com" {
  210. t.Errorf("Host: %#+v != %#+v (Expectation)", client.Host(), "testclient.example.com")
  211. }
  212. for i, logLine := range interaction.Log {
  213. t.Logf("Log[%d] = %#+v", i, logLine)
  214. }
  215. }