chat_test.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package oscar
  2. import (
  3. "bytes"
  4. "context"
  5. "io"
  6. "log/slog"
  7. "testing"
  8. "github.com/mk6i/retro-aim-server/state"
  9. "github.com/mk6i/retro-aim-server/wire"
  10. "github.com/stretchr/testify/assert"
  11. "github.com/stretchr/testify/mock"
  12. )
  13. func TestChatService_handleNewConnection(t *testing.T) {
  14. sess := state.NewSession()
  15. clientReader, serverWriter := io.Pipe()
  16. serverReader, clientWriter := io.Pipe()
  17. go func() {
  18. // < receive FLAPSignonFrame
  19. flap := wire.FLAPFrame{}
  20. assert.NoError(t, wire.Unmarshal(&flap, serverReader))
  21. buf, err := flap.ReadBody(serverReader)
  22. assert.NoError(t, err)
  23. flapSignonFrame := wire.FLAPSignonFrame{}
  24. assert.NoError(t, wire.Unmarshal(&flapSignonFrame, buf))
  25. // > send FLAPSignonFrame
  26. flapSignonFrame = wire.FLAPSignonFrame{
  27. FLAPVersion: 1,
  28. }
  29. flapSignonFrame.Append(wire.NewTLV(wire.OServiceTLVTagsLoginCookie, []byte(`the-chat-login-cookie`)))
  30. buf = &bytes.Buffer{}
  31. assert.NoError(t, wire.Marshal(flapSignonFrame, buf))
  32. flap = wire.FLAPFrame{
  33. StartMarker: 42,
  34. FrameType: wire.FLAPFrameSignon,
  35. PayloadLength: uint16(buf.Len()),
  36. }
  37. assert.NoError(t, wire.Marshal(flap, serverWriter))
  38. _, err = serverWriter.Write(buf.Bytes())
  39. assert.NoError(t, err)
  40. // < receive SNAC_0x01_0x03_OServiceHostOnline
  41. flap = wire.FLAPFrame{}
  42. assert.NoError(t, wire.Unmarshal(&flap, serverReader))
  43. buf, err = flap.ReadBody(serverReader)
  44. assert.NoError(t, err)
  45. frame := wire.SNACFrame{}
  46. assert.NoError(t, wire.Unmarshal(&frame, buf))
  47. body := wire.SNAC_0x01_0x03_OServiceHostOnline{}
  48. assert.NoError(t, wire.Unmarshal(&body, buf))
  49. // send the first request that should get relayed to BOSRouter.Handle
  50. flapc := wire.NewFlapClient(0, nil, serverWriter)
  51. frame = wire.SNACFrame{
  52. FoodGroup: wire.Chat,
  53. SubGroup: wire.ChatNavNavInfo,
  54. }
  55. assert.NoError(t, flapc.SendSNAC(frame, struct{}{}))
  56. assert.NoError(t, serverWriter.Close())
  57. }()
  58. authService := newMockAuthService(t)
  59. authService.EXPECT().
  60. RegisterChatSession([]byte(`user-screen-name`)).
  61. Return(sess, nil)
  62. authService.EXPECT().
  63. SignoutChat(mock.Anything, sess).
  64. Return(nil)
  65. onlineNotifier := newMockOnlineNotifier(t)
  66. onlineNotifier.EXPECT().
  67. HostOnline().
  68. Return(wire.SNACMessage{
  69. Frame: wire.SNACFrame{
  70. FoodGroup: wire.OService,
  71. SubGroup: wire.OServiceHostOnline,
  72. },
  73. Body: wire.SNAC_0x01_0x03_OServiceHostOnline{},
  74. })
  75. cookieCracker := newMockCookieCracker(t)
  76. cookieCracker.EXPECT().
  77. Crack([]byte(`the-chat-login-cookie`)).
  78. Return([]byte(`user-screen-name`), nil)
  79. bosRouter := newMockHandler(t)
  80. bosRouter.EXPECT().
  81. Handle(mock.Anything, sess, mock.Anything, mock.Anything, mock.Anything).
  82. Return(nil)
  83. rt := ChatServer{
  84. AuthService: authService,
  85. CookieCracker: cookieCracker,
  86. Handler: bosRouter,
  87. Logger: slog.Default(),
  88. OnlineNotifier: onlineNotifier,
  89. }
  90. rwc := pipeRWC{
  91. PipeReader: clientReader,
  92. PipeWriter: clientWriter,
  93. }
  94. assert.NoError(t, rt.handleNewConnection(context.Background(), rwc))
  95. }