Преглед изворни кода

reinstate buddy arrivals at signon

Mike пре 1 година
родитељ
комит
6cef4419b1

+ 6 - 5
foodgroup/buddy.go

@@ -72,7 +72,7 @@ func (s BuddyService) AddBuddies(
 	for _, entry := range inBody.Buddies {
 		toNotify = append(toNotify, state.NewIdentScreenName(entry.ScreenName))
 	}
-	if err := s.buddyBroadcaster.BroadcastVisibility(ctx, sess, toNotify); err != nil {
+	if err := s.buddyBroadcaster.BroadcastVisibility(ctx, sess, toNotify, true); err != nil {
 		return fmt.Errorf("buddyBroadcaster.BroadcastVisibility: %w", err)
 	}
 
@@ -96,7 +96,7 @@ func (s BuddyService) DelBuddies(
 		toNotify = append(toNotify, sn)
 	}
 
-	if err := s.buddyBroadcaster.BroadcastVisibility(ctx, sess, toNotify); err != nil {
+	if err := s.buddyBroadcaster.BroadcastVisibility(ctx, sess, toNotify, true); err != nil {
 		return fmt.Errorf("buddyBroadcaster.BroadcastVisibility: %w", err)
 	}
 
@@ -207,9 +207,9 @@ func (s buddyNotifier) BroadcastBuddyDeparted(ctx context.Context, sess *state.S
 //   - Sends arrival notifications to users that you block who have you on
 //     their buddy lists.
 //   - Sends you departure notifications for users on your buddy list that you
-//     block.
+//     block  (if doSendDepartures is true).
 //   - Sends departure notifications to users that you block who have you on
-//     their buddy lists.
+//     their buddy lists (if doSendDepartures is true).
 //   - Don't send notifications for any user that blocks you.
 //
 // This method is called when your visibility settings change, ensuring that
@@ -218,6 +218,7 @@ func (s buddyNotifier) BroadcastVisibility(
 	ctx context.Context,
 	you *state.Session,
 	filter []state.IdentScreenName,
+	doSendDepartures bool,
 ) error {
 
 	relationships, err := s.buddyListRetriever.AllRelationships(you.IdentScreenName(), filter)
@@ -258,7 +259,7 @@ func (s buddyNotifier) BroadcastVisibility(
 				// tell you they're online
 				s.unicastBuddyArrived(ctx, theirInfo, you.IdentScreenName())
 			}
-		} else {
+		} else if relationship.YouBlock && doSendDepartures {
 			if relationship.IsOnTheirList {
 				// tell them you're offline
 				s.unicastBuddyDeparted(ctx, you, theirSess.IdentScreenName())

+ 106 - 3
foodgroup/buddy_test.go

@@ -133,7 +133,7 @@ func TestBuddyService_AddBuddies(t *testing.T) {
 			mockBuddyBroadcaster := newMockbuddyBroadcaster(t)
 			for _, params := range tt.mockParams.broadcastVisibilityParams {
 				mockBuddyBroadcaster.EXPECT().
-					BroadcastVisibility(mock.Anything, matchSession(params.from), params.filter).
+					BroadcastVisibility(mock.Anything, matchSession(params.from), params.filter, true).
 					Return(params.err)
 			}
 
@@ -209,7 +209,7 @@ func TestBuddyService_DelBuddies(t *testing.T) {
 			mockBuddyBroadcaster := newMockbuddyBroadcaster(t)
 			for _, params := range tt.mockParams.broadcastVisibilityParams {
 				mockBuddyBroadcaster.EXPECT().
-					BroadcastVisibility(mock.Anything, matchSession(params.from), params.filter).
+					BroadcastVisibility(mock.Anything, matchSession(params.from), params.filter, true).
 					Return(params.err)
 			}
 			localBuddyListManager := newMockLocalBuddyListManager(t)
@@ -484,6 +484,8 @@ func Test_buddyNotifier_BroadcastVisibility(t *testing.T) {
 		userSession *state.Session
 		// filter limits specific users that can be notified
 		filter []state.IdentScreenName
+		// doSendDepartures indicates whether departure messages should be sent
+		doSendDepartures bool
 		// mockParams is the list of params sent to mocks that satisfy this
 		// method's dependencies
 		mockParams mockParams
@@ -641,6 +643,106 @@ func Test_buddyNotifier_BroadcastVisibility(t *testing.T) {
 					},
 				},
 			},
+			doSendDepartures: true,
+		},
+		{
+			name:        "don't send departure notifications",
+			userSession: newTestSession("me"),
+			mockParams: mockParams{
+				buddyListRetrieverParams: buddyListRetrieverParams{
+					allRelationshipsParams: allRelationshipsParams{
+						{
+							screenName: state.NewIdentScreenName("me"),
+							filter:     nil,
+							result: []state.Relationship{
+								{
+									User:          state.NewIdentScreenName("friend2-visible-on-their-list"),
+									BlocksYou:     false,
+									YouBlock:      false,
+									IsOnYourList:  false,
+									IsOnTheirList: true,
+								},
+								{
+									User:          state.NewIdentScreenName("friend3-visible-on-your-list"),
+									BlocksYou:     false,
+									YouBlock:      false,
+									IsOnYourList:  true,
+									IsOnTheirList: false,
+								},
+								{
+									User:          state.NewIdentScreenName("friend4-visible-on-both-lists"),
+									BlocksYou:     false,
+									YouBlock:      false,
+									IsOnYourList:  true,
+									IsOnTheirList: true,
+								},
+								{
+									User:          state.NewIdentScreenName("friend7-visible-offline"),
+									BlocksYou:     false,
+									YouBlock:      false,
+									IsOnYourList:  true,
+									IsOnTheirList: true,
+								},
+							},
+						},
+					},
+					buddyIconRefByNameParams: buddyIconRefByNameParams{
+						{
+							screenName: state.NewIdentScreenName("me"),
+							result:     nil,
+						},
+						{
+							screenName: state.NewIdentScreenName("friend3-visible-on-your-list"),
+							result:     nil,
+						},
+						{
+							screenName: state.NewIdentScreenName("friend4-visible-on-both-lists"),
+							result:     nil,
+						},
+					},
+				},
+				messageRelayerParams: messageRelayerParams{
+					relayToScreenNameParams: relayToScreenNameParams{
+						{
+							screenName: state.NewIdentScreenName("friend2-visible-on-their-list"),
+							message:    newBuddyArrivedNotif(newTestSession("me").TLVUserInfo()),
+						},
+						{
+							screenName: state.NewIdentScreenName("me"),
+							message:    newBuddyArrivedNotif(newTestSession("friend3-visible-on-your-list").TLVUserInfo()),
+						},
+						{
+							screenName: state.NewIdentScreenName("friend4-visible-on-both-lists"),
+							message:    newBuddyArrivedNotif(newTestSession("me").TLVUserInfo()),
+						},
+						{
+							screenName: state.NewIdentScreenName("me"),
+							message:    newBuddyArrivedNotif(newTestSession("friend4-visible-on-both-lists").TLVUserInfo()),
+						},
+					},
+				},
+				sessionRetrieverParams: sessionRetrieverParams{
+					retrieveSessionParams: retrieveSessionParams{
+						{
+							screenName: state.NewIdentScreenName("friend2-visible-on-their-list"),
+							result:     newTestSession("friend2-visible-on-their-list"),
+						},
+						{
+							screenName: state.NewIdentScreenName("friend3-visible-on-your-list"),
+							result:     newTestSession("friend3-visible-on-your-list"),
+						},
+						{
+							screenName: state.NewIdentScreenName("friend4-visible-on-both-lists"),
+							result:     newTestSession("friend4-visible-on-both-lists"),
+						},
+						{
+							screenName: state.NewIdentScreenName("friend7-visible-offline"),
+							result:     nil,
+						},
+					},
+				},
+			},
+			doSendDepartures: false,
 		},
 		{
 			name:        "users have buddy icons",
@@ -724,6 +826,7 @@ func Test_buddyNotifier_BroadcastVisibility(t *testing.T) {
 					},
 				},
 			},
+			doSendDepartures: true,
 		},
 	}
 
@@ -758,7 +861,7 @@ func Test_buddyNotifier_BroadcastVisibility(t *testing.T) {
 				sessionRetriever:   sessionRetriever,
 			}
 
-			err := svc.BroadcastVisibility(nil, tc.userSession, tc.filter)
+			err := svc.BroadcastVisibility(nil, tc.userSession, tc.filter, tc.doSendDepartures)
 			assert.NoError(t, err)
 		})
 	}

+ 2 - 2
foodgroup/feedbag.go

@@ -212,7 +212,7 @@ func (s FeedbagService) UpsertItem(ctx context.Context, sess *state.Session, inF
 	}
 
 	if alertAll || len(filter) > 0 {
-		if err := s.buddyBroadcaster.BroadcastVisibility(ctx, sess, filter); err != nil {
+		if err := s.buddyBroadcaster.BroadcastVisibility(ctx, sess, filter, true); err != nil {
 			return wire.SNACMessage{}, err
 		}
 	}
@@ -306,7 +306,7 @@ func (s FeedbagService) DeleteItem(ctx context.Context, sess *state.Session, inF
 		}
 	}
 
-	if err := s.buddyBroadcaster.BroadcastVisibility(ctx, sess, filter); err != nil {
+	if err := s.buddyBroadcaster.BroadcastVisibility(ctx, sess, filter, true); err != nil {
 		return wire.SNACMessage{}, err
 	}
 

+ 2 - 2
foodgroup/feedbag_test.go

@@ -907,7 +907,7 @@ func TestFeedbagService_UpsertItem(t *testing.T) {
 			}
 			for _, params := range tc.mockParams.broadcastVisibilityParams {
 				buddyUpdateBroadcaster.EXPECT().
-					BroadcastVisibility(mock.Anything, matchSession(params.from), params.filter).
+					BroadcastVisibility(mock.Anything, matchSession(params.from), params.filter, true).
 					Return(params.err)
 			}
 			svc := NewFeedbagService(slog.Default(), messageRelayer, feedbagManager, bartManager, nil, nil)
@@ -1016,7 +1016,7 @@ func TestFeedbagService_DeleteItem(t *testing.T) {
 			buddyUpdateBroadcast := newMockbuddyBroadcaster(t)
 			for _, params := range tc.mockParams.broadcastVisibilityParams {
 				buddyUpdateBroadcast.EXPECT().
-					BroadcastVisibility(mock.Anything, matchSession(params.from), params.filter).
+					BroadcastVisibility(mock.Anything, matchSession(params.from), params.filter, true).
 					Return(params.err)
 			}
 

+ 12 - 11
foodgroup/mock_buddy_broadcaster_test.go

@@ -116,17 +116,17 @@ func (_c *mockbuddyBroadcaster_BroadcastBuddyDeparted_Call) RunAndReturn(run fun
 	return _c
 }
 
-// BroadcastVisibility provides a mock function with given fields: ctx, from, filter
-func (_m *mockbuddyBroadcaster) BroadcastVisibility(ctx context.Context, from *state.Session, filter []state.IdentScreenName) error {
-	ret := _m.Called(ctx, from, filter)
+// BroadcastVisibility provides a mock function with given fields: ctx, you, filter, sendDepartures
+func (_m *mockbuddyBroadcaster) BroadcastVisibility(ctx context.Context, you *state.Session, filter []state.IdentScreenName, sendDepartures bool) error {
+	ret := _m.Called(ctx, you, filter, sendDepartures)
 
 	if len(ret) == 0 {
 		panic("no return value specified for BroadcastVisibility")
 	}
 
 	var r0 error
-	if rf, ok := ret.Get(0).(func(context.Context, *state.Session, []state.IdentScreenName) error); ok {
-		r0 = rf(ctx, from, filter)
+	if rf, ok := ret.Get(0).(func(context.Context, *state.Session, []state.IdentScreenName, bool) error); ok {
+		r0 = rf(ctx, you, filter, sendDepartures)
 	} else {
 		r0 = ret.Error(0)
 	}
@@ -141,15 +141,16 @@ type mockbuddyBroadcaster_BroadcastVisibility_Call struct {
 
 // BroadcastVisibility is a helper method to define mock.On call
 //   - ctx context.Context
-//   - from *state.Session
+//   - you *state.Session
 //   - filter []state.IdentScreenName
-func (_e *mockbuddyBroadcaster_Expecter) BroadcastVisibility(ctx interface{}, from interface{}, filter interface{}) *mockbuddyBroadcaster_BroadcastVisibility_Call {
-	return &mockbuddyBroadcaster_BroadcastVisibility_Call{Call: _e.mock.On("BroadcastVisibility", ctx, from, filter)}
+//   - sendDepartures bool
+func (_e *mockbuddyBroadcaster_Expecter) BroadcastVisibility(ctx interface{}, you interface{}, filter interface{}, sendDepartures interface{}) *mockbuddyBroadcaster_BroadcastVisibility_Call {
+	return &mockbuddyBroadcaster_BroadcastVisibility_Call{Call: _e.mock.On("BroadcastVisibility", ctx, you, filter, sendDepartures)}
 }
 
-func (_c *mockbuddyBroadcaster_BroadcastVisibility_Call) Run(run func(ctx context.Context, from *state.Session, filter []state.IdentScreenName)) *mockbuddyBroadcaster_BroadcastVisibility_Call {
+func (_c *mockbuddyBroadcaster_BroadcastVisibility_Call) Run(run func(ctx context.Context, you *state.Session, filter []state.IdentScreenName, sendDepartures bool)) *mockbuddyBroadcaster_BroadcastVisibility_Call {
 	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(context.Context), args[1].(*state.Session), args[2].([]state.IdentScreenName))
+		run(args[0].(context.Context), args[1].(*state.Session), args[2].([]state.IdentScreenName), args[3].(bool))
 	})
 	return _c
 }
@@ -159,7 +160,7 @@ func (_c *mockbuddyBroadcaster_BroadcastVisibility_Call) Return(_a0 error) *mock
 	return _c
 }
 
-func (_c *mockbuddyBroadcaster_BroadcastVisibility_Call) RunAndReturn(run func(context.Context, *state.Session, []state.IdentScreenName) error) *mockbuddyBroadcaster_BroadcastVisibility_Call {
+func (_c *mockbuddyBroadcaster_BroadcastVisibility_Call) RunAndReturn(run func(context.Context, *state.Session, []state.IdentScreenName, bool) error) *mockbuddyBroadcaster_BroadcastVisibility_Call {
 	_c.Call.Return(run)
 	return _c
 }

+ 1 - 1
foodgroup/oservice.go

@@ -849,7 +849,7 @@ func (s OServiceServiceForBOS) ServiceRequest(ctx context.Context, sess *state.S
 func (s OServiceServiceForBOS) ClientOnline(ctx context.Context, _ wire.SNAC_0x01_0x02_OServiceClientOnline, sess *state.Session) error {
 	sess.SetSignonComplete()
 
-	if err := s.buddyBroadcaster.BroadcastBuddyArrived(ctx, sess); err != nil {
+	if err := s.buddyBroadcaster.BroadcastVisibility(ctx, sess, nil, false); err != nil {
 		return fmt.Errorf("unable to send buddy arrival notification: %w", err)
 	}
 

+ 6 - 4
foodgroup/oservice_test.go

@@ -1734,9 +1734,11 @@ func TestOServiceServiceForBOS_ClientOnline(t *testing.T) {
 			bodyIn: wire.SNAC_0x01_0x02_OServiceClientOnline{},
 			mockParams: mockParams{
 				buddyBroadcasterParams: buddyBroadcasterParams{
-					broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{
+					broadcastVisibilityParams: broadcastVisibilityParams{
 						{
-							screenName: state.NewIdentScreenName("me"),
+							from:             state.NewIdentScreenName("me"),
+							filter:           nil,
+							doSendDepartures: false,
 						},
 					},
 				},
@@ -1747,9 +1749,9 @@ func TestOServiceServiceForBOS_ClientOnline(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
 			buddyUpdateBroadcaster := newMockbuddyBroadcaster(t)
-			for _, params := range tt.mockParams.broadcastBuddyArrivedParams {
+			for _, params := range tt.mockParams.broadcastVisibilityParams {
 				buddyUpdateBroadcaster.EXPECT().
-					BroadcastBuddyArrived(mock.Anything, matchSession(params.screenName)).
+					BroadcastVisibility(mock.Anything, matchSession(params.from), params.filter, params.doSendDepartures).
 					Return(params.err)
 			}
 

+ 1 - 1
foodgroup/permit_deny.go

@@ -166,7 +166,7 @@ func (s PermitDenyService) maybeBroadcastVisibility(ctx context.Context, sess *s
 			filter = append(filter, state.NewIdentScreenName(user.ScreenName))
 		}
 	}
-	return s.buddyBroadcaster.BroadcastVisibility(ctx, sess, filter)
+	return s.buddyBroadcaster.BroadcastVisibility(ctx, sess, filter, true)
 }
 
 // RightsQuery returns settings for the PermitDeny food group. It returns SNAC

+ 4 - 4
foodgroup/permit_deny_test.go

@@ -210,7 +210,7 @@ func TestPermitDenyService_AddDenyListEntries(t *testing.T) {
 			mockBuddyBroadcaster := newMockbuddyBroadcaster(t)
 			for _, item := range tt.mockParams.broadcastVisibilityParams {
 				mockBuddyBroadcaster.EXPECT().
-					BroadcastVisibility(context.TODO(), matchSession(item.from), item.filter).
+					BroadcastVisibility(context.TODO(), matchSession(item.from), item.filter, true).
 					Return(item.err)
 			}
 
@@ -400,7 +400,7 @@ func TestPermitDenyService_AddPermListEntries(t *testing.T) {
 			mockBuddyBroadcaster := newMockbuddyBroadcaster(t)
 			for _, item := range tt.mockParams.broadcastVisibilityParams {
 				mockBuddyBroadcaster.EXPECT().
-					BroadcastVisibility(context.TODO(), matchSession(item.from), item.filter).
+					BroadcastVisibility(context.TODO(), matchSession(item.from), item.filter, true).
 					Return(item.err)
 			}
 
@@ -512,7 +512,7 @@ func TestPermitDenyService_DelDenyListEntries(t *testing.T) {
 			mockBuddyBroadcaster := newMockbuddyBroadcaster(t)
 			for _, item := range tt.mockParams.broadcastVisibilityParams {
 				mockBuddyBroadcaster.EXPECT().
-					BroadcastVisibility(context.TODO(), matchSession(item.from), item.filter).
+					BroadcastVisibility(context.TODO(), matchSession(item.from), item.filter, true).
 					Return(item.err)
 			}
 
@@ -624,7 +624,7 @@ func TestPermitDenyService_DelPermListEntries(t *testing.T) {
 			mockBuddyBroadcaster := newMockbuddyBroadcaster(t)
 			for _, item := range tt.mockParams.broadcastVisibilityParams {
 				mockBuddyBroadcaster.EXPECT().
-					BroadcastVisibility(context.TODO(), matchSession(item.from), item.filter).
+					BroadcastVisibility(context.TODO(), matchSession(item.from), item.filter, true).
 					Return(item.err)
 			}
 

+ 4 - 3
foodgroup/test_helpers.go

@@ -638,9 +638,10 @@ type buddyBroadcasterParams struct {
 // broadcastVisibilityParams is the list of parameters passed at the mock
 // buddyBroadcaster.BroadcastVisibility call site
 type broadcastVisibilityParams []struct {
-	from   state.IdentScreenName
-	filter []state.IdentScreenName
-	err    error
+	from             state.IdentScreenName
+	filter           []state.IdentScreenName
+	doSendDepartures bool
+	err              error
 }
 
 // broadcastBuddyArrivedParams is the list of parameters passed at the mock

+ 1 - 1
foodgroup/types.go

@@ -60,7 +60,7 @@ type BARTManager interface {
 type buddyBroadcaster interface {
 	BroadcastBuddyArrived(ctx context.Context, sess *state.Session) error
 	BroadcastBuddyDeparted(ctx context.Context, sess *state.Session) error
-	BroadcastVisibility(ctx context.Context, from *state.Session, filter []state.IdentScreenName) error
+	BroadcastVisibility(ctx context.Context, you *state.Session, filter []state.IdentScreenName, sendDepartures bool) error
 }
 
 type BuddyListRetriever interface {