connection_test.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package server
  2. import (
  3. "bufio"
  4. "bytes"
  5. "context"
  6. "github.com/mkaminski/goaim/oscar"
  7. "github.com/stretchr/testify/assert"
  8. "io"
  9. "sync"
  10. "testing"
  11. )
  12. func TestHandleChatConnection_Notification(t *testing.T) {
  13. ctx := context.Background()
  14. cfg := Config{}
  15. cr := NewChatRegistry()
  16. logger := NewLogger(cfg)
  17. room := ChatRoom{
  18. Name: "test chat room!",
  19. SessionManager: NewSessionManager(logger),
  20. }
  21. bobSess := room.NewSessionWithSN("bob-sess-id", "bob")
  22. cr.Register(room)
  23. msgIn := []oscar.XMessage{
  24. {
  25. SnacFrame: oscar.SnacFrame{
  26. FoodGroup: oscar.CHAT,
  27. SubGroup: oscar.ChatUsersJoined,
  28. },
  29. SnacOut: oscar.SNAC_0x0E_0x03_ChatUsersJoined{
  30. Users: []oscar.TLVUserInfo{
  31. bobSess.TLVUserInfo(),
  32. },
  33. },
  34. },
  35. {
  36. SnacFrame: oscar.SnacFrame{
  37. FoodGroup: oscar.CHAT,
  38. SubGroup: oscar.ChatUsersLeft,
  39. },
  40. SnacOut: oscar.SNAC_0x0E_0x03_ChatUsersJoined{
  41. Users: []oscar.TLVUserInfo{},
  42. },
  43. },
  44. }
  45. routeSig := func(ctx context.Context, buf io.Reader, w io.Writer, u *uint32) error {
  46. return nil
  47. }
  48. wg := sync.WaitGroup{}
  49. wg.Add(len(msgIn))
  50. var msgOut []oscar.XMessage
  51. alertHandler := func(ctx context.Context, msg oscar.XMessage, w io.Writer, u *uint32) error {
  52. msgOut = append(msgOut, msg)
  53. wg.Done()
  54. return nil
  55. }
  56. go func() {
  57. wg.Wait()
  58. bobSess.Close()
  59. }()
  60. pr, _ := io.Pipe()
  61. rw := bufio.NewReadWriter(bufio.NewReader(pr), bufio.NewWriter(&bytes.Buffer{}))
  62. for _, msg := range msgIn {
  63. room.SendToScreenName(ctx, "bob", msg)
  64. }
  65. dispatchIncomingMessages(ctx, bobSess, uint32(0), rw, logger, routeSig, alertHandler)
  66. assert.Equal(t, msgIn, msgOut)
  67. }
  68. func TestHandleChatConnection_ClientRequestFLAP(t *testing.T) {
  69. ctx := context.Background()
  70. cfg := Config{}
  71. cr := NewChatRegistry()
  72. logger := NewLogger(cfg)
  73. room := ChatRoom{
  74. Name: "test chat room!",
  75. SessionManager: NewSessionManager(logger),
  76. }
  77. bobSess := room.NewSessionWithSN("bob-sess-id", "bob")
  78. cr.Register(room)
  79. payloads := [][]byte{
  80. {'a', 'b', 'c', 'd'},
  81. {'e', 'f', 'g', 'h'},
  82. }
  83. pr, pw := io.Pipe()
  84. _, pw2 := io.Pipe()
  85. go func() {
  86. for _, buf := range payloads {
  87. flap := oscar.FlapFrame{
  88. StartMarker: 42,
  89. FrameType: oscar.FlapFrameData,
  90. PayloadLength: uint16(len(buf)),
  91. }
  92. assert.NoError(t, oscar.Marshal(flap, pw))
  93. assert.NoError(t, oscar.Marshal(buf, pw))
  94. }
  95. }()
  96. var msgOut [][]byte
  97. wg := sync.WaitGroup{}
  98. wg.Add(len(payloads))
  99. routeSig := func(ctx context.Context, buf io.Reader, w io.Writer, u *uint32) error {
  100. var err error
  101. b, err := io.ReadAll(buf)
  102. msgOut = append(msgOut, b)
  103. wg.Done()
  104. return err
  105. }
  106. alertHandler := func(ctx context.Context, msg oscar.XMessage, w io.Writer, u *uint32) error {
  107. return nil
  108. }
  109. rw := bufio.NewReadWriter(bufio.NewReader(pr), bufio.NewWriter(pw2))
  110. go func() {
  111. wg.Wait()
  112. pw.Close()
  113. }()
  114. dispatchIncomingMessages(ctx, bobSess, uint32(0), rw, logger, routeSig, alertHandler)
  115. assert.Equal(t, payloads, msgOut)
  116. }
  117. func TestHandleChatConnection_SessionClosed(t *testing.T) {
  118. ctx := context.Background()
  119. cfg := Config{}
  120. cr := NewChatRegistry()
  121. logger := NewLogger(cfg)
  122. room := ChatRoom{
  123. Name: "test chat room!",
  124. SessionManager: NewSessionManager(logger),
  125. }
  126. sess := room.NewSessionWithSN("bob-sess-id", "bob")
  127. cr.Register(room)
  128. routeSig := func(ctx context.Context, buf io.Reader, w io.Writer, u *uint32) error {
  129. t.Fatal("not expecting any output")
  130. return nil
  131. }
  132. alertHandler := func(ctx context.Context, msg oscar.XMessage, w io.Writer, u *uint32) error {
  133. t.Fatal("not expecting any alerts")
  134. return nil
  135. }
  136. pr1, _ := io.Pipe()
  137. pr2, pw2 := io.Pipe()
  138. in := struct {
  139. io.Reader
  140. io.Writer
  141. }{
  142. Reader: pr1,
  143. Writer: pw2,
  144. }
  145. sess.Close()
  146. go dispatchIncomingMessages(ctx, sess, 0, in, logger, routeSig, alertHandler)
  147. flap := oscar.FlapFrame{}
  148. assert.NoError(t, oscar.Unmarshal(&flap, pr2))
  149. assert.Equal(t, oscar.FlapFrameSignoff, flap.FrameType)
  150. }