chat_test.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. package server
  2. import (
  3. "bytes"
  4. "github.com/stretchr/testify/mock"
  5. "testing"
  6. "github.com/mkaminski/goaim/oscar"
  7. "github.com/stretchr/testify/assert"
  8. )
  9. func TestSendAndReceiveChatChannelMsgToHost(t *testing.T) {
  10. cases := []struct {
  11. // name is the unit test name
  12. name string
  13. // userSession is the session of the user sending the chat message
  14. userSession *Session
  15. // inputSNAC is the SNAC sent by the sender client
  16. inputSNAC oscar.SNAC_0x0E_0x05_ChatChannelMsgToHost
  17. // expectSNACToParticipants is the message the server broadcast to chat
  18. // room participants (except the sender)
  19. expectSNACToParticipants XMessage
  20. expectOutput *XMessage
  21. }{
  22. {
  23. name: "send chat room message, expect acknowledgement to sender client",
  24. userSession: newTestSession(Session{
  25. ScreenName: "user_sending_chat_msg",
  26. }),
  27. inputSNAC: oscar.SNAC_0x0E_0x05_ChatChannelMsgToHost{
  28. Cookie: 1234,
  29. Channel: 14,
  30. TLVRestBlock: oscar.TLVRestBlock{
  31. TLVList: oscar.TLVList{
  32. {
  33. TType: oscar.ChatTLVPublicWhisperFlag,
  34. Val: []byte{},
  35. },
  36. {
  37. TType: oscar.ChatTLVEnableReflectionFlag,
  38. Val: []byte{},
  39. },
  40. },
  41. },
  42. },
  43. expectSNACToParticipants: XMessage{
  44. snacFrame: oscar.SnacFrame{
  45. FoodGroup: oscar.CHAT,
  46. SubGroup: oscar.ChatChannelMsgToClient,
  47. },
  48. snacOut: oscar.SNAC_0x0E_0x06_ChatChannelMsgToClient{
  49. Cookie: 1234,
  50. Channel: 14,
  51. TLVRestBlock: oscar.TLVRestBlock{
  52. TLVList: oscar.TLVList{
  53. oscar.NewTLV(oscar.ChatTLVPublicWhisperFlag, []byte{}),
  54. oscar.NewTLV(oscar.ChatTLVEnableReflectionFlag, []byte{}),
  55. oscar.NewTLV(oscar.ChatTLVSenderInformation,
  56. newTestSession(Session{ScreenName: "user_sending_chat_msg"}).GetTLVUserInfo()),
  57. },
  58. },
  59. },
  60. },
  61. expectOutput: &XMessage{
  62. snacFrame: oscar.SnacFrame{
  63. FoodGroup: oscar.CHAT,
  64. SubGroup: oscar.ChatChannelMsgToClient,
  65. },
  66. snacOut: oscar.SNAC_0x0E_0x06_ChatChannelMsgToClient{
  67. Cookie: 1234,
  68. Channel: 14,
  69. TLVRestBlock: oscar.TLVRestBlock{
  70. TLVList: oscar.TLVList{
  71. oscar.NewTLV(oscar.ChatTLVPublicWhisperFlag, []byte{}),
  72. oscar.NewTLV(oscar.ChatTLVEnableReflectionFlag, []byte{}),
  73. oscar.NewTLV(oscar.ChatTLVSenderInformation, newTestSession(Session{
  74. ScreenName: "user_sending_chat_msg",
  75. }).GetTLVUserInfo()),
  76. },
  77. },
  78. },
  79. },
  80. },
  81. {
  82. name: "send chat room message, don't expect acknowledgement to sender client",
  83. userSession: newTestSession(Session{
  84. ScreenName: "user_sending_chat_msg",
  85. }),
  86. inputSNAC: oscar.SNAC_0x0E_0x05_ChatChannelMsgToHost{
  87. Cookie: 1234,
  88. Channel: 14,
  89. TLVRestBlock: oscar.TLVRestBlock{
  90. TLVList: oscar.TLVList{
  91. {
  92. TType: oscar.ChatTLVPublicWhisperFlag,
  93. Val: []byte{},
  94. },
  95. },
  96. },
  97. },
  98. expectSNACToParticipants: XMessage{
  99. snacFrame: oscar.SnacFrame{
  100. FoodGroup: oscar.CHAT,
  101. SubGroup: oscar.ChatChannelMsgToClient,
  102. },
  103. snacOut: oscar.SNAC_0x0E_0x06_ChatChannelMsgToClient{
  104. Cookie: 1234,
  105. Channel: 14,
  106. TLVRestBlock: oscar.TLVRestBlock{
  107. TLVList: oscar.TLVList{
  108. oscar.NewTLV(oscar.ChatTLVPublicWhisperFlag, []byte{}),
  109. oscar.NewTLV(oscar.ChatTLVSenderInformation,
  110. newTestSession(Session{
  111. ScreenName: "user_sending_chat_msg",
  112. }).GetTLVUserInfo()),
  113. },
  114. },
  115. },
  116. },
  117. expectOutput: &XMessage{},
  118. },
  119. }
  120. for _, tc := range cases {
  121. t.Run(tc.name, func(t *testing.T) {
  122. //
  123. // initialize dependencies
  124. //
  125. crm := NewMockSessionManager(t)
  126. crm.EXPECT().
  127. BroadcastExcept(tc.userSession, tc.expectSNACToParticipants)
  128. //
  129. // send input SNAC
  130. //
  131. svc := ChatService{}
  132. outputSNAC, err := svc.ChannelMsgToHostHandler(tc.userSession, crm, tc.inputSNAC)
  133. assert.NoError(t, err)
  134. if tc.expectOutput.snacFrame == (oscar.SnacFrame{}) {
  135. return // handler doesn't return response
  136. }
  137. assert.Equal(t, tc.expectOutput, outputSNAC)
  138. })
  139. }
  140. }
  141. func TestChatRouter_RouteChat(t *testing.T) {
  142. cases := []struct {
  143. // name is the unit test name
  144. name string
  145. // input is the request payload
  146. input XMessage
  147. // output is the response payload
  148. output *XMessage
  149. // handlerErr is the mocked handler error response
  150. handlerErr error
  151. // expectErr is the expected error returned by the router
  152. expectErr error
  153. }{
  154. {
  155. name: "receive ChatChannelMsgToHost, return ChatChannelMsgToClient",
  156. input: XMessage{
  157. snacFrame: oscar.SnacFrame{
  158. FoodGroup: oscar.CHAT,
  159. SubGroup: oscar.ChatChannelMsgToHost,
  160. },
  161. snacOut: oscar.SNAC_0x0E_0x05_ChatChannelMsgToHost{
  162. Channel: 4,
  163. },
  164. },
  165. output: &XMessage{
  166. snacFrame: oscar.SnacFrame{
  167. FoodGroup: oscar.CHAT,
  168. SubGroup: oscar.ChatChannelMsgToClient,
  169. },
  170. snacOut: oscar.SNAC_0x0E_0x06_ChatChannelMsgToClient{
  171. Channel: 4,
  172. },
  173. },
  174. },
  175. {
  176. name: "receive ChatChannelMsgToHost, return no response",
  177. input: XMessage{
  178. snacFrame: oscar.SnacFrame{
  179. FoodGroup: oscar.CHAT,
  180. SubGroup: oscar.ChatChannelMsgToHost,
  181. },
  182. snacOut: oscar.SNAC_0x0E_0x05_ChatChannelMsgToHost{
  183. Channel: 4,
  184. },
  185. },
  186. output: nil,
  187. },
  188. {
  189. name: "receive ChatRowListInfo, return ErrUnsupportedSubGroup",
  190. input: XMessage{
  191. snacFrame: oscar.SnacFrame{
  192. FoodGroup: oscar.CHAT,
  193. SubGroup: oscar.ChatRowListInfo,
  194. },
  195. snacOut: struct{}{},
  196. },
  197. output: nil,
  198. expectErr: ErrUnsupportedSubGroup,
  199. },
  200. }
  201. for _, tc := range cases {
  202. t.Run(tc.name, func(t *testing.T) {
  203. svc := NewMockChatHandler(t)
  204. svc.EXPECT().
  205. ChannelMsgToHostHandler(mock.Anything, mock.Anything, tc.input.snacOut).
  206. Return(tc.output, tc.handlerErr).
  207. Maybe()
  208. router := ChatRouter{
  209. ChatHandler: svc,
  210. }
  211. bufIn := &bytes.Buffer{}
  212. assert.NoError(t, oscar.Marshal(tc.input.snacOut, bufIn))
  213. bufOut := &bytes.Buffer{}
  214. seq := uint32(0)
  215. err := router.RouteChat(nil, nil, tc.input.snacFrame, bufIn, bufOut, &seq)
  216. assert.ErrorIs(t, err, tc.expectErr)
  217. if tc.expectErr != nil {
  218. return
  219. }
  220. if tc.output == nil {
  221. // make sure no response was sent
  222. assert.Empty(t, bufOut.Bytes())
  223. return
  224. }
  225. // verify the FLAP frame
  226. flap := oscar.FlapFrame{}
  227. assert.NoError(t, oscar.Unmarshal(&flap, bufOut))
  228. // make sure the sequence increments
  229. assert.Equal(t, seq, uint32(1))
  230. assert.Equal(t, flap.Sequence, uint16(0))
  231. flapBuf, err := flap.SNACBuffer(bufOut)
  232. assert.NoError(t, err)
  233. // verify the SNAC frame
  234. snacFrame := oscar.SnacFrame{}
  235. assert.NoError(t, oscar.Unmarshal(&snacFrame, flapBuf))
  236. assert.Equal(t, tc.output.snacFrame, snacFrame)
  237. // verify the SNAC message
  238. snacBuf := &bytes.Buffer{}
  239. assert.NoError(t, oscar.Marshal(tc.output.snacOut, snacBuf))
  240. assert.Equal(t, snacBuf.Bytes(), flapBuf.Bytes())
  241. })
  242. }
  243. }