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

Update mgmt api and buddy unit tests

Josh Knight 1 год назад
Родитель
Сommit
79d73de22c

+ 39 - 30
foodgroup/buddy_test.go

@@ -106,9 +106,10 @@ func TestBuddyService_AddBuddies(t *testing.T) {
 					},
 				},
 				feedbagManagerParams: feedbagManagerParams{
-					feedbagParams: feedbagParams{
+					buddyIconRefByNameParams: buddyIconRefByNameParams{
 						{
 							screenName: state.NewIdentScreenName("buddy_1_online"),
+							result:     nil,
 						},
 					},
 				},
@@ -159,6 +160,11 @@ func TestBuddyService_AddBuddies(t *testing.T) {
 			}
 
 			feedbagManager := newMockFeedbagManager(t)
+			for _, params := range tt.mockParams.feedbagManagerParams.buddyIconRefByNameParams {
+				feedbagManager.EXPECT().
+					BuddyIconRefByName(params.screenName).
+					Return(params.result, params.err)
+			}
 			for _, params := range tt.mockParams.feedbagParams {
 				feedbagManager.EXPECT().
 					Feedbag(params.screenName).
@@ -266,6 +272,12 @@ func TestBuddyService_BroadcastBuddyArrived(t *testing.T) {
 							results:    []wire.FeedbagItem{},
 						},
 					},
+					buddyIconRefByNameParams: buddyIconRefByNameParams{
+						{
+							screenName: state.NewIdentScreenName("user_screen_name"),
+							result:     nil,
+						},
+					},
 				},
 				messageRelayerParams: messageRelayerParams{
 					relayToScreenNamesParams: relayToScreenNamesParams{
@@ -307,28 +319,14 @@ func TestBuddyService_BroadcastBuddyArrived(t *testing.T) {
 							users:      []state.IdentScreenName{state.NewIdentScreenName("friend1")},
 						},
 					},
-					feedbagParams: feedbagParams{
+					buddyIconRefByNameParams: buddyIconRefByNameParams{
 						{
 							screenName: state.NewIdentScreenName("user_screen_name"),
-							results: []wire.FeedbagItem{
-								{
-									ClassID: wire.FeedbagClassIdBuddy,
-									Name:    "friend10",
-								},
-								{
-									ClassID: wire.FeedbagClassIdBart,
-									Name:    strconv.Itoa(int(wire.BARTTypesBadgeUrl)),
-								},
-								{
-									ClassID: wire.FeedbagClassIdBart,
-									Name:    strconv.Itoa(int(wire.BARTTypesBuddyIcon)),
-									TLVLBlock: wire.TLVLBlock{
-										TLVList: wire.TLVList{
-											wire.NewTLV(wire.FeedbagAttributesBartInfo, wire.BARTInfo{
-												Hash: []byte{'t', 'h', 'e', 'h', 'a', 's', 'h'},
-											}),
-										},
-									},
+							result: &wire.BARTID{
+								Type: wire.BARTTypesBuddyIcon,
+								BARTInfo: wire.BARTInfo{
+									Flags: wire.BARTFlagsKnown,
+									Hash:  []byte{'t', 'h', 'e', 'h', 'a', 's', 'h'},
 								},
 							},
 						},
@@ -379,10 +377,10 @@ func TestBuddyService_BroadcastBuddyArrived(t *testing.T) {
 					AdjacentUsers(params.screenName).
 					Return(params.users, params.err)
 			}
-			for _, params := range tc.mockParams.feedbagManagerParams.feedbagParams {
+			for _, params := range tc.mockParams.feedbagManagerParams.buddyIconRefByNameParams {
 				feedbagManager.EXPECT().
-					Feedbag(params.screenName).
-					Return(params.results, nil)
+					BuddyIconRefByName(params.screenName).
+					Return(params.result, params.err)
 			}
 			messageRelayer := newMockMessageRelayer(t)
 			for _, params := range tc.mockParams.messageRelayerParams.relayToScreenNamesParams {
@@ -566,10 +564,10 @@ func TestBuddyService_UnicastBuddyArrived(t *testing.T) {
 			destSession:   newTestSession("dest_screen_name"),
 			mockParams: mockParams{
 				feedbagManagerParams: feedbagManagerParams{
-					feedbagParams: feedbagParams{
+					buddyIconRefByNameParams: buddyIconRefByNameParams{
 						{
 							screenName: state.NewIdentScreenName("src_screen_name"),
-							results:    []wire.FeedbagItem{},
+							result:     nil,
 						},
 					},
 				},
@@ -623,6 +621,18 @@ func TestBuddyService_UnicastBuddyArrived(t *testing.T) {
 							},
 						},
 					},
+					buddyIconRefByNameParams: buddyIconRefByNameParams{
+						{
+							screenName: state.NewIdentScreenName("src_screen_name"),
+							result: &wire.BARTID{
+								Type: wire.BARTTypesBuddyIcon,
+								BARTInfo: wire.BARTInfo{
+									Flags: wire.BARTFlagsKnown,
+									Hash:  []byte{'t', 'h', 'e', 'h', 'a', 's', 'h'},
+								},
+							},
+						},
+					},
 				},
 				messageRelayerParams: messageRelayerParams{
 					relayToScreenNameParams: relayToScreenNameParams{
@@ -656,17 +666,16 @@ func TestBuddyService_UnicastBuddyArrived(t *testing.T) {
 	for _, tc := range cases {
 		t.Run(tc.name, func(t *testing.T) {
 			feedbagManager := newMockFeedbagManager(t)
-			for _, params := range tc.mockParams.feedbagManagerParams.feedbagParams {
+			for _, params := range tc.mockParams.feedbagManagerParams.buddyIconRefByNameParams {
 				feedbagManager.EXPECT().
-					Feedbag(params.screenName).
-					Return(params.results, nil)
+					BuddyIconRefByName(params.screenName).
+					Return(params.result, params.err)
 			}
 			messageRelayer := newMockMessageRelayer(t)
 			for _, params := range tc.mockParams.messageRelayerParams.relayToScreenNameParams {
 				messageRelayer.EXPECT().
 					RelayToScreenName(mock.Anything, params.screenName, params.message)
 			}
-
 			svc := NewBuddyService(messageRelayer, feedbagManager, nil)
 
 			err := svc.UnicastBuddyArrived(nil, tc.sourceSession, tc.destSession)

+ 58 - 0
foodgroup/mock_feedbag_manager_test.go

@@ -197,6 +197,64 @@ func (_c *mockFeedbagManager_Buddies_Call) RunAndReturn(run func(state.IdentScre
 	return _c
 }
 
+// BuddyIconRefByName provides a mock function with given fields: screenName
+func (_m *mockFeedbagManager) BuddyIconRefByName(screenName state.IdentScreenName) (*wire.BARTID, error) {
+	ret := _m.Called(screenName)
+
+	if len(ret) == 0 {
+		panic("no return value specified for BuddyIconRefByName")
+	}
+
+	var r0 *wire.BARTID
+	var r1 error
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) (*wire.BARTID, error)); ok {
+		return rf(screenName)
+	}
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) *wire.BARTID); ok {
+		r0 = rf(screenName)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*wire.BARTID)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok {
+		r1 = rf(screenName)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// mockFeedbagManager_BuddyIconRefByName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BuddyIconRefByName'
+type mockFeedbagManager_BuddyIconRefByName_Call struct {
+	*mock.Call
+}
+
+// BuddyIconRefByName is a helper method to define mock.On call
+//   - screenName state.IdentScreenName
+func (_e *mockFeedbagManager_Expecter) BuddyIconRefByName(screenName interface{}) *mockFeedbagManager_BuddyIconRefByName_Call {
+	return &mockFeedbagManager_BuddyIconRefByName_Call{Call: _e.mock.On("BuddyIconRefByName", screenName)}
+}
+
+func (_c *mockFeedbagManager_BuddyIconRefByName_Call) Run(run func(screenName state.IdentScreenName)) *mockFeedbagManager_BuddyIconRefByName_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(state.IdentScreenName))
+	})
+	return _c
+}
+
+func (_c *mockFeedbagManager_BuddyIconRefByName_Call) Return(_a0 *wire.BARTID, _a1 error) *mockFeedbagManager_BuddyIconRefByName_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *mockFeedbagManager_BuddyIconRefByName_Call) RunAndReturn(run func(state.IdentScreenName) (*wire.BARTID, error)) *mockFeedbagManager_BuddyIconRefByName_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
 // Feedbag provides a mock function with given fields: screenName
 func (_m *mockFeedbagManager) Feedbag(screenName state.IdentScreenName) ([]wire.FeedbagItem, error) {
 	ret := _m.Called(screenName)

+ 12 - 3
foodgroup/test_helpers.go

@@ -67,8 +67,8 @@ type sessionRetrieverParams struct {
 	retrieveSessionParams
 }
 
-// retrieveSessionParams is a helper struct that contains mock parameters for
-// SessionRetriever methods
+// retrieveSessionParams is the list of parameters passed at the mock
+// SessionRetriever.RetrieveSession call site
 type retrieveSessionParams []struct {
 	screenName state.IdentScreenName
 	result     *state.Session
@@ -257,6 +257,7 @@ type feedbagManagerParams struct {
 	feedbagParams
 	feedbagLastModifiedParams
 	feedbagDeleteParams
+	buddyIconRefByNameParams
 }
 
 // blockedStateParams is the list of parameters passed at the mock
@@ -311,6 +312,14 @@ type feedbagDeleteParams []struct {
 	items      []wire.FeedbagItem
 }
 
+// buddyIconRefByNameParams is the list of parameters passed at the mock
+// FeedbagManager.BuddyIconRefByName call site
+type buddyIconRefByNameParams []struct {
+	screenName state.IdentScreenName
+	result     *wire.BARTID
+	err        error
+}
+
 // messageRelayerParams is a helper struct that contains mock parameters for
 // MessageRelayer methods
 type messageRelayerParams struct {
@@ -348,7 +357,7 @@ type profileManagerParams struct {
 	setProfileParams
 }
 
-// retrieveByScreenNameParams is the list of parameters passed at the mock
+// retrieveProfileParams is the list of parameters passed at the mock
 // ProfileManager.Profile call site
 type retrieveProfileParams []struct {
 	screenName state.IdentScreenName

Разница между файлами не показана из-за своего большого размера
+ 655 - 214
server/http/mgmt_api_test.go


+ 207 - 0
server/http/mock_AccountRetriever.go

@@ -0,0 +1,207 @@
+// Code generated by mockery v2.45.0. DO NOT EDIT.
+
+package http
+
+import (
+	mail "net/mail"
+
+	state "github.com/mk6i/retro-aim-server/state"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// mockAccountRetriever is an autogenerated mock type for the AccountRetriever type
+type mockAccountRetriever struct {
+	mock.Mock
+}
+
+type mockAccountRetriever_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *mockAccountRetriever) EXPECT() *mockAccountRetriever_Expecter {
+	return &mockAccountRetriever_Expecter{mock: &_m.Mock}
+}
+
+// ConfirmStatusByName provides a mock function with given fields: screnName
+func (_m *mockAccountRetriever) ConfirmStatusByName(screnName state.IdentScreenName) (bool, error) {
+	ret := _m.Called(screnName)
+
+	if len(ret) == 0 {
+		panic("no return value specified for ConfirmStatusByName")
+	}
+
+	var r0 bool
+	var r1 error
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) (bool, error)); ok {
+		return rf(screnName)
+	}
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) bool); ok {
+		r0 = rf(screnName)
+	} else {
+		r0 = ret.Get(0).(bool)
+	}
+
+	if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok {
+		r1 = rf(screnName)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// mockAccountRetriever_ConfirmStatusByName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ConfirmStatusByName'
+type mockAccountRetriever_ConfirmStatusByName_Call struct {
+	*mock.Call
+}
+
+// ConfirmStatusByName is a helper method to define mock.On call
+//   - screnName state.IdentScreenName
+func (_e *mockAccountRetriever_Expecter) ConfirmStatusByName(screnName interface{}) *mockAccountRetriever_ConfirmStatusByName_Call {
+	return &mockAccountRetriever_ConfirmStatusByName_Call{Call: _e.mock.On("ConfirmStatusByName", screnName)}
+}
+
+func (_c *mockAccountRetriever_ConfirmStatusByName_Call) Run(run func(screnName state.IdentScreenName)) *mockAccountRetriever_ConfirmStatusByName_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(state.IdentScreenName))
+	})
+	return _c
+}
+
+func (_c *mockAccountRetriever_ConfirmStatusByName_Call) Return(_a0 bool, _a1 error) *mockAccountRetriever_ConfirmStatusByName_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *mockAccountRetriever_ConfirmStatusByName_Call) RunAndReturn(run func(state.IdentScreenName) (bool, error)) *mockAccountRetriever_ConfirmStatusByName_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// EmailAddressByName provides a mock function with given fields: screenName
+func (_m *mockAccountRetriever) EmailAddressByName(screenName state.IdentScreenName) (*mail.Address, error) {
+	ret := _m.Called(screenName)
+
+	if len(ret) == 0 {
+		panic("no return value specified for EmailAddressByName")
+	}
+
+	var r0 *mail.Address
+	var r1 error
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) (*mail.Address, error)); ok {
+		return rf(screenName)
+	}
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) *mail.Address); ok {
+		r0 = rf(screenName)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*mail.Address)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok {
+		r1 = rf(screenName)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// mockAccountRetriever_EmailAddressByName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'EmailAddressByName'
+type mockAccountRetriever_EmailAddressByName_Call struct {
+	*mock.Call
+}
+
+// EmailAddressByName is a helper method to define mock.On call
+//   - screenName state.IdentScreenName
+func (_e *mockAccountRetriever_Expecter) EmailAddressByName(screenName interface{}) *mockAccountRetriever_EmailAddressByName_Call {
+	return &mockAccountRetriever_EmailAddressByName_Call{Call: _e.mock.On("EmailAddressByName", screenName)}
+}
+
+func (_c *mockAccountRetriever_EmailAddressByName_Call) Run(run func(screenName state.IdentScreenName)) *mockAccountRetriever_EmailAddressByName_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(state.IdentScreenName))
+	})
+	return _c
+}
+
+func (_c *mockAccountRetriever_EmailAddressByName_Call) Return(_a0 *mail.Address, _a1 error) *mockAccountRetriever_EmailAddressByName_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *mockAccountRetriever_EmailAddressByName_Call) RunAndReturn(run func(state.IdentScreenName) (*mail.Address, error)) *mockAccountRetriever_EmailAddressByName_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// RegStatusByName provides a mock function with given fields: screenName
+func (_m *mockAccountRetriever) RegStatusByName(screenName state.IdentScreenName) (uint16, error) {
+	ret := _m.Called(screenName)
+
+	if len(ret) == 0 {
+		panic("no return value specified for RegStatusByName")
+	}
+
+	var r0 uint16
+	var r1 error
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) (uint16, error)); ok {
+		return rf(screenName)
+	}
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) uint16); ok {
+		r0 = rf(screenName)
+	} else {
+		r0 = ret.Get(0).(uint16)
+	}
+
+	if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok {
+		r1 = rf(screenName)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// mockAccountRetriever_RegStatusByName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RegStatusByName'
+type mockAccountRetriever_RegStatusByName_Call struct {
+	*mock.Call
+}
+
+// RegStatusByName is a helper method to define mock.On call
+//   - screenName state.IdentScreenName
+func (_e *mockAccountRetriever_Expecter) RegStatusByName(screenName interface{}) *mockAccountRetriever_RegStatusByName_Call {
+	return &mockAccountRetriever_RegStatusByName_Call{Call: _e.mock.On("RegStatusByName", screenName)}
+}
+
+func (_c *mockAccountRetriever_RegStatusByName_Call) Run(run func(screenName state.IdentScreenName)) *mockAccountRetriever_RegStatusByName_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(state.IdentScreenName))
+	})
+	return _c
+}
+
+func (_c *mockAccountRetriever_RegStatusByName_Call) Return(_a0 uint16, _a1 error) *mockAccountRetriever_RegStatusByName_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *mockAccountRetriever_RegStatusByName_Call) RunAndReturn(run func(state.IdentScreenName) (uint16, error)) *mockAccountRetriever_RegStatusByName_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// newMockAccountRetriever creates a new instance of mockAccountRetriever. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func newMockAccountRetriever(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *mockAccountRetriever {
+	mock := &mockAccountRetriever{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}

+ 90 - 0
server/http/mock_BARTRetriever.go

@@ -0,0 +1,90 @@
+// Code generated by mockery v2.45.0. DO NOT EDIT.
+
+package http
+
+import mock "github.com/stretchr/testify/mock"
+
+// mockBARTRetriever is an autogenerated mock type for the BARTRetriever type
+type mockBARTRetriever struct {
+	mock.Mock
+}
+
+type mockBARTRetriever_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *mockBARTRetriever) EXPECT() *mockBARTRetriever_Expecter {
+	return &mockBARTRetriever_Expecter{mock: &_m.Mock}
+}
+
+// BARTRetrieve provides a mock function with given fields: itemHash
+func (_m *mockBARTRetriever) BARTRetrieve(itemHash []byte) ([]byte, error) {
+	ret := _m.Called(itemHash)
+
+	if len(ret) == 0 {
+		panic("no return value specified for BARTRetrieve")
+	}
+
+	var r0 []byte
+	var r1 error
+	if rf, ok := ret.Get(0).(func([]byte) ([]byte, error)); ok {
+		return rf(itemHash)
+	}
+	if rf, ok := ret.Get(0).(func([]byte) []byte); ok {
+		r0 = rf(itemHash)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]byte)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func([]byte) error); ok {
+		r1 = rf(itemHash)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// mockBARTRetriever_BARTRetrieve_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BARTRetrieve'
+type mockBARTRetriever_BARTRetrieve_Call struct {
+	*mock.Call
+}
+
+// BARTRetrieve is a helper method to define mock.On call
+//   - itemHash []byte
+func (_e *mockBARTRetriever_Expecter) BARTRetrieve(itemHash interface{}) *mockBARTRetriever_BARTRetrieve_Call {
+	return &mockBARTRetriever_BARTRetrieve_Call{Call: _e.mock.On("BARTRetrieve", itemHash)}
+}
+
+func (_c *mockBARTRetriever_BARTRetrieve_Call) Run(run func(itemHash []byte)) *mockBARTRetriever_BARTRetrieve_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].([]byte))
+	})
+	return _c
+}
+
+func (_c *mockBARTRetriever_BARTRetrieve_Call) Return(_a0 []byte, _a1 error) *mockBARTRetriever_BARTRetrieve_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *mockBARTRetriever_BARTRetrieve_Call) RunAndReturn(run func([]byte) ([]byte, error)) *mockBARTRetriever_BARTRetrieve_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// newMockBARTRetriever creates a new instance of mockBARTRetriever. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func newMockBARTRetriever(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *mockBARTRetriever {
+	mock := &mockBARTRetriever{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}

+ 95 - 0
server/http/mock_FeedBagRetriever.go

@@ -0,0 +1,95 @@
+// Code generated by mockery v2.45.0. DO NOT EDIT.
+
+package http
+
+import (
+	state "github.com/mk6i/retro-aim-server/state"
+	mock "github.com/stretchr/testify/mock"
+
+	wire "github.com/mk6i/retro-aim-server/wire"
+)
+
+// mockFeedBagRetriever is an autogenerated mock type for the FeedBagRetriever type
+type mockFeedBagRetriever struct {
+	mock.Mock
+}
+
+type mockFeedBagRetriever_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *mockFeedBagRetriever) EXPECT() *mockFeedBagRetriever_Expecter {
+	return &mockFeedBagRetriever_Expecter{mock: &_m.Mock}
+}
+
+// BuddyIconRefByName provides a mock function with given fields: screenName
+func (_m *mockFeedBagRetriever) BuddyIconRefByName(screenName state.IdentScreenName) (*wire.BARTID, error) {
+	ret := _m.Called(screenName)
+
+	if len(ret) == 0 {
+		panic("no return value specified for BuddyIconRefByName")
+	}
+
+	var r0 *wire.BARTID
+	var r1 error
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) (*wire.BARTID, error)); ok {
+		return rf(screenName)
+	}
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) *wire.BARTID); ok {
+		r0 = rf(screenName)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*wire.BARTID)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok {
+		r1 = rf(screenName)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// mockFeedBagRetriever_BuddyIconRefByName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'BuddyIconRefByName'
+type mockFeedBagRetriever_BuddyIconRefByName_Call struct {
+	*mock.Call
+}
+
+// BuddyIconRefByName is a helper method to define mock.On call
+//   - screenName state.IdentScreenName
+func (_e *mockFeedBagRetriever_Expecter) BuddyIconRefByName(screenName interface{}) *mockFeedBagRetriever_BuddyIconRefByName_Call {
+	return &mockFeedBagRetriever_BuddyIconRefByName_Call{Call: _e.mock.On("BuddyIconRefByName", screenName)}
+}
+
+func (_c *mockFeedBagRetriever_BuddyIconRefByName_Call) Run(run func(screenName state.IdentScreenName)) *mockFeedBagRetriever_BuddyIconRefByName_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(state.IdentScreenName))
+	})
+	return _c
+}
+
+func (_c *mockFeedBagRetriever_BuddyIconRefByName_Call) Return(_a0 *wire.BARTID, _a1 error) *mockFeedBagRetriever_BuddyIconRefByName_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *mockFeedBagRetriever_BuddyIconRefByName_Call) RunAndReturn(run func(state.IdentScreenName) (*wire.BARTID, error)) *mockFeedBagRetriever_BuddyIconRefByName_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// newMockFeedBagRetriever creates a new instance of mockFeedBagRetriever. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func newMockFeedBagRetriever(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *mockFeedBagRetriever {
+	mock := &mockFeedBagRetriever{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}

+ 91 - 0
server/http/mock_ProfileRetriever.go

@@ -0,0 +1,91 @@
+// Code generated by mockery v2.45.0. DO NOT EDIT.
+
+package http
+
+import (
+	state "github.com/mk6i/retro-aim-server/state"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// mockProfileRetriever is an autogenerated mock type for the ProfileRetriever type
+type mockProfileRetriever struct {
+	mock.Mock
+}
+
+type mockProfileRetriever_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *mockProfileRetriever) EXPECT() *mockProfileRetriever_Expecter {
+	return &mockProfileRetriever_Expecter{mock: &_m.Mock}
+}
+
+// Profile provides a mock function with given fields: screenName
+func (_m *mockProfileRetriever) Profile(screenName state.IdentScreenName) (string, error) {
+	ret := _m.Called(screenName)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Profile")
+	}
+
+	var r0 string
+	var r1 error
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) (string, error)); ok {
+		return rf(screenName)
+	}
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) string); ok {
+		r0 = rf(screenName)
+	} else {
+		r0 = ret.Get(0).(string)
+	}
+
+	if rf, ok := ret.Get(1).(func(state.IdentScreenName) error); ok {
+		r1 = rf(screenName)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// mockProfileRetriever_Profile_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Profile'
+type mockProfileRetriever_Profile_Call struct {
+	*mock.Call
+}
+
+// Profile is a helper method to define mock.On call
+//   - screenName state.IdentScreenName
+func (_e *mockProfileRetriever_Expecter) Profile(screenName interface{}) *mockProfileRetriever_Profile_Call {
+	return &mockProfileRetriever_Profile_Call{Call: _e.mock.On("Profile", screenName)}
+}
+
+func (_c *mockProfileRetriever_Profile_Call) Run(run func(screenName state.IdentScreenName)) *mockProfileRetriever_Profile_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(state.IdentScreenName))
+	})
+	return _c
+}
+
+func (_c *mockProfileRetriever_Profile_Call) Return(_a0 string, _a1 error) *mockProfileRetriever_Profile_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *mockProfileRetriever_Profile_Call) RunAndReturn(run func(state.IdentScreenName) (string, error)) *mockProfileRetriever_Profile_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// newMockProfileRetriever creates a new instance of mockProfileRetriever. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func newMockProfileRetriever(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *mockProfileRetriever {
+	mock := &mockProfileRetriever{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}

+ 48 - 0
server/http/mock_session_retriever_test.go

@@ -67,6 +67,54 @@ func (_c *mockSessionRetriever_AllSessions_Call) RunAndReturn(run func() []*stat
 	return _c
 }
 
+// RetrieveByScreenName provides a mock function with given fields: screenName
+func (_m *mockSessionRetriever) RetrieveByScreenName(screenName state.IdentScreenName) *state.Session {
+	ret := _m.Called(screenName)
+
+	if len(ret) == 0 {
+		panic("no return value specified for RetrieveByScreenName")
+	}
+
+	var r0 *state.Session
+	if rf, ok := ret.Get(0).(func(state.IdentScreenName) *state.Session); ok {
+		r0 = rf(screenName)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*state.Session)
+		}
+	}
+
+	return r0
+}
+
+// mockSessionRetriever_RetrieveByScreenName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RetrieveByScreenName'
+type mockSessionRetriever_RetrieveByScreenName_Call struct {
+	*mock.Call
+}
+
+// RetrieveByScreenName is a helper method to define mock.On call
+//   - screenName state.IdentScreenName
+func (_e *mockSessionRetriever_Expecter) RetrieveByScreenName(screenName interface{}) *mockSessionRetriever_RetrieveByScreenName_Call {
+	return &mockSessionRetriever_RetrieveByScreenName_Call{Call: _e.mock.On("RetrieveByScreenName", screenName)}
+}
+
+func (_c *mockSessionRetriever_RetrieveByScreenName_Call) Run(run func(screenName state.IdentScreenName)) *mockSessionRetriever_RetrieveByScreenName_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(state.IdentScreenName))
+	})
+	return _c
+}
+
+func (_c *mockSessionRetriever_RetrieveByScreenName_Call) Return(_a0 *state.Session) *mockSessionRetriever_RetrieveByScreenName_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *mockSessionRetriever_RetrieveByScreenName_Call) RunAndReturn(run func(state.IdentScreenName) *state.Session) *mockSessionRetriever_RetrieveByScreenName_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
 // newMockSessionRetriever creates a new instance of mockSessionRetriever. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
 // The first argument is typically a *testing.T value.
 func newMockSessionRetriever(t interface {

+ 217 - 0
server/http/test_helpers.go

@@ -0,0 +1,217 @@
+package http
+
+import (
+	"context"
+	"net/mail"
+
+	"github.com/mk6i/retro-aim-server/state"
+	"github.com/mk6i/retro-aim-server/wire"
+)
+
+type mockParams struct {
+	accountRetrieverParams
+	bartRetrieverParams
+	chatRoomCreatorParams
+	chatRoomRetrieverParams
+	chatSessionRetrieverParams
+	feedBagRetrieverParams
+	messageRelayerParams
+	profileRetrieverParams
+	sessionRetrieverParams
+	userManagerParams
+}
+
+// accountRetrieverParams is a helper struct that contains mock parameters for
+// accountRetriever methods
+type accountRetrieverParams struct {
+	emailAddressByNameParams
+	regStatusByNameParams
+	confirmStatusByNameParams
+}
+
+// emailAddressByNameParams is the list of parameters passed at the mock
+// accountRetriever.EmailAddressByName call site
+type emailAddressByNameParams []struct {
+	screenName state.IdentScreenName
+	result     *mail.Address
+	err        error
+}
+
+// regStatusByNameParams is the list of parameters passed at the mock
+// accountRetriever.RegStatusByName call site
+type regStatusByNameParams []struct {
+	screenName state.IdentScreenName
+	result     uint16
+	err        error
+}
+
+// confirmStatusByNameParams is the list of parameters passed at the mock
+// accountRetriever.ConfirmStatusByName call site
+type confirmStatusByNameParams []struct {
+	screenName state.IdentScreenName
+	result     bool
+	err        error
+}
+
+// bartRetrieverParams is a helper struct that contains mock parameters for
+// BARTRetriever methods
+type bartRetrieverParams struct {
+	bartRetrieveParams
+}
+
+// bartRetrieveParams is the list of parameters passed at the mock
+// BARTRetriever.BARTRetrieveParams call site
+type bartRetrieveParams []struct {
+	itemHash []byte
+	result   []byte
+	err      error
+}
+
+// chatRoomCreatorParams is a helper struct that contains mock parameters for
+// ChatRoomCreator methods
+type chatRoomCreatorParams struct {
+	createChatRoomParams
+}
+
+// createChatRoomParams is the list of parameters passed at the mock
+// ChatRoomCreator.CreateChatRoom call site
+type createChatRoomParams []struct {
+	chatRoom *state.ChatRoom
+	err      error
+}
+
+// chatRoomRetrieverParams is a helper struct that contains mock parameters for
+// ChatRoomRetriever methods
+type chatRoomRetrieverParams struct {
+	allChatRoomsParams
+}
+
+// allChatRoomsParams is the list of parameters passed at the mock
+// ChatRoomRetriever.AllChatRooms call site
+type allChatRoomsParams []struct {
+	exchange uint16
+	result   []state.ChatRoom
+	err      error
+}
+
+// chatRoomRetrieverParams is a helper struct that contains mock parameters for
+// ChatRoomRetriever methods
+type chatSessionRetrieverParams struct {
+	chatSessionRetrieverAllSessionsParams
+}
+
+// chatSessionRetrieverAllSessionsParams is the list of parameters passed at the mock
+// ChatSessionRetriever.AllSessions call site
+type chatSessionRetrieverAllSessionsParams []struct {
+	cookie string
+	result []*state.Session
+}
+
+// feedBagRetrieverParams is a helper struct that contains mock parameters for
+// FeedBagRetriever methods
+type feedBagRetrieverParams struct {
+	buddyIconRefByNameParams
+}
+
+// buddyIconRefByNameParams is the list of parameters passed at the mock
+// FeedBagRetriever.BuddyIconRefByNameParams call site
+type buddyIconRefByNameParams []struct {
+	screenName state.IdentScreenName
+	result     *wire.BARTID
+	err        error
+}
+
+// messageRelayerParams is a helper struct that contains mock parameters for
+// MessageRelayer methods
+type messageRelayerParams struct {
+	relayToScreenNameParams
+}
+
+// relayToScreenNameParams is the list of parameters passed at the mock
+// MessageRelayer.RelayToScreenNameParams call site
+type relayToScreenNameParams []struct {
+	ctx        context.Context
+	screenName state.IdentScreenName
+	msg        wire.SNACMessage
+}
+
+// profileRetrieverParams is a helper struct that contains mock parameters for
+// ProfileRetriever methods
+type profileRetrieverParams struct {
+	retrieveProfileParams
+}
+
+// retrieveProfileParams is the list of parameters passed at the mock
+// ProfileRetriever.Profile call site
+type retrieveProfileParams []struct {
+	screenName state.IdentScreenName
+	result     string
+	err        error
+}
+
+// sessionRetrieverParams is a helper struct that contains mock parameters for
+// SessionRetriever methods
+type sessionRetrieverParams struct {
+	sessionRetrieverAllSessionsParams
+	retrieveSessionByNameParams
+}
+
+// sessionRetrieverAllSessionsParams is the list of parameters passed at the mock
+// SessionRetriever.AllSessions call site
+type sessionRetrieverAllSessionsParams []struct {
+	result []*state.Session
+}
+
+// retrieveSessionParams is the list of parameters passed at the mock
+// SessionRetriever.RetrieveSessionByName call site
+type retrieveSessionByNameParams []struct {
+	screenName state.IdentScreenName
+	result     *state.Session
+}
+
+// userManagerParams is a helper struct that contains mock parameters for
+// UserManager methods
+type userManagerParams struct {
+	allUsersParams
+	deleteUserParams
+	getUserParams
+	insertUserParams
+	setUserPasswordParams
+}
+
+// allUsersParams is the list of parameters passed at the mock
+// UserManager.AllUsers call site
+type allUsersParams []struct {
+	result []state.User
+	err    error
+}
+
+// deleteUserParams is the list of parameters passed at the mock
+// UserManager.DeleteUser call site
+type deleteUserParams []struct {
+	screenName state.IdentScreenName
+	err        error
+}
+
+// getUserParams is the list of parameters passed at the mock
+// UserManager.User call site
+type getUserParams []struct {
+	screenName state.IdentScreenName
+	result     *state.User
+	err        error
+}
+
+// insertUserParams is the list of parameters passed at the mock
+// UserManager.InsertUser call site
+type insertUserParams []struct {
+	u   state.User
+	err error
+}
+
+// setUserPasswordParams is the list of parameters passed at the mock
+// UserManager.SetUserPassword call site
+type setUserPasswordParams []struct {
+	screenName  state.IdentScreenName
+	newPassword string
+	err         error
+}

+ 91 - 0
server/oscar/mock_HandlerFunc.go

@@ -0,0 +1,91 @@
+// Code generated by mockery v2.45.0. DO NOT EDIT.
+
+package oscar
+
+import (
+	context "context"
+	io "io"
+
+	mock "github.com/stretchr/testify/mock"
+
+	state "github.com/mk6i/retro-aim-server/state"
+
+	wire "github.com/mk6i/retro-aim-server/wire"
+)
+
+// mockHandlerFunc is an autogenerated mock type for the HandlerFunc type
+type mockHandlerFunc struct {
+	mock.Mock
+}
+
+type mockHandlerFunc_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *mockHandlerFunc) EXPECT() *mockHandlerFunc_Expecter {
+	return &mockHandlerFunc_Expecter{mock: &_m.Mock}
+}
+
+// Execute provides a mock function with given fields: ctx, sess, inFrame, r, rw
+func (_m *mockHandlerFunc) Execute(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter) error {
+	ret := _m.Called(ctx, sess, inFrame, r, rw)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Execute")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(context.Context, *state.Session, wire.SNACFrame, io.Reader, ResponseWriter) error); ok {
+		r0 = rf(ctx, sess, inFrame, r, rw)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// mockHandlerFunc_Execute_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Execute'
+type mockHandlerFunc_Execute_Call struct {
+	*mock.Call
+}
+
+// Execute is a helper method to define mock.On call
+//   - ctx context.Context
+//   - sess *state.Session
+//   - inFrame wire.SNACFrame
+//   - r io.Reader
+//   - rw ResponseWriter
+func (_e *mockHandlerFunc_Expecter) Execute(ctx interface{}, sess interface{}, inFrame interface{}, r interface{}, rw interface{}) *mockHandlerFunc_Execute_Call {
+	return &mockHandlerFunc_Execute_Call{Call: _e.mock.On("Execute", ctx, sess, inFrame, r, rw)}
+}
+
+func (_c *mockHandlerFunc_Execute_Call) Run(run func(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw ResponseWriter)) *mockHandlerFunc_Execute_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(context.Context), args[1].(*state.Session), args[2].(wire.SNACFrame), args[3].(io.Reader), args[4].(ResponseWriter))
+	})
+	return _c
+}
+
+func (_c *mockHandlerFunc_Execute_Call) Return(_a0 error) *mockHandlerFunc_Execute_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *mockHandlerFunc_Execute_Call) RunAndReturn(run func(context.Context, *state.Session, wire.SNACFrame, io.Reader, ResponseWriter) error) *mockHandlerFunc_Execute_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// newMockHandlerFunc creates a new instance of mockHandlerFunc. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func newMockHandlerFunc(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *mockHandlerFunc {
+	mock := &mockHandlerFunc{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}

+ 82 - 0
server/oscar/mock_ResponseWriter.go

@@ -0,0 +1,82 @@
+// Code generated by mockery v2.45.0. DO NOT EDIT.
+
+package oscar
+
+import (
+	wire "github.com/mk6i/retro-aim-server/wire"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// mockResponseWriter is an autogenerated mock type for the ResponseWriter type
+type mockResponseWriter struct {
+	mock.Mock
+}
+
+type mockResponseWriter_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *mockResponseWriter) EXPECT() *mockResponseWriter_Expecter {
+	return &mockResponseWriter_Expecter{mock: &_m.Mock}
+}
+
+// SendSNAC provides a mock function with given fields: frame, body
+func (_m *mockResponseWriter) SendSNAC(frame wire.SNACFrame, body interface{}) error {
+	ret := _m.Called(frame, body)
+
+	if len(ret) == 0 {
+		panic("no return value specified for SendSNAC")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(wire.SNACFrame, interface{}) error); ok {
+		r0 = rf(frame, body)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// mockResponseWriter_SendSNAC_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SendSNAC'
+type mockResponseWriter_SendSNAC_Call struct {
+	*mock.Call
+}
+
+// SendSNAC is a helper method to define mock.On call
+//   - frame wire.SNACFrame
+//   - body interface{}
+func (_e *mockResponseWriter_Expecter) SendSNAC(frame interface{}, body interface{}) *mockResponseWriter_SendSNAC_Call {
+	return &mockResponseWriter_SendSNAC_Call{Call: _e.mock.On("SendSNAC", frame, body)}
+}
+
+func (_c *mockResponseWriter_SendSNAC_Call) Run(run func(frame wire.SNACFrame, body interface{})) *mockResponseWriter_SendSNAC_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(wire.SNACFrame), args[1].(interface{}))
+	})
+	return _c
+}
+
+func (_c *mockResponseWriter_SendSNAC_Call) Return(_a0 error) *mockResponseWriter_SendSNAC_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *mockResponseWriter_SendSNAC_Call) RunAndReturn(run func(wire.SNACFrame, interface{}) error) *mockResponseWriter_SendSNAC_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// newMockResponseWriter creates a new instance of mockResponseWriter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func newMockResponseWriter(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *mockResponseWriter {
+	mock := &mockResponseWriter{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}

+ 72 - 0
state/user_store_test.go

@@ -1796,3 +1796,75 @@ func TestSQLiteUserStore_DeleteMessages(t *testing.T) {
 		assert.Len(t, messages, 1)
 	})
 }
+
+func TestSQLiteUserStore_BuddyIconRefByNameExistingRef(t *testing.T) {
+	defer func() {
+		assert.NoError(t, os.Remove(testFile))
+	}()
+	screenName := NewIdentScreenName("TalkingTyler")
+	testHash := []byte{'t', 'h', 'e', 'h', 'a', 's', 'h'}
+
+	feedbagStore, err := NewSQLiteUserStore(testFile)
+	assert.NoError(t, err)
+
+	itemsIn := []wire.FeedbagItem{
+		{
+			Name:    "1",
+			ClassID: wire.FeedbagClassIdBart,
+			TLVLBlock: wire.TLVLBlock{
+				TLVList: wire.TLVList{
+					wire.NewTLV(wire.FeedbagAttributesBartInfo, wire.BARTInfo{
+						Hash: testHash,
+					}),
+				},
+			},
+		},
+	}
+	if err := feedbagStore.FeedbagUpsert(screenName, itemsIn); err != nil {
+		t.Fatalf("failed to upsert: %s", err.Error())
+	}
+
+	b, err := feedbagStore.BuddyIconRefByName(screenName)
+	assert.NoError(t, err)
+
+	if !reflect.DeepEqual(b.BARTInfo.Hash, testHash) {
+		t.Fatalf("expected hash did not match")
+	}
+}
+
+func TestSQLiteUserStore_BuddyIconRefByNameMissingRef(t *testing.T) {
+	defer func() {
+		assert.NoError(t, os.Remove(testFile))
+	}()
+
+	existingScreenName := NewIdentScreenName("TalkingTyler")
+	queryScreenName := NewIdentScreenName("SingingSuzy")
+	testHash := []byte{'t', 'h', 'e', 'h', 'a', 's', 'h'}
+
+	feedbagStore, err := NewSQLiteUserStore(testFile)
+	assert.NoError(t, err)
+
+	itemsIn := []wire.FeedbagItem{
+		{
+			Name:    "1",
+			ClassID: wire.FeedbagClassIdBart,
+			TLVLBlock: wire.TLVLBlock{
+				TLVList: wire.TLVList{
+					wire.NewTLV(wire.FeedbagAttributesBartInfo, wire.BARTInfo{
+						Hash: testHash,
+					}),
+				},
+			},
+		},
+	}
+	if err := feedbagStore.FeedbagUpsert(existingScreenName, itemsIn); err != nil {
+		t.Fatalf("failed to upsert: %s", err.Error())
+	}
+
+	b, err := feedbagStore.BuddyIconRefByName(queryScreenName)
+	assert.NoError(t, err)
+
+	if b != nil {
+		t.Fatalf("empty BARTID expected")
+	}
+}

Некоторые файлы не были показаны из-за большого количества измененных файлов