connection_test.go 3.6 KB

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