Просмотр исходного кода

write test for SetUserInfoFieldsHandler

Mike 2 лет назад
Родитель
Сommit
ee94d144c6
7 измененных файлов с 179 добавлено и 18 удалено
  1. 6 4
      handler/buddy.go
  2. 5 5
      handler/feedbag_test.go
  3. 2 2
      handler/icbm_test.go
  4. 3 3
      handler/oservice.go
  5. 157 0
      handler/oservice_test.go
  6. 4 2
      oscar/snacs.go
  7. 2 2
      server/feedbag_test.go

+ 6 - 4
handler/buddy.go

@@ -45,7 +45,7 @@ func broadcastArrival(ctx context.Context, sess *state.Session, sm SessionManage
 			FoodGroup: oscar.Buddy,
 			SubGroup:  oscar.BuddyArrived,
 		},
-		Body: oscar.SNAC_0x03_0x0A_BuddyArrived{
+		Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
 			TLVUserInfo: oscar.TLVUserInfo{
 				ScreenName:   sess.ScreenName(),
 				WarningLevel: sess.Warning(),
@@ -70,8 +70,10 @@ func broadcastDeparture(ctx context.Context, sess *state.Session, sm SessionMana
 			FoodGroup: oscar.Buddy,
 			SubGroup:  oscar.BuddyDeparted,
 		},
-		Body: oscar.SNAC_0x03_0x0B_BuddyDeparted{
+		Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
 			TLVUserInfo: oscar.TLVUserInfo{
+				// don't include the TLV block, otherwise the AIM client fails
+				// to process the block event
 				ScreenName:   sess.ScreenName(),
 				WarningLevel: sess.Warning(),
 			},
@@ -94,7 +96,7 @@ func unicastArrival(ctx context.Context, srcScreenName, destScreenName string, s
 			FoodGroup: oscar.Buddy,
 			SubGroup:  oscar.BuddyArrived,
 		},
-		Body: oscar.SNAC_0x03_0x0A_BuddyArrived{
+		Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
 			TLVUserInfo: sess.TLVUserInfo(),
 		},
 	})
@@ -114,7 +116,7 @@ func unicastDeparture(ctx context.Context, srcScreenName, destScreenName string,
 			FoodGroup: oscar.Buddy,
 			SubGroup:  oscar.BuddyDeparted,
 		},
-		Body: oscar.SNAC_0x03_0x0B_BuddyDeparted{
+		Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
 			TLVUserInfo: oscar.TLVUserInfo{
 				// don't include the TLV block, otherwise the AIM client fails
 				// to process the block event

+ 5 - 5
handler/feedbag_test.go

@@ -338,7 +338,7 @@ func TestInsertItemHandler(t *testing.T) {
 							FoodGroup: oscar.Buddy,
 							SubGroup:  oscar.BuddyArrived,
 						},
-						Body: oscar.SNAC_0x03_0x0A_BuddyArrived{
+						Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
 							TLVUserInfo: oscar.TLVUserInfo{
 								ScreenName: "buddy_1_online",
 								TLVBlock: oscar.TLVBlock{
@@ -355,7 +355,7 @@ func TestInsertItemHandler(t *testing.T) {
 							FoodGroup: oscar.Buddy,
 							SubGroup:  oscar.BuddyArrived,
 						},
-						Body: oscar.SNAC_0x03_0x0A_BuddyArrived{
+						Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
 							TLVUserInfo: oscar.TLVUserInfo{
 								ScreenName: "buddy_2_online",
 								TLVBlock: oscar.TLVBlock{
@@ -476,7 +476,7 @@ func TestInsertItemHandler(t *testing.T) {
 							FoodGroup: oscar.Buddy,
 							SubGroup:  oscar.BuddyDeparted,
 						},
-						Body: oscar.SNAC_0x03_0x0B_BuddyDeparted{
+						Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
 							TLVUserInfo: oscar.TLVUserInfo{
 								ScreenName:   "user_screen_name",
 								WarningLevel: 0,
@@ -491,7 +491,7 @@ func TestInsertItemHandler(t *testing.T) {
 							FoodGroup: oscar.Buddy,
 							SubGroup:  oscar.BuddyDeparted,
 						},
-						Body: oscar.SNAC_0x03_0x0B_BuddyDeparted{
+						Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
 							TLVUserInfo: oscar.TLVUserInfo{
 								ScreenName:   "buddy_1",
 								WarningLevel: 0,
@@ -559,7 +559,7 @@ func TestInsertItemHandler(t *testing.T) {
 							FoodGroup: oscar.Buddy,
 							SubGroup:  oscar.BuddyDeparted,
 						},
-						Body: oscar.SNAC_0x03_0x0B_BuddyDeparted{
+						Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
 							TLVUserInfo: oscar.TLVUserInfo{
 								ScreenName:   "user_screen_name",
 								WarningLevel: 0,

+ 2 - 2
handler/icbm_test.go

@@ -383,7 +383,7 @@ func TestSendAndReceiveEvilRequest(t *testing.T) {
 					FoodGroup: oscar.Buddy,
 					SubGroup:  oscar.BuddyArrived,
 				},
-				Body: oscar.SNAC_0x03_0x0A_BuddyArrived{
+				Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
 					TLVUserInfo: oscar.TLVUserInfo{
 						ScreenName:   "recipient-screen-name",
 						WarningLevel: evilDeltaAnon,
@@ -435,7 +435,7 @@ func TestSendAndReceiveEvilRequest(t *testing.T) {
 					FoodGroup: oscar.Buddy,
 					SubGroup:  oscar.BuddyArrived,
 				},
-				Body: oscar.SNAC_0x03_0x0A_BuddyArrived{
+				Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
 					TLVUserInfo: oscar.TLVUserInfo{
 						ScreenName:   "recipient-screen-name",
 						WarningLevel: evilDelta,

+ 3 - 3
handler/oservice.go

@@ -117,14 +117,14 @@ func (s OServiceService) UserInfoQueryHandler(ctx context.Context, sess *state.S
 }
 
 func (s OServiceService) SetUserInfoFieldsHandler(ctx context.Context, sess *state.Session, inFrame oscar.SNACFrame, inBody oscar.SNAC_0x01_0x1E_OServiceSetUserInfoFields) (oscar.SNACMessage, error) {
-	if status, hasStatus := inBody.GetUint32(0x06); hasStatus {
+	if status, hasStatus := inBody.GetUint32(oscar.OServiceUserInfoStatus); hasStatus {
 		switch status {
-		case 0x000:
+		case 0x0000:
 			sess.SetInvisible(false)
 			if err := broadcastArrival(ctx, sess, s.sessionManager, s.feedbagManager); err != nil {
 				return oscar.SNACMessage{}, err
 			}
-		case 0x100:
+		case 0x0100:
 			sess.SetInvisible(true)
 			if err := broadcastDeparture(ctx, sess, s.sessionManager, s.feedbagManager); err != nil {
 				return oscar.SNACMessage{}, err

+ 157 - 0
handler/oservice_test.go

@@ -1,6 +1,7 @@
 package handler
 
 import (
+	"github.com/stretchr/testify/mock"
 	"testing"
 	"time"
 
@@ -163,3 +164,159 @@ func TestReceiveAndSendServiceRequest(t *testing.T) {
 		})
 	}
 }
+
+func TestSetUserInfoFieldsHandler(t *testing.T) {
+	cases := []struct {
+		// name is the unit test name
+		name string
+		// userSession is the session of the user whose info is being set
+		userSession *state.Session
+		// inputSNAC is the SNAC sent from the client to the server
+		inputSNAC oscar.SNACMessage
+		// expectOutput is the SNAC reply sent from the server back to the
+		// client
+		expectOutput oscar.SNACMessage
+		// broadcastMessage is the arrival/departure message sent to buddies
+		broadcastMessage []struct {
+			recipients []string
+			msg        oscar.SNACMessage
+		}
+		// interestedUserLookups contains all the users who have this user on
+		// their buddy list
+		interestedUserLookups map[string][]string
+		// expectErr is the expected error returned
+		expectErr error
+	}{
+		{
+			name:        "set user status to visible",
+			userSession: newTestSession("user_screen_name"),
+			inputSNAC: oscar.SNACMessage{
+				Frame: oscar.SNACFrame{
+					RequestID: 1234,
+				},
+				Body: oscar.SNAC_0x01_0x1E_OServiceSetUserInfoFields{
+					TLVRestBlock: oscar.TLVRestBlock{
+						TLVList: oscar.TLVList{
+							oscar.NewTLV(oscar.OServiceUserInfoStatus, uint32(0x0000)),
+						},
+					},
+				},
+			},
+			expectOutput: oscar.SNACMessage{
+				Frame: oscar.SNACFrame{
+					FoodGroup: oscar.OService,
+					SubGroup:  oscar.OServiceUserInfoUpdate,
+					RequestID: 1234,
+				},
+				Body: oscar.SNAC_0x01_0x0F_OServiceUserInfoUpdate{
+					TLVUserInfo: newTestSession("user_screen_name").TLVUserInfo(),
+				},
+			},
+			broadcastMessage: []struct {
+				recipients []string
+				msg        oscar.SNACMessage
+			}{
+				{
+					recipients: []string{"friend1", "friend2"},
+					msg: oscar.SNACMessage{
+						Frame: oscar.SNACFrame{
+							FoodGroup: oscar.Buddy,
+							SubGroup:  oscar.BuddyArrived,
+						},
+						Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
+							TLVUserInfo: newTestSession("user_screen_name").TLVUserInfo(),
+						},
+					},
+				},
+			},
+			interestedUserLookups: map[string][]string{
+				"user_screen_name": {"friend1", "friend2"},
+			},
+		},
+		{
+			name:        "set user status to invisible",
+			userSession: newTestSession("user_screen_name"),
+			inputSNAC: oscar.SNACMessage{
+				Frame: oscar.SNACFrame{
+					RequestID: 1234,
+				},
+				Body: oscar.SNAC_0x01_0x1E_OServiceSetUserInfoFields{
+					TLVRestBlock: oscar.TLVRestBlock{
+						TLVList: oscar.TLVList{
+							oscar.NewTLV(oscar.OServiceUserInfoStatus, uint32(0x0100)),
+						},
+					},
+				},
+			},
+			expectOutput: oscar.SNACMessage{
+				Frame: oscar.SNACFrame{
+					FoodGroup: oscar.OService,
+					SubGroup:  oscar.OServiceUserInfoUpdate,
+					RequestID: 1234,
+				},
+				Body: oscar.SNAC_0x01_0x0F_OServiceUserInfoUpdate{
+					TLVUserInfo: newTestSession("user_screen_name", sessOptInvisible).TLVUserInfo(),
+				},
+			},
+			broadcastMessage: []struct {
+				recipients []string
+				msg        oscar.SNACMessage
+			}{
+				{
+					recipients: []string{"friend1", "friend2"},
+					msg: oscar.SNACMessage{
+						Frame: oscar.SNACFrame{
+							FoodGroup: oscar.Buddy,
+							SubGroup:  oscar.BuddyDeparted,
+						},
+						Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
+							TLVUserInfo: oscar.TLVUserInfo{
+								ScreenName:   "user_screen_name",
+								WarningLevel: 0,
+							},
+						},
+					},
+				},
+			},
+			interestedUserLookups: map[string][]string{
+				"user_screen_name": {"friend1", "friend2"},
+			},
+		},
+	}
+
+	for _, tc := range cases {
+		t.Run(tc.name, func(t *testing.T) {
+			//
+			// initialize dependencies
+			//
+			fm := newMockFeedbagManager(t)
+			for user, friends := range tc.interestedUserLookups {
+				fm.EXPECT().
+					InterestedUsers(user).
+					Return(friends, nil).
+					Maybe()
+			}
+			sm := newMockSessionManager(t)
+			for _, broadcastMsg := range tc.broadcastMessage {
+				sm.EXPECT().BroadcastToScreenNames(mock.Anything, broadcastMsg.recipients, broadcastMsg.msg)
+			}
+			//
+			// send input SNAC
+			//
+			svc := OServiceService{
+				feedbagManager: fm,
+				sessionManager: sm,
+			}
+			outputSNAC, err := svc.SetUserInfoFieldsHandler(nil, tc.userSession, tc.inputSNAC.Frame,
+				tc.inputSNAC.Body.(oscar.SNAC_0x01_0x1E_OServiceSetUserInfoFields))
+			assert.ErrorIs(t, err, tc.expectErr)
+			if tc.expectErr != nil {
+				return
+			}
+			//
+			// verify output
+			//
+			assert.Equal(t, tc.expectOutput, outputSNAC)
+		})
+	}
+}

+ 4 - 2
oscar/snacs.go

@@ -111,6 +111,8 @@ const (
 	OServiceBartQuery2        uint16 = 0x0022
 	OServiceBartReply2        uint16 = 0x0023
 
+	OServiceUserInfoStatus uint16 = 0x06
+
 	OServiceTLVTagsReconnectHere uint16 = 0x05
 	OServiceTLVTagsLoginCookie   uint16 = 0x06
 	OServiceTLVTagsGroupID       uint16 = 0x0D
@@ -322,11 +324,11 @@ type SNAC_0x03_0x03_BuddyRightsReply struct {
 	TLVRestBlock
 }
 
-type SNAC_0x03_0x0A_BuddyArrived struct {
+type SNAC_0x03_0x0B_BuddyArrived struct {
 	TLVUserInfo
 }
 
-type SNAC_0x03_0x0B_BuddyDeparted struct {
+type SNAC_0x03_0x0C_BuddyDeparted struct {
 	TLVUserInfo
 }
 

+ 2 - 2
server/feedbag_test.go

@@ -118,7 +118,7 @@ func TestFeedbagRouter_RouteFeedbag(t *testing.T) {
 			output: oscar.SNACMessage{},
 		},
 		{
-			name: "receive FeedbagInsertItem, return BuddyArrived and FeedbagStatus",
+			name: "receive FeedbagInsertItem, return FeedbagStatus",
 			input: oscar.SNACMessage{
 				Frame: oscar.SNACFrame{
 					FoodGroup: oscar.Feedbag,
@@ -143,7 +143,7 @@ func TestFeedbagRouter_RouteFeedbag(t *testing.T) {
 			},
 		},
 		{
-			name: "receive FeedbagUpdateItem, return BuddyArrived and FeedbagStatus",
+			name: "receive FeedbagUpdateItem, return FeedbagStatus",
 			input: oscar.SNACMessage{
 				Frame: oscar.SNACFrame{
 					FoodGroup: oscar.Feedbag,