chat_test.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. sess.SetID("session-id-1234")
  16. clientReader, serverWriter := io.Pipe()
  17. serverReader, clientWriter := io.Pipe()
  18. go func() {
  19. // < receive FLAPSignonFrame
  20. flap := wire.FLAPFrame{}
  21. assert.NoError(t, wire.Unmarshal(&flap, serverReader))
  22. buf, err := flap.ReadBody(serverReader)
  23. assert.NoError(t, err)
  24. flapSignonFrame := wire.FLAPSignonFrame{}
  25. assert.NoError(t, wire.Unmarshal(&flapSignonFrame, buf))
  26. // > send FLAPSignonFrame
  27. flapSignonFrame = wire.FLAPSignonFrame{
  28. FLAPVersion: 1,
  29. }
  30. flapSignonFrame.Append(wire.NewTLV(wire.OServiceTLVTagsLoginCookie, []byte(`the-chat-login-cookie`)))
  31. buf = &bytes.Buffer{}
  32. assert.NoError(t, wire.Marshal(flapSignonFrame, buf))
  33. flap = wire.FLAPFrame{
  34. StartMarker: 42,
  35. FrameType: wire.FLAPFrameSignon,
  36. PayloadLength: uint16(buf.Len()),
  37. }
  38. assert.NoError(t, wire.Marshal(flap, serverWriter))
  39. _, err = serverWriter.Write(buf.Bytes())
  40. assert.NoError(t, err)
  41. // < receive SNAC_0x01_0x03_OServiceHostOnline
  42. flap = wire.FLAPFrame{}
  43. assert.NoError(t, wire.Unmarshal(&flap, serverReader))
  44. buf, err = flap.ReadBody(serverReader)
  45. assert.NoError(t, err)
  46. frame := wire.SNACFrame{}
  47. assert.NoError(t, wire.Unmarshal(&frame, buf))
  48. body := wire.SNAC_0x01_0x03_OServiceHostOnline{}
  49. assert.NoError(t, wire.Unmarshal(&body, buf))
  50. // send the first request that should get relayed to BOSRouter.Handle
  51. flapc := flapClient{
  52. w: serverWriter,
  53. }
  54. frame = wire.SNACFrame{
  55. FoodGroup: wire.Chat,
  56. SubGroup: wire.ChatNavNavInfo,
  57. }
  58. assert.NoError(t, flapc.SendSNAC(frame, struct{}{}))
  59. assert.NoError(t, serverWriter.Close())
  60. }()
  61. authService := newMockAuthService(t)
  62. authService.EXPECT().
  63. RetrieveChatSession([]byte(`the-chat-login-cookie`)).
  64. Return(sess, nil)
  65. authService.EXPECT().
  66. SignoutChat(mock.Anything, sess).
  67. Return(nil)
  68. onlineNotifier := newMockOnlineNotifier(t)
  69. onlineNotifier.EXPECT().
  70. HostOnline().
  71. Return(wire.SNACMessage{
  72. Frame: wire.SNACFrame{
  73. FoodGroup: wire.OService,
  74. SubGroup: wire.OServiceHostOnline,
  75. },
  76. Body: wire.SNAC_0x01_0x03_OServiceHostOnline{},
  77. })
  78. bosRouter := newMockHandler(t)
  79. bosRouter.EXPECT().
  80. Handle(mock.Anything, sess, mock.Anything, mock.Anything, mock.Anything).
  81. Return(nil)
  82. rt := ChatServer{
  83. AuthService: authService,
  84. Handler: bosRouter,
  85. Logger: slog.Default(),
  86. OnlineNotifier: onlineNotifier,
  87. }
  88. rwc := pipeRWC{
  89. PipeReader: clientReader,
  90. PipeWriter: clientWriter,
  91. }
  92. assert.NoError(t, rt.handleNewConnection(context.Background(), rwc))
  93. }