diff --git a/backend/.mockery.yaml b/backend/.mockery.yaml index aed98f2..d6c04f9 100644 --- a/backend/.mockery.yaml +++ b/backend/.mockery.yaml @@ -1,5 +1,6 @@ dir: '{{.InterfaceDir}}/mocks' structname: Mock{{.InterfaceName}} +filename: mock_{{.InterfaceName | snakecase}}.go pkgname: mocks template: testify template-data: @@ -7,6 +8,7 @@ template-data: packages: github.com/cocursor/backend/internal/application/team: interfaces: + CacheManager: {} HTTPClientInterface: {} ProjectConfigStoreInterface: {} TeamServiceInterface: {} diff --git a/backend/internal/application/team/mocks/mock_cache_manager.go b/backend/internal/application/team/mocks/mock_cache_manager.go new file mode 100644 index 0000000..73e86c8 --- /dev/null +++ b/backend/internal/application/team/mocks/mock_cache_manager.go @@ -0,0 +1,122 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + mock "github.com/stretchr/testify/mock" +) + +// NewMockCacheManager creates a new instance of MockCacheManager. 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 NewMockCacheManager(t interface { + mock.TestingT + Cleanup(func()) +}) *MockCacheManager { + mock := &MockCacheManager{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockCacheManager is an autogenerated mock type for the CacheManager type +type MockCacheManager struct { + mock.Mock +} + +type MockCacheManager_Expecter struct { + mock *mock.Mock +} + +func (_m *MockCacheManager) EXPECT() *MockCacheManager_Expecter { + return &MockCacheManager_Expecter{mock: &_m.Mock} +} + +// InvalidateMemberCache provides a mock function for the type MockCacheManager +func (_mock *MockCacheManager) InvalidateMemberCache(teamID string, memberID string) { + _mock.Called(teamID, memberID) + return +} + +// MockCacheManager_InvalidateMemberCache_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InvalidateMemberCache' +type MockCacheManager_InvalidateMemberCache_Call struct { + *mock.Call +} + +// InvalidateMemberCache is a helper method to define mock.On call +// - teamID string +// - memberID string +func (_e *MockCacheManager_Expecter) InvalidateMemberCache(teamID interface{}, memberID interface{}) *MockCacheManager_InvalidateMemberCache_Call { + return &MockCacheManager_InvalidateMemberCache_Call{Call: _e.mock.On("InvalidateMemberCache", teamID, memberID)} +} + +func (_c *MockCacheManager_InvalidateMemberCache_Call) Run(run func(teamID string, memberID string)) *MockCacheManager_InvalidateMemberCache_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockCacheManager_InvalidateMemberCache_Call) Return() *MockCacheManager_InvalidateMemberCache_Call { + _c.Call.Return() + return _c +} + +func (_c *MockCacheManager_InvalidateMemberCache_Call) RunAndReturn(run func(teamID string, memberID string)) *MockCacheManager_InvalidateMemberCache_Call { + _c.Run(run) + return _c +} + +// InvalidateTeamCache provides a mock function for the type MockCacheManager +func (_mock *MockCacheManager) InvalidateTeamCache(teamID string) { + _mock.Called(teamID) + return +} + +// MockCacheManager_InvalidateTeamCache_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'InvalidateTeamCache' +type MockCacheManager_InvalidateTeamCache_Call struct { + *mock.Call +} + +// InvalidateTeamCache is a helper method to define mock.On call +// - teamID string +func (_e *MockCacheManager_Expecter) InvalidateTeamCache(teamID interface{}) *MockCacheManager_InvalidateTeamCache_Call { + return &MockCacheManager_InvalidateTeamCache_Call{Call: _e.mock.On("InvalidateTeamCache", teamID)} +} + +func (_c *MockCacheManager_InvalidateTeamCache_Call) Run(run func(teamID string)) *MockCacheManager_InvalidateTeamCache_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockCacheManager_InvalidateTeamCache_Call) Return() *MockCacheManager_InvalidateTeamCache_Call { + _c.Call.Return() + return _c +} + +func (_c *MockCacheManager_InvalidateTeamCache_Call) RunAndReturn(run func(teamID string)) *MockCacheManager_InvalidateTeamCache_Call { + _c.Run(run) + return _c +} diff --git a/backend/internal/application/team/mocks/mock_http_client_interface.go b/backend/internal/application/team/mocks/mock_http_client_interface.go new file mode 100644 index 0000000..7382626 --- /dev/null +++ b/backend/internal/application/team/mocks/mock_http_client_interface.go @@ -0,0 +1,100 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "net/http" + + mock "github.com/stretchr/testify/mock" +) + +// NewMockHTTPClientInterface creates a new instance of MockHTTPClientInterface. 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 NewMockHTTPClientInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *MockHTTPClientInterface { + mock := &MockHTTPClientInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockHTTPClientInterface is an autogenerated mock type for the HTTPClientInterface type +type MockHTTPClientInterface struct { + mock.Mock +} + +type MockHTTPClientInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *MockHTTPClientInterface) EXPECT() *MockHTTPClientInterface_Expecter { + return &MockHTTPClientInterface_Expecter{mock: &_m.Mock} +} + +// Do provides a mock function for the type MockHTTPClientInterface +func (_mock *MockHTTPClientInterface) Do(req *http.Request) (*http.Response, error) { + ret := _mock.Called(req) + + if len(ret) == 0 { + panic("no return value specified for Do") + } + + var r0 *http.Response + var r1 error + if returnFunc, ok := ret.Get(0).(func(*http.Request) (*http.Response, error)); ok { + return returnFunc(req) + } + if returnFunc, ok := ret.Get(0).(func(*http.Request) *http.Response); ok { + r0 = returnFunc(req) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*http.Response) + } + } + if returnFunc, ok := ret.Get(1).(func(*http.Request) error); ok { + r1 = returnFunc(req) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockHTTPClientInterface_Do_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Do' +type MockHTTPClientInterface_Do_Call struct { + *mock.Call +} + +// Do is a helper method to define mock.On call +// - req *http.Request +func (_e *MockHTTPClientInterface_Expecter) Do(req interface{}) *MockHTTPClientInterface_Do_Call { + return &MockHTTPClientInterface_Do_Call{Call: _e.mock.On("Do", req)} +} + +func (_c *MockHTTPClientInterface_Do_Call) Run(run func(req *http.Request)) *MockHTTPClientInterface_Do_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 *http.Request + if args[0] != nil { + arg0 = args[0].(*http.Request) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockHTTPClientInterface_Do_Call) Return(response *http.Response, err error) *MockHTTPClientInterface_Do_Call { + _c.Call.Return(response, err) + return _c +} + +func (_c *MockHTTPClientInterface_Do_Call) RunAndReturn(run func(req *http.Request) (*http.Response, error)) *MockHTTPClientInterface_Do_Call { + _c.Call.Return(run) + return _c +} diff --git a/backend/internal/application/team/mocks/mock_project_config_store_interface.go b/backend/internal/application/team/mocks/mock_project_config_store_interface.go new file mode 100644 index 0000000..24ea4cd --- /dev/null +++ b/backend/internal/application/team/mocks/mock_project_config_store_interface.go @@ -0,0 +1,342 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "github.com/cocursor/backend/internal/domain/team" + mock "github.com/stretchr/testify/mock" +) + +// NewMockProjectConfigStoreInterface creates a new instance of MockProjectConfigStoreInterface. 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 NewMockProjectConfigStoreInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *MockProjectConfigStoreInterface { + mock := &MockProjectConfigStoreInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockProjectConfigStoreInterface is an autogenerated mock type for the ProjectConfigStoreInterface type +type MockProjectConfigStoreInterface struct { + mock.Mock +} + +type MockProjectConfigStoreInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *MockProjectConfigStoreInterface) EXPECT() *MockProjectConfigStoreInterface_Expecter { + return &MockProjectConfigStoreInterface_Expecter{mock: &_m.Mock} +} + +// AddProject provides a mock function for the type MockProjectConfigStoreInterface +func (_mock *MockProjectConfigStoreInterface) AddProject(project team.ProjectMatcher) error { + ret := _mock.Called(project) + + if len(ret) == 0 { + panic("no return value specified for AddProject") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(team.ProjectMatcher) error); ok { + r0 = returnFunc(project) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockProjectConfigStoreInterface_AddProject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddProject' +type MockProjectConfigStoreInterface_AddProject_Call struct { + *mock.Call +} + +// AddProject is a helper method to define mock.On call +// - project team.ProjectMatcher +func (_e *MockProjectConfigStoreInterface_Expecter) AddProject(project interface{}) *MockProjectConfigStoreInterface_AddProject_Call { + return &MockProjectConfigStoreInterface_AddProject_Call{Call: _e.mock.On("AddProject", project)} +} + +func (_c *MockProjectConfigStoreInterface_AddProject_Call) Run(run func(project team.ProjectMatcher)) *MockProjectConfigStoreInterface_AddProject_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 team.ProjectMatcher + if args[0] != nil { + arg0 = args[0].(team.ProjectMatcher) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockProjectConfigStoreInterface_AddProject_Call) Return(err error) *MockProjectConfigStoreInterface_AddProject_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockProjectConfigStoreInterface_AddProject_Call) RunAndReturn(run func(project team.ProjectMatcher) error) *MockProjectConfigStoreInterface_AddProject_Call { + _c.Call.Return(run) + return _c +} + +// GetRepoURLs provides a mock function for the type MockProjectConfigStoreInterface +func (_mock *MockProjectConfigStoreInterface) GetRepoURLs() []string { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for GetRepoURLs") + } + + var r0 []string + if returnFunc, ok := ret.Get(0).(func() []string); ok { + r0 = returnFunc() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + return r0 +} + +// MockProjectConfigStoreInterface_GetRepoURLs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRepoURLs' +type MockProjectConfigStoreInterface_GetRepoURLs_Call struct { + *mock.Call +} + +// GetRepoURLs is a helper method to define mock.On call +func (_e *MockProjectConfigStoreInterface_Expecter) GetRepoURLs() *MockProjectConfigStoreInterface_GetRepoURLs_Call { + return &MockProjectConfigStoreInterface_GetRepoURLs_Call{Call: _e.mock.On("GetRepoURLs")} +} + +func (_c *MockProjectConfigStoreInterface_GetRepoURLs_Call) Run(run func()) *MockProjectConfigStoreInterface_GetRepoURLs_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockProjectConfigStoreInterface_GetRepoURLs_Call) Return(strings []string) *MockProjectConfigStoreInterface_GetRepoURLs_Call { + _c.Call.Return(strings) + return _c +} + +func (_c *MockProjectConfigStoreInterface_GetRepoURLs_Call) RunAndReturn(run func() []string) *MockProjectConfigStoreInterface_GetRepoURLs_Call { + _c.Call.Return(run) + return _c +} + +// Load provides a mock function for the type MockProjectConfigStoreInterface +func (_mock *MockProjectConfigStoreInterface) Load() (*team.TeamProjectConfig, error) { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Load") + } + + var r0 *team.TeamProjectConfig + var r1 error + if returnFunc, ok := ret.Get(0).(func() (*team.TeamProjectConfig, error)); ok { + return returnFunc() + } + if returnFunc, ok := ret.Get(0).(func() *team.TeamProjectConfig); ok { + r0 = returnFunc() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*team.TeamProjectConfig) + } + } + if returnFunc, ok := ret.Get(1).(func() error); ok { + r1 = returnFunc() + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockProjectConfigStoreInterface_Load_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Load' +type MockProjectConfigStoreInterface_Load_Call struct { + *mock.Call +} + +// Load is a helper method to define mock.On call +func (_e *MockProjectConfigStoreInterface_Expecter) Load() *MockProjectConfigStoreInterface_Load_Call { + return &MockProjectConfigStoreInterface_Load_Call{Call: _e.mock.On("Load")} +} + +func (_c *MockProjectConfigStoreInterface_Load_Call) Run(run func()) *MockProjectConfigStoreInterface_Load_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockProjectConfigStoreInterface_Load_Call) Return(teamProjectConfig *team.TeamProjectConfig, err error) *MockProjectConfigStoreInterface_Load_Call { + _c.Call.Return(teamProjectConfig, err) + return _c +} + +func (_c *MockProjectConfigStoreInterface_Load_Call) RunAndReturn(run func() (*team.TeamProjectConfig, error)) *MockProjectConfigStoreInterface_Load_Call { + _c.Call.Return(run) + return _c +} + +// RemoveProject provides a mock function for the type MockProjectConfigStoreInterface +func (_mock *MockProjectConfigStoreInterface) RemoveProject(projectID string) error { + ret := _mock.Called(projectID) + + if len(ret) == 0 { + panic("no return value specified for RemoveProject") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string) error); ok { + r0 = returnFunc(projectID) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockProjectConfigStoreInterface_RemoveProject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveProject' +type MockProjectConfigStoreInterface_RemoveProject_Call struct { + *mock.Call +} + +// RemoveProject is a helper method to define mock.On call +// - projectID string +func (_e *MockProjectConfigStoreInterface_Expecter) RemoveProject(projectID interface{}) *MockProjectConfigStoreInterface_RemoveProject_Call { + return &MockProjectConfigStoreInterface_RemoveProject_Call{Call: _e.mock.On("RemoveProject", projectID)} +} + +func (_c *MockProjectConfigStoreInterface_RemoveProject_Call) Run(run func(projectID string)) *MockProjectConfigStoreInterface_RemoveProject_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockProjectConfigStoreInterface_RemoveProject_Call) Return(err error) *MockProjectConfigStoreInterface_RemoveProject_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockProjectConfigStoreInterface_RemoveProject_Call) RunAndReturn(run func(projectID string) error) *MockProjectConfigStoreInterface_RemoveProject_Call { + _c.Call.Return(run) + return _c +} + +// Save provides a mock function for the type MockProjectConfigStoreInterface +func (_mock *MockProjectConfigStoreInterface) Save(config *team.TeamProjectConfig) error { + ret := _mock.Called(config) + + if len(ret) == 0 { + panic("no return value specified for Save") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(*team.TeamProjectConfig) error); ok { + r0 = returnFunc(config) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockProjectConfigStoreInterface_Save_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Save' +type MockProjectConfigStoreInterface_Save_Call struct { + *mock.Call +} + +// Save is a helper method to define mock.On call +// - config *team.TeamProjectConfig +func (_e *MockProjectConfigStoreInterface_Expecter) Save(config interface{}) *MockProjectConfigStoreInterface_Save_Call { + return &MockProjectConfigStoreInterface_Save_Call{Call: _e.mock.On("Save", config)} +} + +func (_c *MockProjectConfigStoreInterface_Save_Call) Run(run func(config *team.TeamProjectConfig)) *MockProjectConfigStoreInterface_Save_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 *team.TeamProjectConfig + if args[0] != nil { + arg0 = args[0].(*team.TeamProjectConfig) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockProjectConfigStoreInterface_Save_Call) Return(err error) *MockProjectConfigStoreInterface_Save_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockProjectConfigStoreInterface_Save_Call) RunAndReturn(run func(config *team.TeamProjectConfig) error) *MockProjectConfigStoreInterface_Save_Call { + _c.Call.Return(run) + return _c +} + +// UpdateProject provides a mock function for the type MockProjectConfigStoreInterface +func (_mock *MockProjectConfigStoreInterface) UpdateProject(project team.ProjectMatcher) error { + ret := _mock.Called(project) + + if len(ret) == 0 { + panic("no return value specified for UpdateProject") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(team.ProjectMatcher) error); ok { + r0 = returnFunc(project) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockProjectConfigStoreInterface_UpdateProject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateProject' +type MockProjectConfigStoreInterface_UpdateProject_Call struct { + *mock.Call +} + +// UpdateProject is a helper method to define mock.On call +// - project team.ProjectMatcher +func (_e *MockProjectConfigStoreInterface_Expecter) UpdateProject(project interface{}) *MockProjectConfigStoreInterface_UpdateProject_Call { + return &MockProjectConfigStoreInterface_UpdateProject_Call{Call: _e.mock.On("UpdateProject", project)} +} + +func (_c *MockProjectConfigStoreInterface_UpdateProject_Call) Run(run func(project team.ProjectMatcher)) *MockProjectConfigStoreInterface_UpdateProject_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 team.ProjectMatcher + if args[0] != nil { + arg0 = args[0].(team.ProjectMatcher) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockProjectConfigStoreInterface_UpdateProject_Call) Return(err error) *MockProjectConfigStoreInterface_UpdateProject_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockProjectConfigStoreInterface_UpdateProject_Call) RunAndReturn(run func(project team.ProjectMatcher) error) *MockProjectConfigStoreInterface_UpdateProject_Call { + _c.Call.Return(run) + return _c +} diff --git a/backend/internal/application/team/mocks/mock_team_service_interface.go b/backend/internal/application/team/mocks/mock_team_service_interface.go new file mode 100644 index 0000000..3c1efdf --- /dev/null +++ b/backend/internal/application/team/mocks/mock_team_service_interface.go @@ -0,0 +1,417 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "github.com/cocursor/backend/internal/domain/team" + mock "github.com/stretchr/testify/mock" +) + +// NewMockTeamServiceInterface creates a new instance of MockTeamServiceInterface. 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 NewMockTeamServiceInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *MockTeamServiceInterface { + mock := &MockTeamServiceInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockTeamServiceInterface is an autogenerated mock type for the TeamServiceInterface type +type MockTeamServiceInterface struct { + mock.Mock +} + +type MockTeamServiceInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *MockTeamServiceInterface) EXPECT() *MockTeamServiceInterface_Expecter { + return &MockTeamServiceInterface_Expecter{mock: &_m.Mock} +} + +// GetOnlineMembers provides a mock function for the type MockTeamServiceInterface +func (_mock *MockTeamServiceInterface) GetOnlineMembers(teamID string) ([]*team.TeamMember, error) { + ret := _mock.Called(teamID) + + if len(ret) == 0 { + panic("no return value specified for GetOnlineMembers") + } + + var r0 []*team.TeamMember + var r1 error + if returnFunc, ok := ret.Get(0).(func(string) ([]*team.TeamMember, error)); ok { + return returnFunc(teamID) + } + if returnFunc, ok := ret.Get(0).(func(string) []*team.TeamMember); ok { + r0 = returnFunc(teamID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*team.TeamMember) + } + } + if returnFunc, ok := ret.Get(1).(func(string) error); ok { + r1 = returnFunc(teamID) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockTeamServiceInterface_GetOnlineMembers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetOnlineMembers' +type MockTeamServiceInterface_GetOnlineMembers_Call struct { + *mock.Call +} + +// GetOnlineMembers is a helper method to define mock.On call +// - teamID string +func (_e *MockTeamServiceInterface_Expecter) GetOnlineMembers(teamID interface{}) *MockTeamServiceInterface_GetOnlineMembers_Call { + return &MockTeamServiceInterface_GetOnlineMembers_Call{Call: _e.mock.On("GetOnlineMembers", teamID)} +} + +func (_c *MockTeamServiceInterface_GetOnlineMembers_Call) Run(run func(teamID string)) *MockTeamServiceInterface_GetOnlineMembers_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockTeamServiceInterface_GetOnlineMembers_Call) Return(teamMembers []*team.TeamMember, err error) *MockTeamServiceInterface_GetOnlineMembers_Call { + _c.Call.Return(teamMembers, err) + return _c +} + +func (_c *MockTeamServiceInterface_GetOnlineMembers_Call) RunAndReturn(run func(teamID string) ([]*team.TeamMember, error)) *MockTeamServiceInterface_GetOnlineMembers_Call { + _c.Call.Return(run) + return _c +} + +// GetSkillIndex provides a mock function for the type MockTeamServiceInterface +func (_mock *MockTeamServiceInterface) GetSkillIndex(teamID string) (*team.TeamSkillIndex, error) { + ret := _mock.Called(teamID) + + if len(ret) == 0 { + panic("no return value specified for GetSkillIndex") + } + + var r0 *team.TeamSkillIndex + var r1 error + if returnFunc, ok := ret.Get(0).(func(string) (*team.TeamSkillIndex, error)); ok { + return returnFunc(teamID) + } + if returnFunc, ok := ret.Get(0).(func(string) *team.TeamSkillIndex); ok { + r0 = returnFunc(teamID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*team.TeamSkillIndex) + } + } + if returnFunc, ok := ret.Get(1).(func(string) error); ok { + r1 = returnFunc(teamID) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockTeamServiceInterface_GetSkillIndex_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSkillIndex' +type MockTeamServiceInterface_GetSkillIndex_Call struct { + *mock.Call +} + +// GetSkillIndex is a helper method to define mock.On call +// - teamID string +func (_e *MockTeamServiceInterface_Expecter) GetSkillIndex(teamID interface{}) *MockTeamServiceInterface_GetSkillIndex_Call { + return &MockTeamServiceInterface_GetSkillIndex_Call{Call: _e.mock.On("GetSkillIndex", teamID)} +} + +func (_c *MockTeamServiceInterface_GetSkillIndex_Call) Run(run func(teamID string)) *MockTeamServiceInterface_GetSkillIndex_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockTeamServiceInterface_GetSkillIndex_Call) Return(teamSkillIndex *team.TeamSkillIndex, err error) *MockTeamServiceInterface_GetSkillIndex_Call { + _c.Call.Return(teamSkillIndex, err) + return _c +} + +func (_c *MockTeamServiceInterface_GetSkillIndex_Call) RunAndReturn(run func(teamID string) (*team.TeamSkillIndex, error)) *MockTeamServiceInterface_GetSkillIndex_Call { + _c.Call.Return(run) + return _c +} + +// GetTeam provides a mock function for the type MockTeamServiceInterface +func (_mock *MockTeamServiceInterface) GetTeam(teamID string) (*team.Team, error) { + ret := _mock.Called(teamID) + + if len(ret) == 0 { + panic("no return value specified for GetTeam") + } + + var r0 *team.Team + var r1 error + if returnFunc, ok := ret.Get(0).(func(string) (*team.Team, error)); ok { + return returnFunc(teamID) + } + if returnFunc, ok := ret.Get(0).(func(string) *team.Team); ok { + r0 = returnFunc(teamID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*team.Team) + } + } + if returnFunc, ok := ret.Get(1).(func(string) error); ok { + r1 = returnFunc(teamID) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockTeamServiceInterface_GetTeam_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTeam' +type MockTeamServiceInterface_GetTeam_Call struct { + *mock.Call +} + +// GetTeam is a helper method to define mock.On call +// - teamID string +func (_e *MockTeamServiceInterface_Expecter) GetTeam(teamID interface{}) *MockTeamServiceInterface_GetTeam_Call { + return &MockTeamServiceInterface_GetTeam_Call{Call: _e.mock.On("GetTeam", teamID)} +} + +func (_c *MockTeamServiceInterface_GetTeam_Call) Run(run func(teamID string)) *MockTeamServiceInterface_GetTeam_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockTeamServiceInterface_GetTeam_Call) Return(team1 *team.Team, err error) *MockTeamServiceInterface_GetTeam_Call { + _c.Call.Return(team1, err) + return _c +} + +func (_c *MockTeamServiceInterface_GetTeam_Call) RunAndReturn(run func(teamID string) (*team.Team, error)) *MockTeamServiceInterface_GetTeam_Call { + _c.Call.Return(run) + return _c +} + +// GetTeamList provides a mock function for the type MockTeamServiceInterface +func (_mock *MockTeamServiceInterface) GetTeamList() []*team.Team { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for GetTeamList") + } + + var r0 []*team.Team + if returnFunc, ok := ret.Get(0).(func() []*team.Team); ok { + r0 = returnFunc() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*team.Team) + } + } + return r0 +} + +// MockTeamServiceInterface_GetTeamList_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTeamList' +type MockTeamServiceInterface_GetTeamList_Call struct { + *mock.Call +} + +// GetTeamList is a helper method to define mock.On call +func (_e *MockTeamServiceInterface_Expecter) GetTeamList() *MockTeamServiceInterface_GetTeamList_Call { + return &MockTeamServiceInterface_GetTeamList_Call{Call: _e.mock.On("GetTeamList")} +} + +func (_c *MockTeamServiceInterface_GetTeamList_Call) Run(run func()) *MockTeamServiceInterface_GetTeamList_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockTeamServiceInterface_GetTeamList_Call) Return(teams []*team.Team) *MockTeamServiceInterface_GetTeamList_Call { + _c.Call.Return(teams) + return _c +} + +func (_c *MockTeamServiceInterface_GetTeamList_Call) RunAndReturn(run func() []*team.Team) *MockTeamServiceInterface_GetTeamList_Call { + _c.Call.Return(run) + return _c +} + +// GetTeamMembers provides a mock function for the type MockTeamServiceInterface +func (_mock *MockTeamServiceInterface) GetTeamMembers(teamID string) ([]*team.TeamMember, error) { + ret := _mock.Called(teamID) + + if len(ret) == 0 { + panic("no return value specified for GetTeamMembers") + } + + var r0 []*team.TeamMember + var r1 error + if returnFunc, ok := ret.Get(0).(func(string) ([]*team.TeamMember, error)); ok { + return returnFunc(teamID) + } + if returnFunc, ok := ret.Get(0).(func(string) []*team.TeamMember); ok { + r0 = returnFunc(teamID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*team.TeamMember) + } + } + if returnFunc, ok := ret.Get(1).(func(string) error); ok { + r1 = returnFunc(teamID) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockTeamServiceInterface_GetTeamMembers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTeamMembers' +type MockTeamServiceInterface_GetTeamMembers_Call struct { + *mock.Call +} + +// GetTeamMembers is a helper method to define mock.On call +// - teamID string +func (_e *MockTeamServiceInterface_Expecter) GetTeamMembers(teamID interface{}) *MockTeamServiceInterface_GetTeamMembers_Call { + return &MockTeamServiceInterface_GetTeamMembers_Call{Call: _e.mock.On("GetTeamMembers", teamID)} +} + +func (_c *MockTeamServiceInterface_GetTeamMembers_Call) Run(run func(teamID string)) *MockTeamServiceInterface_GetTeamMembers_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockTeamServiceInterface_GetTeamMembers_Call) Return(teamMembers []*team.TeamMember, err error) *MockTeamServiceInterface_GetTeamMembers_Call { + _c.Call.Return(teamMembers, err) + return _c +} + +func (_c *MockTeamServiceInterface_GetTeamMembers_Call) RunAndReturn(run func(teamID string) ([]*team.TeamMember, error)) *MockTeamServiceInterface_GetTeamMembers_Call { + _c.Call.Return(run) + return _c +} + +// UpdateLastSync provides a mock function for the type MockTeamServiceInterface +func (_mock *MockTeamServiceInterface) UpdateLastSync(teamID string) { + _mock.Called(teamID) + return +} + +// MockTeamServiceInterface_UpdateLastSync_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateLastSync' +type MockTeamServiceInterface_UpdateLastSync_Call struct { + *mock.Call +} + +// UpdateLastSync is a helper method to define mock.On call +// - teamID string +func (_e *MockTeamServiceInterface_Expecter) UpdateLastSync(teamID interface{}) *MockTeamServiceInterface_UpdateLastSync_Call { + return &MockTeamServiceInterface_UpdateLastSync_Call{Call: _e.mock.On("UpdateLastSync", teamID)} +} + +func (_c *MockTeamServiceInterface_UpdateLastSync_Call) Run(run func(teamID string)) *MockTeamServiceInterface_UpdateLastSync_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockTeamServiceInterface_UpdateLastSync_Call) Return() *MockTeamServiceInterface_UpdateLastSync_Call { + _c.Call.Return() + return _c +} + +func (_c *MockTeamServiceInterface_UpdateLastSync_Call) RunAndReturn(run func(teamID string)) *MockTeamServiceInterface_UpdateLastSync_Call { + _c.Run(run) + return _c +} + +// UpdateLeaderOnline provides a mock function for the type MockTeamServiceInterface +func (_mock *MockTeamServiceInterface) UpdateLeaderOnline(teamID string, online bool) { + _mock.Called(teamID, online) + return +} + +// MockTeamServiceInterface_UpdateLeaderOnline_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateLeaderOnline' +type MockTeamServiceInterface_UpdateLeaderOnline_Call struct { + *mock.Call +} + +// UpdateLeaderOnline is a helper method to define mock.On call +// - teamID string +// - online bool +func (_e *MockTeamServiceInterface_Expecter) UpdateLeaderOnline(teamID interface{}, online interface{}) *MockTeamServiceInterface_UpdateLeaderOnline_Call { + return &MockTeamServiceInterface_UpdateLeaderOnline_Call{Call: _e.mock.On("UpdateLeaderOnline", teamID, online)} +} + +func (_c *MockTeamServiceInterface_UpdateLeaderOnline_Call) Run(run func(teamID string, online bool)) *MockTeamServiceInterface_UpdateLeaderOnline_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 bool + if args[1] != nil { + arg1 = args[1].(bool) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockTeamServiceInterface_UpdateLeaderOnline_Call) Return() *MockTeamServiceInterface_UpdateLeaderOnline_Call { + _c.Call.Return() + return _c +} + +func (_c *MockTeamServiceInterface_UpdateLeaderOnline_Call) RunAndReturn(run func(teamID string, online bool)) *MockTeamServiceInterface_UpdateLeaderOnline_Call { + _c.Run(run) + return _c +} diff --git a/backend/internal/application/team/mocks/mock_weekly_stats_store_interface.go b/backend/internal/application/team/mocks/mock_weekly_stats_store_interface.go new file mode 100644 index 0000000..fc9abdc --- /dev/null +++ b/backend/internal/application/team/mocks/mock_weekly_stats_store_interface.go @@ -0,0 +1,461 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "time" + + "github.com/cocursor/backend/internal/domain/team" + mock "github.com/stretchr/testify/mock" +) + +// NewMockWeeklyStatsStoreInterface creates a new instance of MockWeeklyStatsStoreInterface. 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 NewMockWeeklyStatsStoreInterface(t interface { + mock.TestingT + Cleanup(func()) +}) *MockWeeklyStatsStoreInterface { + mock := &MockWeeklyStatsStoreInterface{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// MockWeeklyStatsStoreInterface is an autogenerated mock type for the WeeklyStatsStoreInterface type +type MockWeeklyStatsStoreInterface struct { + mock.Mock +} + +type MockWeeklyStatsStoreInterface_Expecter struct { + mock *mock.Mock +} + +func (_m *MockWeeklyStatsStoreInterface) EXPECT() *MockWeeklyStatsStoreInterface_Expecter { + return &MockWeeklyStatsStoreInterface_Expecter{mock: &_m.Mock} +} + +// Clear provides a mock function for the type MockWeeklyStatsStoreInterface +func (_mock *MockWeeklyStatsStoreInterface) Clear() error { + ret := _mock.Called() + + if len(ret) == 0 { + panic("no return value specified for Clear") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func() error); ok { + r0 = returnFunc() + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockWeeklyStatsStoreInterface_Clear_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Clear' +type MockWeeklyStatsStoreInterface_Clear_Call struct { + *mock.Call +} + +// Clear is a helper method to define mock.On call +func (_e *MockWeeklyStatsStoreInterface_Expecter) Clear() *MockWeeklyStatsStoreInterface_Clear_Call { + return &MockWeeklyStatsStoreInterface_Clear_Call{Call: _e.mock.On("Clear")} +} + +func (_c *MockWeeklyStatsStoreInterface_Clear_Call) Run(run func()) *MockWeeklyStatsStoreInterface_Clear_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_Clear_Call) Return(err error) *MockWeeklyStatsStoreInterface_Clear_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_Clear_Call) RunAndReturn(run func() error) *MockWeeklyStatsStoreInterface_Clear_Call { + _c.Call.Return(run) + return _c +} + +// Delete provides a mock function for the type MockWeeklyStatsStoreInterface +func (_mock *MockWeeklyStatsStoreInterface) Delete(memberID string, weekStart string) error { + ret := _mock.Called(memberID, weekStart) + + if len(ret) == 0 { + panic("no return value specified for Delete") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string, string) error); ok { + r0 = returnFunc(memberID, weekStart) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockWeeklyStatsStoreInterface_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' +type MockWeeklyStatsStoreInterface_Delete_Call struct { + *mock.Call +} + +// Delete is a helper method to define mock.On call +// - memberID string +// - weekStart string +func (_e *MockWeeklyStatsStoreInterface_Expecter) Delete(memberID interface{}, weekStart interface{}) *MockWeeklyStatsStoreInterface_Delete_Call { + return &MockWeeklyStatsStoreInterface_Delete_Call{Call: _e.mock.On("Delete", memberID, weekStart)} +} + +func (_c *MockWeeklyStatsStoreInterface_Delete_Call) Run(run func(memberID string, weekStart string)) *MockWeeklyStatsStoreInterface_Delete_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_Delete_Call) Return(err error) *MockWeeklyStatsStoreInterface_Delete_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_Delete_Call) RunAndReturn(run func(memberID string, weekStart string) error) *MockWeeklyStatsStoreInterface_Delete_Call { + _c.Call.Return(run) + return _c +} + +// Get provides a mock function for the type MockWeeklyStatsStoreInterface +func (_mock *MockWeeklyStatsStoreInterface) Get(memberID string, weekStart string) (*team.MemberWeeklyStats, error) { + ret := _mock.Called(memberID, weekStart) + + if len(ret) == 0 { + panic("no return value specified for Get") + } + + var r0 *team.MemberWeeklyStats + var r1 error + if returnFunc, ok := ret.Get(0).(func(string, string) (*team.MemberWeeklyStats, error)); ok { + return returnFunc(memberID, weekStart) + } + if returnFunc, ok := ret.Get(0).(func(string, string) *team.MemberWeeklyStats); ok { + r0 = returnFunc(memberID, weekStart) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*team.MemberWeeklyStats) + } + } + if returnFunc, ok := ret.Get(1).(func(string, string) error); ok { + r1 = returnFunc(memberID, weekStart) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockWeeklyStatsStoreInterface_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' +type MockWeeklyStatsStoreInterface_Get_Call struct { + *mock.Call +} + +// Get is a helper method to define mock.On call +// - memberID string +// - weekStart string +func (_e *MockWeeklyStatsStoreInterface_Expecter) Get(memberID interface{}, weekStart interface{}) *MockWeeklyStatsStoreInterface_Get_Call { + return &MockWeeklyStatsStoreInterface_Get_Call{Call: _e.mock.On("Get", memberID, weekStart)} +} + +func (_c *MockWeeklyStatsStoreInterface_Get_Call) Run(run func(memberID string, weekStart string)) *MockWeeklyStatsStoreInterface_Get_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_Get_Call) Return(memberWeeklyStats *team.MemberWeeklyStats, err error) *MockWeeklyStatsStoreInterface_Get_Call { + _c.Call.Return(memberWeeklyStats, err) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_Get_Call) RunAndReturn(run func(memberID string, weekStart string) (*team.MemberWeeklyStats, error)) *MockWeeklyStatsStoreInterface_Get_Call { + _c.Call.Return(run) + return _c +} + +// GetAll provides a mock function for the type MockWeeklyStatsStoreInterface +func (_mock *MockWeeklyStatsStoreInterface) GetAll(weekStart string) (map[string]*team.MemberWeeklyStats, error) { + ret := _mock.Called(weekStart) + + if len(ret) == 0 { + panic("no return value specified for GetAll") + } + + var r0 map[string]*team.MemberWeeklyStats + var r1 error + if returnFunc, ok := ret.Get(0).(func(string) (map[string]*team.MemberWeeklyStats, error)); ok { + return returnFunc(weekStart) + } + if returnFunc, ok := ret.Get(0).(func(string) map[string]*team.MemberWeeklyStats); ok { + r0 = returnFunc(weekStart) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]*team.MemberWeeklyStats) + } + } + if returnFunc, ok := ret.Get(1).(func(string) error); ok { + r1 = returnFunc(weekStart) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// MockWeeklyStatsStoreInterface_GetAll_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAll' +type MockWeeklyStatsStoreInterface_GetAll_Call struct { + *mock.Call +} + +// GetAll is a helper method to define mock.On call +// - weekStart string +func (_e *MockWeeklyStatsStoreInterface_Expecter) GetAll(weekStart interface{}) *MockWeeklyStatsStoreInterface_GetAll_Call { + return &MockWeeklyStatsStoreInterface_GetAll_Call{Call: _e.mock.On("GetAll", weekStart)} +} + +func (_c *MockWeeklyStatsStoreInterface_GetAll_Call) Run(run func(weekStart string)) *MockWeeklyStatsStoreInterface_GetAll_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_GetAll_Call) Return(stringToMemberWeeklyStats map[string]*team.MemberWeeklyStats, err error) *MockWeeklyStatsStoreInterface_GetAll_Call { + _c.Call.Return(stringToMemberWeeklyStats, err) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_GetAll_Call) RunAndReturn(run func(weekStart string) (map[string]*team.MemberWeeklyStats, error)) *MockWeeklyStatsStoreInterface_GetAll_Call { + _c.Call.Return(run) + return _c +} + +// GetExpiredMembers provides a mock function for the type MockWeeklyStatsStoreInterface +func (_mock *MockWeeklyStatsStoreInterface) GetExpiredMembers(memberIDs []string, weekStart string) []string { + ret := _mock.Called(memberIDs, weekStart) + + if len(ret) == 0 { + panic("no return value specified for GetExpiredMembers") + } + + var r0 []string + if returnFunc, ok := ret.Get(0).(func([]string, string) []string); ok { + r0 = returnFunc(memberIDs, weekStart) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + return r0 +} + +// MockWeeklyStatsStoreInterface_GetExpiredMembers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExpiredMembers' +type MockWeeklyStatsStoreInterface_GetExpiredMembers_Call struct { + *mock.Call +} + +// GetExpiredMembers is a helper method to define mock.On call +// - memberIDs []string +// - weekStart string +func (_e *MockWeeklyStatsStoreInterface_Expecter) GetExpiredMembers(memberIDs interface{}, weekStart interface{}) *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call { + return &MockWeeklyStatsStoreInterface_GetExpiredMembers_Call{Call: _e.mock.On("GetExpiredMembers", memberIDs, weekStart)} +} + +func (_c *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call) Run(run func(memberIDs []string, weekStart string)) *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 []string + if args[0] != nil { + arg0 = args[0].([]string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call) Return(strings []string) *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call { + _c.Call.Return(strings) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call) RunAndReturn(run func(memberIDs []string, weekStart string) []string) *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call { + _c.Call.Return(run) + return _c +} + +// Set provides a mock function for the type MockWeeklyStatsStoreInterface +func (_mock *MockWeeklyStatsStoreInterface) Set(memberID string, weekStart string, stats *team.MemberWeeklyStats) error { + ret := _mock.Called(memberID, weekStart, stats) + + if len(ret) == 0 { + panic("no return value specified for Set") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string, string, *team.MemberWeeklyStats) error); ok { + r0 = returnFunc(memberID, weekStart, stats) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockWeeklyStatsStoreInterface_Set_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Set' +type MockWeeklyStatsStoreInterface_Set_Call struct { + *mock.Call +} + +// Set is a helper method to define mock.On call +// - memberID string +// - weekStart string +// - stats *team.MemberWeeklyStats +func (_e *MockWeeklyStatsStoreInterface_Expecter) Set(memberID interface{}, weekStart interface{}, stats interface{}) *MockWeeklyStatsStoreInterface_Set_Call { + return &MockWeeklyStatsStoreInterface_Set_Call{Call: _e.mock.On("Set", memberID, weekStart, stats)} +} + +func (_c *MockWeeklyStatsStoreInterface_Set_Call) Run(run func(memberID string, weekStart string, stats *team.MemberWeeklyStats)) *MockWeeklyStatsStoreInterface_Set_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 *team.MemberWeeklyStats + if args[2] != nil { + arg2 = args[2].(*team.MemberWeeklyStats) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_Set_Call) Return(err error) *MockWeeklyStatsStoreInterface_Set_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_Set_Call) RunAndReturn(run func(memberID string, weekStart string, stats *team.MemberWeeklyStats) error) *MockWeeklyStatsStoreInterface_Set_Call { + _c.Call.Return(run) + return _c +} + +// SetWithExpiration provides a mock function for the type MockWeeklyStatsStoreInterface +func (_mock *MockWeeklyStatsStoreInterface) SetWithExpiration(memberID string, weekStart string, stats *team.MemberWeeklyStats, expiration time.Duration) error { + ret := _mock.Called(memberID, weekStart, stats, expiration) + + if len(ret) == 0 { + panic("no return value specified for SetWithExpiration") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(string, string, *team.MemberWeeklyStats, time.Duration) error); ok { + r0 = returnFunc(memberID, weekStart, stats, expiration) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// MockWeeklyStatsStoreInterface_SetWithExpiration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetWithExpiration' +type MockWeeklyStatsStoreInterface_SetWithExpiration_Call struct { + *mock.Call +} + +// SetWithExpiration is a helper method to define mock.On call +// - memberID string +// - weekStart string +// - stats *team.MemberWeeklyStats +// - expiration time.Duration +func (_e *MockWeeklyStatsStoreInterface_Expecter) SetWithExpiration(memberID interface{}, weekStart interface{}, stats interface{}, expiration interface{}) *MockWeeklyStatsStoreInterface_SetWithExpiration_Call { + return &MockWeeklyStatsStoreInterface_SetWithExpiration_Call{Call: _e.mock.On("SetWithExpiration", memberID, weekStart, stats, expiration)} +} + +func (_c *MockWeeklyStatsStoreInterface_SetWithExpiration_Call) Run(run func(memberID string, weekStart string, stats *team.MemberWeeklyStats, expiration time.Duration)) *MockWeeklyStatsStoreInterface_SetWithExpiration_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 string + if args[0] != nil { + arg0 = args[0].(string) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 *team.MemberWeeklyStats + if args[2] != nil { + arg2 = args[2].(*team.MemberWeeklyStats) + } + var arg3 time.Duration + if args[3] != nil { + arg3 = args[3].(time.Duration) + } + run( + arg0, + arg1, + arg2, + arg3, + ) + }) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_SetWithExpiration_Call) Return(err error) *MockWeeklyStatsStoreInterface_SetWithExpiration_Call { + _c.Call.Return(err) + return _c +} + +func (_c *MockWeeklyStatsStoreInterface_SetWithExpiration_Call) RunAndReturn(run func(memberID string, weekStart string, stats *team.MemberWeeklyStats, expiration time.Duration) error) *MockWeeklyStatsStoreInterface_SetWithExpiration_Call { + _c.Call.Return(run) + return _c +} diff --git a/backend/internal/application/team/mocks/mocks.go b/backend/internal/application/team/mocks/mocks.go deleted file mode 100644 index 2b049f7..0000000 --- a/backend/internal/application/team/mocks/mocks.go +++ /dev/null @@ -1,1096 +0,0 @@ -// Code generated by mockery; DO NOT EDIT. -// github.com/vektra/mockery -// template: testify - -package mocks - -import ( - "net/http" - "time" - - "github.com/cocursor/backend/internal/domain/team" - mock "github.com/stretchr/testify/mock" -) - -// NewMockTeamServiceInterface creates a new instance of MockTeamServiceInterface. 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 NewMockTeamServiceInterface(t interface { - mock.TestingT - Cleanup(func()) -}) *MockTeamServiceInterface { - mock := &MockTeamServiceInterface{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} - -// MockTeamServiceInterface is an autogenerated mock type for the TeamServiceInterface type -type MockTeamServiceInterface struct { - mock.Mock -} - -type MockTeamServiceInterface_Expecter struct { - mock *mock.Mock -} - -func (_m *MockTeamServiceInterface) EXPECT() *MockTeamServiceInterface_Expecter { - return &MockTeamServiceInterface_Expecter{mock: &_m.Mock} -} - -// GetOnlineMembers provides a mock function for the type MockTeamServiceInterface -func (_mock *MockTeamServiceInterface) GetOnlineMembers(teamID string) ([]*team.TeamMember, error) { - ret := _mock.Called(teamID) - - if len(ret) == 0 { - panic("no return value specified for GetOnlineMembers") - } - - var r0 []*team.TeamMember - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) ([]*team.TeamMember, error)); ok { - return returnFunc(teamID) - } - if returnFunc, ok := ret.Get(0).(func(string) []*team.TeamMember); ok { - r0 = returnFunc(teamID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*team.TeamMember) - } - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(teamID) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockTeamServiceInterface_GetOnlineMembers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetOnlineMembers' -type MockTeamServiceInterface_GetOnlineMembers_Call struct { - *mock.Call -} - -// GetOnlineMembers is a helper method to define mock.On call -// - teamID string -func (_e *MockTeamServiceInterface_Expecter) GetOnlineMembers(teamID interface{}) *MockTeamServiceInterface_GetOnlineMembers_Call { - return &MockTeamServiceInterface_GetOnlineMembers_Call{Call: _e.mock.On("GetOnlineMembers", teamID)} -} - -func (_c *MockTeamServiceInterface_GetOnlineMembers_Call) Run(run func(teamID string)) *MockTeamServiceInterface_GetOnlineMembers_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) - }) - return _c -} - -func (_c *MockTeamServiceInterface_GetOnlineMembers_Call) Return(teamMembers []*team.TeamMember, err error) *MockTeamServiceInterface_GetOnlineMembers_Call { - _c.Call.Return(teamMembers, err) - return _c -} - -func (_c *MockTeamServiceInterface_GetOnlineMembers_Call) RunAndReturn(run func(teamID string) ([]*team.TeamMember, error)) *MockTeamServiceInterface_GetOnlineMembers_Call { - _c.Call.Return(run) - return _c -} - -// GetTeam provides a mock function for the type MockTeamServiceInterface -func (_mock *MockTeamServiceInterface) GetTeam(teamID string) (*team.Team, error) { - ret := _mock.Called(teamID) - - if len(ret) == 0 { - panic("no return value specified for GetTeam") - } - - var r0 *team.Team - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) (*team.Team, error)); ok { - return returnFunc(teamID) - } - if returnFunc, ok := ret.Get(0).(func(string) *team.Team); ok { - r0 = returnFunc(teamID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*team.Team) - } - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(teamID) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockTeamServiceInterface_GetTeam_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTeam' -type MockTeamServiceInterface_GetTeam_Call struct { - *mock.Call -} - -// GetTeam is a helper method to define mock.On call -// - teamID string -func (_e *MockTeamServiceInterface_Expecter) GetTeam(teamID interface{}) *MockTeamServiceInterface_GetTeam_Call { - return &MockTeamServiceInterface_GetTeam_Call{Call: _e.mock.On("GetTeam", teamID)} -} - -func (_c *MockTeamServiceInterface_GetTeam_Call) Run(run func(teamID string)) *MockTeamServiceInterface_GetTeam_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) - }) - return _c -} - -func (_c *MockTeamServiceInterface_GetTeam_Call) Return(team1 *team.Team, err error) *MockTeamServiceInterface_GetTeam_Call { - _c.Call.Return(team1, err) - return _c -} - -func (_c *MockTeamServiceInterface_GetTeam_Call) RunAndReturn(run func(teamID string) (*team.Team, error)) *MockTeamServiceInterface_GetTeam_Call { - _c.Call.Return(run) - return _c -} - -// GetTeamMembers provides a mock function for the type MockTeamServiceInterface -func (_mock *MockTeamServiceInterface) GetTeamMembers(teamID string) ([]*team.TeamMember, error) { - ret := _mock.Called(teamID) - - if len(ret) == 0 { - panic("no return value specified for GetTeamMembers") - } - - var r0 []*team.TeamMember - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) ([]*team.TeamMember, error)); ok { - return returnFunc(teamID) - } - if returnFunc, ok := ret.Get(0).(func(string) []*team.TeamMember); ok { - r0 = returnFunc(teamID) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*team.TeamMember) - } - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(teamID) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockTeamServiceInterface_GetTeamMembers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTeamMembers' -type MockTeamServiceInterface_GetTeamMembers_Call struct { - *mock.Call -} - -// GetTeamMembers is a helper method to define mock.On call -// - teamID string -func (_e *MockTeamServiceInterface_Expecter) GetTeamMembers(teamID interface{}) *MockTeamServiceInterface_GetTeamMembers_Call { - return &MockTeamServiceInterface_GetTeamMembers_Call{Call: _e.mock.On("GetTeamMembers", teamID)} -} - -func (_c *MockTeamServiceInterface_GetTeamMembers_Call) Run(run func(teamID string)) *MockTeamServiceInterface_GetTeamMembers_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) - }) - return _c -} - -func (_c *MockTeamServiceInterface_GetTeamMembers_Call) Return(teamMembers []*team.TeamMember, err error) *MockTeamServiceInterface_GetTeamMembers_Call { - _c.Call.Return(teamMembers, err) - return _c -} - -func (_c *MockTeamServiceInterface_GetTeamMembers_Call) RunAndReturn(run func(teamID string) ([]*team.TeamMember, error)) *MockTeamServiceInterface_GetTeamMembers_Call { - _c.Call.Return(run) - return _c -} - -// NewMockProjectConfigStoreInterface creates a new instance of MockProjectConfigStoreInterface. 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 NewMockProjectConfigStoreInterface(t interface { - mock.TestingT - Cleanup(func()) -}) *MockProjectConfigStoreInterface { - mock := &MockProjectConfigStoreInterface{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} - -// MockProjectConfigStoreInterface is an autogenerated mock type for the ProjectConfigStoreInterface type -type MockProjectConfigStoreInterface struct { - mock.Mock -} - -type MockProjectConfigStoreInterface_Expecter struct { - mock *mock.Mock -} - -func (_m *MockProjectConfigStoreInterface) EXPECT() *MockProjectConfigStoreInterface_Expecter { - return &MockProjectConfigStoreInterface_Expecter{mock: &_m.Mock} -} - -// AddProject provides a mock function for the type MockProjectConfigStoreInterface -func (_mock *MockProjectConfigStoreInterface) AddProject(project team.ProjectMatcher) error { - ret := _mock.Called(project) - - if len(ret) == 0 { - panic("no return value specified for AddProject") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(team.ProjectMatcher) error); ok { - r0 = returnFunc(project) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockProjectConfigStoreInterface_AddProject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddProject' -type MockProjectConfigStoreInterface_AddProject_Call struct { - *mock.Call -} - -// AddProject is a helper method to define mock.On call -// - project team.ProjectMatcher -func (_e *MockProjectConfigStoreInterface_Expecter) AddProject(project interface{}) *MockProjectConfigStoreInterface_AddProject_Call { - return &MockProjectConfigStoreInterface_AddProject_Call{Call: _e.mock.On("AddProject", project)} -} - -func (_c *MockProjectConfigStoreInterface_AddProject_Call) Run(run func(project team.ProjectMatcher)) *MockProjectConfigStoreInterface_AddProject_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 team.ProjectMatcher - if args[0] != nil { - arg0 = args[0].(team.ProjectMatcher) - } - run( - arg0, - ) - }) - return _c -} - -func (_c *MockProjectConfigStoreInterface_AddProject_Call) Return(err error) *MockProjectConfigStoreInterface_AddProject_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockProjectConfigStoreInterface_AddProject_Call) RunAndReturn(run func(project team.ProjectMatcher) error) *MockProjectConfigStoreInterface_AddProject_Call { - _c.Call.Return(run) - return _c -} - -// GetRepoURLs provides a mock function for the type MockProjectConfigStoreInterface -func (_mock *MockProjectConfigStoreInterface) GetRepoURLs() []string { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for GetRepoURLs") - } - - var r0 []string - if returnFunc, ok := ret.Get(0).(func() []string); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - return r0 -} - -// MockProjectConfigStoreInterface_GetRepoURLs_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetRepoURLs' -type MockProjectConfigStoreInterface_GetRepoURLs_Call struct { - *mock.Call -} - -// GetRepoURLs is a helper method to define mock.On call -func (_e *MockProjectConfigStoreInterface_Expecter) GetRepoURLs() *MockProjectConfigStoreInterface_GetRepoURLs_Call { - return &MockProjectConfigStoreInterface_GetRepoURLs_Call{Call: _e.mock.On("GetRepoURLs")} -} - -func (_c *MockProjectConfigStoreInterface_GetRepoURLs_Call) Run(run func()) *MockProjectConfigStoreInterface_GetRepoURLs_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockProjectConfigStoreInterface_GetRepoURLs_Call) Return(strings []string) *MockProjectConfigStoreInterface_GetRepoURLs_Call { - _c.Call.Return(strings) - return _c -} - -func (_c *MockProjectConfigStoreInterface_GetRepoURLs_Call) RunAndReturn(run func() []string) *MockProjectConfigStoreInterface_GetRepoURLs_Call { - _c.Call.Return(run) - return _c -} - -// Load provides a mock function for the type MockProjectConfigStoreInterface -func (_mock *MockProjectConfigStoreInterface) Load() (*team.TeamProjectConfig, error) { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for Load") - } - - var r0 *team.TeamProjectConfig - var r1 error - if returnFunc, ok := ret.Get(0).(func() (*team.TeamProjectConfig, error)); ok { - return returnFunc() - } - if returnFunc, ok := ret.Get(0).(func() *team.TeamProjectConfig); ok { - r0 = returnFunc() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*team.TeamProjectConfig) - } - } - if returnFunc, ok := ret.Get(1).(func() error); ok { - r1 = returnFunc() - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockProjectConfigStoreInterface_Load_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Load' -type MockProjectConfigStoreInterface_Load_Call struct { - *mock.Call -} - -// Load is a helper method to define mock.On call -func (_e *MockProjectConfigStoreInterface_Expecter) Load() *MockProjectConfigStoreInterface_Load_Call { - return &MockProjectConfigStoreInterface_Load_Call{Call: _e.mock.On("Load")} -} - -func (_c *MockProjectConfigStoreInterface_Load_Call) Run(run func()) *MockProjectConfigStoreInterface_Load_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockProjectConfigStoreInterface_Load_Call) Return(teamProjectConfig *team.TeamProjectConfig, err error) *MockProjectConfigStoreInterface_Load_Call { - _c.Call.Return(teamProjectConfig, err) - return _c -} - -func (_c *MockProjectConfigStoreInterface_Load_Call) RunAndReturn(run func() (*team.TeamProjectConfig, error)) *MockProjectConfigStoreInterface_Load_Call { - _c.Call.Return(run) - return _c -} - -// RemoveProject provides a mock function for the type MockProjectConfigStoreInterface -func (_mock *MockProjectConfigStoreInterface) RemoveProject(projectID string) error { - ret := _mock.Called(projectID) - - if len(ret) == 0 { - panic("no return value specified for RemoveProject") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(string) error); ok { - r0 = returnFunc(projectID) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockProjectConfigStoreInterface_RemoveProject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveProject' -type MockProjectConfigStoreInterface_RemoveProject_Call struct { - *mock.Call -} - -// RemoveProject is a helper method to define mock.On call -// - projectID string -func (_e *MockProjectConfigStoreInterface_Expecter) RemoveProject(projectID interface{}) *MockProjectConfigStoreInterface_RemoveProject_Call { - return &MockProjectConfigStoreInterface_RemoveProject_Call{Call: _e.mock.On("RemoveProject", projectID)} -} - -func (_c *MockProjectConfigStoreInterface_RemoveProject_Call) Run(run func(projectID string)) *MockProjectConfigStoreInterface_RemoveProject_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) - }) - return _c -} - -func (_c *MockProjectConfigStoreInterface_RemoveProject_Call) Return(err error) *MockProjectConfigStoreInterface_RemoveProject_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockProjectConfigStoreInterface_RemoveProject_Call) RunAndReturn(run func(projectID string) error) *MockProjectConfigStoreInterface_RemoveProject_Call { - _c.Call.Return(run) - return _c -} - -// Save provides a mock function for the type MockProjectConfigStoreInterface -func (_mock *MockProjectConfigStoreInterface) Save(config *team.TeamProjectConfig) error { - ret := _mock.Called(config) - - if len(ret) == 0 { - panic("no return value specified for Save") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(*team.TeamProjectConfig) error); ok { - r0 = returnFunc(config) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockProjectConfigStoreInterface_Save_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Save' -type MockProjectConfigStoreInterface_Save_Call struct { - *mock.Call -} - -// Save is a helper method to define mock.On call -// - config *team.TeamProjectConfig -func (_e *MockProjectConfigStoreInterface_Expecter) Save(config interface{}) *MockProjectConfigStoreInterface_Save_Call { - return &MockProjectConfigStoreInterface_Save_Call{Call: _e.mock.On("Save", config)} -} - -func (_c *MockProjectConfigStoreInterface_Save_Call) Run(run func(config *team.TeamProjectConfig)) *MockProjectConfigStoreInterface_Save_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 *team.TeamProjectConfig - if args[0] != nil { - arg0 = args[0].(*team.TeamProjectConfig) - } - run( - arg0, - ) - }) - return _c -} - -func (_c *MockProjectConfigStoreInterface_Save_Call) Return(err error) *MockProjectConfigStoreInterface_Save_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockProjectConfigStoreInterface_Save_Call) RunAndReturn(run func(config *team.TeamProjectConfig) error) *MockProjectConfigStoreInterface_Save_Call { - _c.Call.Return(run) - return _c -} - -// UpdateProject provides a mock function for the type MockProjectConfigStoreInterface -func (_mock *MockProjectConfigStoreInterface) UpdateProject(project team.ProjectMatcher) error { - ret := _mock.Called(project) - - if len(ret) == 0 { - panic("no return value specified for UpdateProject") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(team.ProjectMatcher) error); ok { - r0 = returnFunc(project) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockProjectConfigStoreInterface_UpdateProject_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateProject' -type MockProjectConfigStoreInterface_UpdateProject_Call struct { - *mock.Call -} - -// UpdateProject is a helper method to define mock.On call -// - project team.ProjectMatcher -func (_e *MockProjectConfigStoreInterface_Expecter) UpdateProject(project interface{}) *MockProjectConfigStoreInterface_UpdateProject_Call { - return &MockProjectConfigStoreInterface_UpdateProject_Call{Call: _e.mock.On("UpdateProject", project)} -} - -func (_c *MockProjectConfigStoreInterface_UpdateProject_Call) Run(run func(project team.ProjectMatcher)) *MockProjectConfigStoreInterface_UpdateProject_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 team.ProjectMatcher - if args[0] != nil { - arg0 = args[0].(team.ProjectMatcher) - } - run( - arg0, - ) - }) - return _c -} - -func (_c *MockProjectConfigStoreInterface_UpdateProject_Call) Return(err error) *MockProjectConfigStoreInterface_UpdateProject_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockProjectConfigStoreInterface_UpdateProject_Call) RunAndReturn(run func(project team.ProjectMatcher) error) *MockProjectConfigStoreInterface_UpdateProject_Call { - _c.Call.Return(run) - return _c -} - -// NewMockWeeklyStatsStoreInterface creates a new instance of MockWeeklyStatsStoreInterface. 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 NewMockWeeklyStatsStoreInterface(t interface { - mock.TestingT - Cleanup(func()) -}) *MockWeeklyStatsStoreInterface { - mock := &MockWeeklyStatsStoreInterface{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} - -// MockWeeklyStatsStoreInterface is an autogenerated mock type for the WeeklyStatsStoreInterface type -type MockWeeklyStatsStoreInterface struct { - mock.Mock -} - -type MockWeeklyStatsStoreInterface_Expecter struct { - mock *mock.Mock -} - -func (_m *MockWeeklyStatsStoreInterface) EXPECT() *MockWeeklyStatsStoreInterface_Expecter { - return &MockWeeklyStatsStoreInterface_Expecter{mock: &_m.Mock} -} - -// Clear provides a mock function for the type MockWeeklyStatsStoreInterface -func (_mock *MockWeeklyStatsStoreInterface) Clear() error { - ret := _mock.Called() - - if len(ret) == 0 { - panic("no return value specified for Clear") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func() error); ok { - r0 = returnFunc() - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockWeeklyStatsStoreInterface_Clear_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Clear' -type MockWeeklyStatsStoreInterface_Clear_Call struct { - *mock.Call -} - -// Clear is a helper method to define mock.On call -func (_e *MockWeeklyStatsStoreInterface_Expecter) Clear() *MockWeeklyStatsStoreInterface_Clear_Call { - return &MockWeeklyStatsStoreInterface_Clear_Call{Call: _e.mock.On("Clear")} -} - -func (_c *MockWeeklyStatsStoreInterface_Clear_Call) Run(run func()) *MockWeeklyStatsStoreInterface_Clear_Call { - _c.Call.Run(func(args mock.Arguments) { - run() - }) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_Clear_Call) Return(err error) *MockWeeklyStatsStoreInterface_Clear_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_Clear_Call) RunAndReturn(run func() error) *MockWeeklyStatsStoreInterface_Clear_Call { - _c.Call.Return(run) - return _c -} - -// Delete provides a mock function for the type MockWeeklyStatsStoreInterface -func (_mock *MockWeeklyStatsStoreInterface) Delete(memberID string, weekStart string) error { - ret := _mock.Called(memberID, weekStart) - - if len(ret) == 0 { - panic("no return value specified for Delete") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(string, string) error); ok { - r0 = returnFunc(memberID, weekStart) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockWeeklyStatsStoreInterface_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' -type MockWeeklyStatsStoreInterface_Delete_Call struct { - *mock.Call -} - -// Delete is a helper method to define mock.On call -// - memberID string -// - weekStart string -func (_e *MockWeeklyStatsStoreInterface_Expecter) Delete(memberID interface{}, weekStart interface{}) *MockWeeklyStatsStoreInterface_Delete_Call { - return &MockWeeklyStatsStoreInterface_Delete_Call{Call: _e.mock.On("Delete", memberID, weekStart)} -} - -func (_c *MockWeeklyStatsStoreInterface_Delete_Call) Run(run func(memberID string, weekStart string)) *MockWeeklyStatsStoreInterface_Delete_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_Delete_Call) Return(err error) *MockWeeklyStatsStoreInterface_Delete_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_Delete_Call) RunAndReturn(run func(memberID string, weekStart string) error) *MockWeeklyStatsStoreInterface_Delete_Call { - _c.Call.Return(run) - return _c -} - -// Get provides a mock function for the type MockWeeklyStatsStoreInterface -func (_mock *MockWeeklyStatsStoreInterface) Get(memberID string, weekStart string) (*team.MemberWeeklyStats, error) { - ret := _mock.Called(memberID, weekStart) - - if len(ret) == 0 { - panic("no return value specified for Get") - } - - var r0 *team.MemberWeeklyStats - var r1 error - if returnFunc, ok := ret.Get(0).(func(string, string) (*team.MemberWeeklyStats, error)); ok { - return returnFunc(memberID, weekStart) - } - if returnFunc, ok := ret.Get(0).(func(string, string) *team.MemberWeeklyStats); ok { - r0 = returnFunc(memberID, weekStart) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*team.MemberWeeklyStats) - } - } - if returnFunc, ok := ret.Get(1).(func(string, string) error); ok { - r1 = returnFunc(memberID, weekStart) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockWeeklyStatsStoreInterface_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' -type MockWeeklyStatsStoreInterface_Get_Call struct { - *mock.Call -} - -// Get is a helper method to define mock.On call -// - memberID string -// - weekStart string -func (_e *MockWeeklyStatsStoreInterface_Expecter) Get(memberID interface{}, weekStart interface{}) *MockWeeklyStatsStoreInterface_Get_Call { - return &MockWeeklyStatsStoreInterface_Get_Call{Call: _e.mock.On("Get", memberID, weekStart)} -} - -func (_c *MockWeeklyStatsStoreInterface_Get_Call) Run(run func(memberID string, weekStart string)) *MockWeeklyStatsStoreInterface_Get_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_Get_Call) Return(memberWeeklyStats *team.MemberWeeklyStats, err error) *MockWeeklyStatsStoreInterface_Get_Call { - _c.Call.Return(memberWeeklyStats, err) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_Get_Call) RunAndReturn(run func(memberID string, weekStart string) (*team.MemberWeeklyStats, error)) *MockWeeklyStatsStoreInterface_Get_Call { - _c.Call.Return(run) - return _c -} - -// GetAll provides a mock function for the type MockWeeklyStatsStoreInterface -func (_mock *MockWeeklyStatsStoreInterface) GetAll(weekStart string) (map[string]*team.MemberWeeklyStats, error) { - ret := _mock.Called(weekStart) - - if len(ret) == 0 { - panic("no return value specified for GetAll") - } - - var r0 map[string]*team.MemberWeeklyStats - var r1 error - if returnFunc, ok := ret.Get(0).(func(string) (map[string]*team.MemberWeeklyStats, error)); ok { - return returnFunc(weekStart) - } - if returnFunc, ok := ret.Get(0).(func(string) map[string]*team.MemberWeeklyStats); ok { - r0 = returnFunc(weekStart) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(map[string]*team.MemberWeeklyStats) - } - } - if returnFunc, ok := ret.Get(1).(func(string) error); ok { - r1 = returnFunc(weekStart) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockWeeklyStatsStoreInterface_GetAll_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAll' -type MockWeeklyStatsStoreInterface_GetAll_Call struct { - *mock.Call -} - -// GetAll is a helper method to define mock.On call -// - weekStart string -func (_e *MockWeeklyStatsStoreInterface_Expecter) GetAll(weekStart interface{}) *MockWeeklyStatsStoreInterface_GetAll_Call { - return &MockWeeklyStatsStoreInterface_GetAll_Call{Call: _e.mock.On("GetAll", weekStart)} -} - -func (_c *MockWeeklyStatsStoreInterface_GetAll_Call) Run(run func(weekStart string)) *MockWeeklyStatsStoreInterface_GetAll_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - run( - arg0, - ) - }) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_GetAll_Call) Return(stringToMemberWeeklyStats map[string]*team.MemberWeeklyStats, err error) *MockWeeklyStatsStoreInterface_GetAll_Call { - _c.Call.Return(stringToMemberWeeklyStats, err) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_GetAll_Call) RunAndReturn(run func(weekStart string) (map[string]*team.MemberWeeklyStats, error)) *MockWeeklyStatsStoreInterface_GetAll_Call { - _c.Call.Return(run) - return _c -} - -// GetExpiredMembers provides a mock function for the type MockWeeklyStatsStoreInterface -func (_mock *MockWeeklyStatsStoreInterface) GetExpiredMembers(memberIDs []string, weekStart string) []string { - ret := _mock.Called(memberIDs, weekStart) - - if len(ret) == 0 { - panic("no return value specified for GetExpiredMembers") - } - - var r0 []string - if returnFunc, ok := ret.Get(0).(func([]string, string) []string); ok { - r0 = returnFunc(memberIDs, weekStart) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - return r0 -} - -// MockWeeklyStatsStoreInterface_GetExpiredMembers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetExpiredMembers' -type MockWeeklyStatsStoreInterface_GetExpiredMembers_Call struct { - *mock.Call -} - -// GetExpiredMembers is a helper method to define mock.On call -// - memberIDs []string -// - weekStart string -func (_e *MockWeeklyStatsStoreInterface_Expecter) GetExpiredMembers(memberIDs interface{}, weekStart interface{}) *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call { - return &MockWeeklyStatsStoreInterface_GetExpiredMembers_Call{Call: _e.mock.On("GetExpiredMembers", memberIDs, weekStart)} -} - -func (_c *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call) Run(run func(memberIDs []string, weekStart string)) *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 []string - if args[0] != nil { - arg0 = args[0].([]string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - run( - arg0, - arg1, - ) - }) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call) Return(strings []string) *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call { - _c.Call.Return(strings) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call) RunAndReturn(run func(memberIDs []string, weekStart string) []string) *MockWeeklyStatsStoreInterface_GetExpiredMembers_Call { - _c.Call.Return(run) - return _c -} - -// Set provides a mock function for the type MockWeeklyStatsStoreInterface -func (_mock *MockWeeklyStatsStoreInterface) Set(memberID string, weekStart string, stats *team.MemberWeeklyStats) error { - ret := _mock.Called(memberID, weekStart, stats) - - if len(ret) == 0 { - panic("no return value specified for Set") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(string, string, *team.MemberWeeklyStats) error); ok { - r0 = returnFunc(memberID, weekStart, stats) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockWeeklyStatsStoreInterface_Set_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Set' -type MockWeeklyStatsStoreInterface_Set_Call struct { - *mock.Call -} - -// Set is a helper method to define mock.On call -// - memberID string -// - weekStart string -// - stats *team.MemberWeeklyStats -func (_e *MockWeeklyStatsStoreInterface_Expecter) Set(memberID interface{}, weekStart interface{}, stats interface{}) *MockWeeklyStatsStoreInterface_Set_Call { - return &MockWeeklyStatsStoreInterface_Set_Call{Call: _e.mock.On("Set", memberID, weekStart, stats)} -} - -func (_c *MockWeeklyStatsStoreInterface_Set_Call) Run(run func(memberID string, weekStart string, stats *team.MemberWeeklyStats)) *MockWeeklyStatsStoreInterface_Set_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 *team.MemberWeeklyStats - if args[2] != nil { - arg2 = args[2].(*team.MemberWeeklyStats) - } - run( - arg0, - arg1, - arg2, - ) - }) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_Set_Call) Return(err error) *MockWeeklyStatsStoreInterface_Set_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_Set_Call) RunAndReturn(run func(memberID string, weekStart string, stats *team.MemberWeeklyStats) error) *MockWeeklyStatsStoreInterface_Set_Call { - _c.Call.Return(run) - return _c -} - -// SetWithExpiration provides a mock function for the type MockWeeklyStatsStoreInterface -func (_mock *MockWeeklyStatsStoreInterface) SetWithExpiration(memberID string, weekStart string, stats *team.MemberWeeklyStats, expiration time.Duration) error { - ret := _mock.Called(memberID, weekStart, stats, expiration) - - if len(ret) == 0 { - panic("no return value specified for SetWithExpiration") - } - - var r0 error - if returnFunc, ok := ret.Get(0).(func(string, string, *team.MemberWeeklyStats, time.Duration) error); ok { - r0 = returnFunc(memberID, weekStart, stats, expiration) - } else { - r0 = ret.Error(0) - } - return r0 -} - -// MockWeeklyStatsStoreInterface_SetWithExpiration_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetWithExpiration' -type MockWeeklyStatsStoreInterface_SetWithExpiration_Call struct { - *mock.Call -} - -// SetWithExpiration is a helper method to define mock.On call -// - memberID string -// - weekStart string -// - stats *team.MemberWeeklyStats -// - expiration time.Duration -func (_e *MockWeeklyStatsStoreInterface_Expecter) SetWithExpiration(memberID interface{}, weekStart interface{}, stats interface{}, expiration interface{}) *MockWeeklyStatsStoreInterface_SetWithExpiration_Call { - return &MockWeeklyStatsStoreInterface_SetWithExpiration_Call{Call: _e.mock.On("SetWithExpiration", memberID, weekStart, stats, expiration)} -} - -func (_c *MockWeeklyStatsStoreInterface_SetWithExpiration_Call) Run(run func(memberID string, weekStart string, stats *team.MemberWeeklyStats, expiration time.Duration)) *MockWeeklyStatsStoreInterface_SetWithExpiration_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 string - if args[0] != nil { - arg0 = args[0].(string) - } - var arg1 string - if args[1] != nil { - arg1 = args[1].(string) - } - var arg2 *team.MemberWeeklyStats - if args[2] != nil { - arg2 = args[2].(*team.MemberWeeklyStats) - } - var arg3 time.Duration - if args[3] != nil { - arg3 = args[3].(time.Duration) - } - run( - arg0, - arg1, - arg2, - arg3, - ) - }) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_SetWithExpiration_Call) Return(err error) *MockWeeklyStatsStoreInterface_SetWithExpiration_Call { - _c.Call.Return(err) - return _c -} - -func (_c *MockWeeklyStatsStoreInterface_SetWithExpiration_Call) RunAndReturn(run func(memberID string, weekStart string, stats *team.MemberWeeklyStats, expiration time.Duration) error) *MockWeeklyStatsStoreInterface_SetWithExpiration_Call { - _c.Call.Return(run) - return _c -} - -// NewMockHTTPClientInterface creates a new instance of MockHTTPClientInterface. 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 NewMockHTTPClientInterface(t interface { - mock.TestingT - Cleanup(func()) -}) *MockHTTPClientInterface { - mock := &MockHTTPClientInterface{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} - -// MockHTTPClientInterface is an autogenerated mock type for the HTTPClientInterface type -type MockHTTPClientInterface struct { - mock.Mock -} - -type MockHTTPClientInterface_Expecter struct { - mock *mock.Mock -} - -func (_m *MockHTTPClientInterface) EXPECT() *MockHTTPClientInterface_Expecter { - return &MockHTTPClientInterface_Expecter{mock: &_m.Mock} -} - -// Do provides a mock function for the type MockHTTPClientInterface -func (_mock *MockHTTPClientInterface) Do(req *http.Request) (*http.Response, error) { - ret := _mock.Called(req) - - if len(ret) == 0 { - panic("no return value specified for Do") - } - - var r0 *http.Response - var r1 error - if returnFunc, ok := ret.Get(0).(func(*http.Request) (*http.Response, error)); ok { - return returnFunc(req) - } - if returnFunc, ok := ret.Get(0).(func(*http.Request) *http.Response); ok { - r0 = returnFunc(req) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*http.Response) - } - } - if returnFunc, ok := ret.Get(1).(func(*http.Request) error); ok { - r1 = returnFunc(req) - } else { - r1 = ret.Error(1) - } - return r0, r1 -} - -// MockHTTPClientInterface_Do_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Do' -type MockHTTPClientInterface_Do_Call struct { - *mock.Call -} - -// Do is a helper method to define mock.On call -// - req *http.Request -func (_e *MockHTTPClientInterface_Expecter) Do(req interface{}) *MockHTTPClientInterface_Do_Call { - return &MockHTTPClientInterface_Do_Call{Call: _e.mock.On("Do", req)} -} - -func (_c *MockHTTPClientInterface_Do_Call) Run(run func(req *http.Request)) *MockHTTPClientInterface_Do_Call { - _c.Call.Run(func(args mock.Arguments) { - var arg0 *http.Request - if args[0] != nil { - arg0 = args[0].(*http.Request) - } - run( - arg0, - ) - }) - return _c -} - -func (_c *MockHTTPClientInterface_Do_Call) Return(response *http.Response, err error) *MockHTTPClientInterface_Do_Call { - _c.Call.Return(response, err) - return _c -} - -func (_c *MockHTTPClientInterface_Do_Call) RunAndReturn(run func(req *http.Request) (*http.Response, error)) *MockHTTPClientInterface_Do_Call { - _c.Call.Return(run) - return _c -} diff --git a/backend/internal/application/team/session_sharing_service.go b/backend/internal/application/team/session_sharing_service.go index 4069ec0..6d6dc7f 100644 --- a/backend/internal/application/team/session_sharing_service.go +++ b/backend/internal/application/team/session_sharing_service.go @@ -150,11 +150,15 @@ func (s *SessionSharingService) forwardShareToLeader(ctx context.Context, team * Title string `json:"title"` Messages json.RawMessage `json:"messages"` Description string `json:"description,omitempty"` + SharerID string `json:"sharer_id"` + SharerName string `json:"sharer_name"` }{ SessionID: req.SessionID, Title: req.Title, Messages: req.Messages, Description: req.Description, + SharerID: sharerID, + SharerName: sharerName, } body, err := json.Marshal(forwardReq) @@ -295,31 +299,31 @@ func (s *SessionSharingService) AddComment(ctx context.Context, teamID, shareID return "", fmt.Errorf("team not found: %w", err) } - // 验证分享会话存在 - session, err := s.sharedSessionRepo.FindByID(shareID) - if err != nil { - return "", fmt.Errorf("failed to get shared session: %w", err) - } - if session == nil { - return "", fmt.Errorf("shared session not found") - } - if session.TeamID != teamID { - return "", fmt.Errorf("shared session not found in this team") - } + // 如果是 Leader,在本地验证并存储 + if team.IsLeader { + // 验证分享会话存在(只有 Leader 端有完整数据) + session, err := s.sharedSessionRepo.FindByID(shareID) + if err != nil { + return "", fmt.Errorf("failed to get shared session: %w", err) + } + if session == nil { + return "", fmt.Errorf("shared session not found") + } + if session.TeamID != teamID { + return "", fmt.Errorf("shared session not found in this team") + } - // 创建评论 - comment := &domainTeam.SessionComment{ - ID: uuid.New().String(), - ShareID: shareID, - AuthorID: authorID, - AuthorName: authorName, - Content: req.Content, - Mentions: req.Mentions, - CreatedAt: time.Now(), - } + // 创建评论 + comment := &domainTeam.SessionComment{ + ID: uuid.New().String(), + ShareID: shareID, + AuthorID: authorID, + AuthorName: authorName, + Content: req.Content, + Mentions: req.Mentions, + CreatedAt: time.Now(), + } - // 如果是 Leader,直接存储并广播 - if team.IsLeader { if err := s.sharedSessionRepo.CreateComment(comment); err != nil { return "", fmt.Errorf("failed to save comment: %w", err) } @@ -358,7 +362,7 @@ func (s *SessionSharingService) AddComment(ctx context.Context, teamID, shareID return comment.ID, nil } - // 非 Leader,转发请求到 Leader + // 非 Leader,转发请求到 Leader(由 Leader 端负责验证和存储) if !team.LeaderOnline { return "", fmt.Errorf("leader is offline, cannot add comment") } @@ -370,6 +374,10 @@ func (s *SessionSharingService) AddComment(ctx context.Context, teamID, shareID func (s *SessionSharingService) forwardCommentToLeader(ctx context.Context, team *domainTeam.Team, shareID string, req *domainTeam.AddCommentRequest, authorID, authorName string) (string, error) { url := fmt.Sprintf("http://%s/api/v1/team/%s/sessions/%s/comments", team.LeaderEndpoint, team.ID, shareID) + // 在转发请求中携带评论者身份信息,避免 Leader 端使用自身身份 + req.AuthorID = authorID + req.AuthorName = authorName + body, err := json.Marshal(req) if err != nil { return "", fmt.Errorf("failed to marshal forward request: %w", err) @@ -492,8 +500,8 @@ func (s *SessionSharingService) forwardGetSessionDetailToLeader(ctx context.Cont // 解析 Leader 返回的会话详情 var result struct { Data struct { - Session *domainTeam.SharedSession `json:"session"` - Comments []domainTeam.SessionComment `json:"comments"` + Session *domainTeam.SharedSession `json:"session"` + Comments []domainTeam.SessionComment `json:"comments"` } `json:"data"` } if err := json.Unmarshal(respBody, &result); err != nil { diff --git a/backend/internal/application/team/sync_service_test.go b/backend/internal/application/team/sync_service_test.go index 29756d6..52d152f 100644 --- a/backend/internal/application/team/sync_service_test.go +++ b/backend/internal/application/team/sync_service_test.go @@ -6,91 +6,15 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/cocursor/backend/internal/application/team/mocks" "github.com/cocursor/backend/internal/domain/p2p" domainTeam "github.com/cocursor/backend/internal/domain/team" infraTeam "github.com/cocursor/backend/internal/infrastructure/team" ) -// mockTeamService 实现 TeamServiceInterface 用于测试 -type mockTeamService struct { - teams map[string]*domainTeam.Team - members map[string][]*domainTeam.TeamMember - skillIndexes map[string]*domainTeam.TeamSkillIndex - lastSyncCalls []string - onlineCalls []struct { - teamID string - online bool - } -} - -func newMockTeamService() *mockTeamService { - return &mockTeamService{ - teams: make(map[string]*domainTeam.Team), - members: make(map[string][]*domainTeam.TeamMember), - skillIndexes: make(map[string]*domainTeam.TeamSkillIndex), - } -} - -func (m *mockTeamService) GetTeam(teamID string) (*domainTeam.Team, error) { - if team, ok := m.teams[teamID]; ok { - return team, nil - } - return nil, domainTeam.ErrTeamNotFound -} - -func (m *mockTeamService) GetTeamList() []*domainTeam.Team { - var result []*domainTeam.Team - for _, team := range m.teams { - result = append(result, team) - } - return result -} - -func (m *mockTeamService) GetTeamMembers(teamID string) ([]*domainTeam.TeamMember, error) { - if members, ok := m.members[teamID]; ok { - return members, nil - } - return nil, nil -} - -func (m *mockTeamService) GetOnlineMembers(teamID string) ([]*domainTeam.TeamMember, error) { - members, err := m.GetTeamMembers(teamID) - if err != nil { - return nil, err - } - var online []*domainTeam.TeamMember - for _, member := range members { - if member.IsOnline { - online = append(online, member) - } - } - return online, nil -} - -func (m *mockTeamService) GetSkillIndex(teamID string) (*domainTeam.TeamSkillIndex, error) { - if index, ok := m.skillIndexes[teamID]; ok { - return index, nil - } - return nil, nil -} - -func (m *mockTeamService) UpdateLastSync(teamID string) { - m.lastSyncCalls = append(m.lastSyncCalls, teamID) -} - -func (m *mockTeamService) UpdateLeaderOnline(teamID string, online bool) { - m.onlineCalls = append(m.onlineCalls, struct { - teamID string - online bool - }{teamID, online}) - // 同时更新 team 对象 - if team, ok := m.teams[teamID]; ok { - team.LeaderOnline = online - } -} - func TestSyncService_HandleSkillEvents(t *testing.T) { tmpDir, err := os.MkdirTemp("", "sync-service-test") require.NoError(t, err) @@ -102,13 +26,8 @@ func TestSyncService_HandleSkillEvents(t *testing.T) { teamID := "test-team" - // 创建 mock 服务 - mockService := newMockTeamService() - mockService.teams[teamID] = &domainTeam.Team{ - ID: teamID, - Name: "Test Team", - IsLeader: false, - } + // 创建 mockery mock 服务 + mockService := mocks.NewMockTeamServiceInterface(t) skillIndexStore, err := infraTeam.NewSkillIndexStore(teamID) require.NoError(t, err) @@ -205,16 +124,8 @@ func TestSyncService_HandleMemberEvents(t *testing.T) { teamID := "test-team" - // 创建 mock 服务 - mockService := newMockTeamService() - mockService.teams[teamID] = &domainTeam.Team{ - ID: teamID, - Name: "Test Team", - MemberCount: 2, - IsLeader: false, - JoinedAt: time.Now(), - CreatedAt: time.Now(), - } + // 创建 mockery mock 服务 + mockService := mocks.NewMockTeamServiceInterface(t) // 创建同步服务 syncService := NewSyncService(mockService, nil) @@ -268,14 +179,8 @@ func TestSyncService_HandleTeamDissolved(t *testing.T) { teamID := "test-team" - // 创建 mock 服务 - mockService := newMockTeamService() - mockService.teams[teamID] = &domainTeam.Team{ - ID: teamID, - Name: "Test Team", - IsLeader: false, - JoinedAt: time.Now(), - } + // 创建 mockery mock 服务 + mockService := mocks.NewMockTeamServiceInterface(t) skillIndexStore, _ := infraTeam.NewSkillIndexStore(teamID) skillIndexStores := map[string]*infraTeam.SkillIndexStore{ @@ -317,24 +222,38 @@ func TestEventListener(t *testing.T) { teamID := "test-team" - // 创建 mock 服务 - mockService := newMockTeamService() - mockService.teams[teamID] = &domainTeam.Team{ - ID: teamID, - Name: "Test Team", - IsLeader: false, - LeaderOnline: false, - JoinedAt: time.Now(), - } + // 创建 mockery mock 服务 + mockService := mocks.NewMockTeamServiceInterface(t) + + // OnConnect 会调用 UpdateLeaderOnline(teamID, true) + // 然后启动 goroutine 调用 SyncSkillIndex -> GetTeam -> 返回 IsLeader=true,跳过同步 + // OnDisconnect 会调用 UpdateLeaderOnline(teamID, false) + mockService.On("UpdateLeaderOnline", teamID, true).Return().Once() + mockService.On("GetTeam", teamID).Return(&domainTeam.Team{ + ID: teamID, + Name: "Test Team", + IsLeader: true, // 使 SyncSkillIndex 跳过 HTTP 请求 + }, nil).Maybe() + mockService.On("UpdateLeaderOnline", teamID, false).Return().Once() syncService := NewSyncService(mockService, nil) listener := NewEventListener(syncService, mockService) // 测试连接回调 listener.OnConnect(teamID) - assert.True(t, mockService.teams[teamID].LeaderOnline) + + // 等待 OnConnect 启动的 goroutine(SyncSkillIndex)完成 + time.Sleep(100 * time.Millisecond) + + // 验证 UpdateLeaderOnline(true) 被调用 + mockService.AssertCalled(t, "UpdateLeaderOnline", teamID, true) // 测试断开回调 listener.OnDisconnect(teamID, nil) - assert.False(t, mockService.teams[teamID].LeaderOnline) + + // 验证 UpdateLeaderOnline(false) 被调用 + mockService.AssertCalled(t, "UpdateLeaderOnline", teamID, false) + + // 验证所有期望都满足(由 Cleanup 自动检查) + mock.AssertExpectationsForObjects(t, mockService) } diff --git a/backend/internal/domain/team/session_sharing.go b/backend/internal/domain/team/session_sharing.go index 3b5bab4..4fc0518 100644 --- a/backend/internal/domain/team/session_sharing.go +++ b/backend/internal/domain/team/session_sharing.go @@ -64,10 +64,12 @@ type SessionComment struct { // ShareSessionRequest 分享会话请求 type ShareSessionRequest struct { - SessionID string `json:"session_id"` // 原始会话 ID - Title string `json:"title"` // 会话标题 - Messages json.RawMessage `json:"messages"` // 消息内容 - Description string `json:"description,omitempty"` // 可选分享说明 + SessionID string `json:"session_id"` // 原始会话 ID + Title string `json:"title"` // 会话标题 + Messages json.RawMessage `json:"messages"` // 消息内容 + Description string `json:"description,omitempty"` // 可选分享说明 + SharerID string `json:"sharer_id,omitempty"` // 分享者 ID(转发场景携带) + SharerName string `json:"sharer_name,omitempty"` // 分享者名称(转发场景携带) } // Validate 验证分享请求 @@ -86,8 +88,10 @@ func (r *ShareSessionRequest) Validate() error { // AddCommentRequest 添加评论请求 type AddCommentRequest struct { - Content string `json:"content"` // 评论内容 - Mentions []string `json:"mentions,omitempty"` // @提及的成员 ID 列表 + Content string `json:"content"` // 评论内容 + Mentions []string `json:"mentions,omitempty"` // @提及的成员 ID 列表 + AuthorID string `json:"author_id,omitempty"` // 评论者 ID(转发场景携带) + AuthorName string `json:"author_name,omitempty"` // 评论者名称(转发场景携带) } // Validate 验证评论请求 diff --git a/backend/internal/interfaces/http/handler/team_session.go b/backend/internal/interfaces/http/handler/team_session.go index 6e8f621..28cc981 100644 --- a/backend/internal/interfaces/http/handler/team_session.go +++ b/backend/internal/interfaces/http/handler/team_session.go @@ -80,8 +80,16 @@ func (h *TeamSessionHandler) ShareSession(c *gin.Context) { return } + // 确定分享者身份:转发请求中携带了原始分享者信息时优先使用 + sharerID := identity.ID + sharerName := identity.Name + if req.SharerID != "" && req.SharerName != "" { + sharerID = req.SharerID + sharerName = req.SharerName + } + // 分享会话 - shareID, err := h.sessionSharingService.ShareSession(c.Request.Context(), teamID, &req, identity.ID, identity.Name) + shareID, err := h.sessionSharingService.ShareSession(c.Request.Context(), teamID, &req, sharerID, sharerName) if err != nil { response.Error(c, http.StatusInternalServerError, 610004, "Failed to share session: "+err.Error()) return @@ -194,16 +202,28 @@ func (h *TeamSessionHandler) AddComment(c *gin.Context) { return } - // 获取当前用户身份 - identity, err := h.identityService.GetIdentity() - if err != nil { - response.Error(c, http.StatusUnauthorized, 610003, "Identity not found, please create identity first") - return + // 确定评论者身份:优先使用请求体中携带的身份信息(转发场景),否则使用本地身份 + authorID := req.AuthorID + authorName := req.AuthorName + if authorID == "" || authorName == "" { + identity, err := h.identityService.GetIdentity() + if err != nil { + response.Error(c, http.StatusUnauthorized, 610003, "Identity not found, please create identity first") + return + } + authorID = identity.ID + authorName = identity.Name } // 添加评论 - commentID, err := h.sessionSharingService.AddComment(c.Request.Context(), teamID, shareID, &req, identity.ID, identity.Name) + commentID, err := h.sessionSharingService.AddComment(c.Request.Context(), teamID, shareID, &req, authorID, authorName) if err != nil { + h.logger.Error("failed to add comment", + "error", err, + "team_id", teamID, + "share_id", shareID, + "author_id", authorID, + ) response.Error(c, http.StatusInternalServerError, 610007, "Failed to add comment: "+err.Error()) return } diff --git a/backend/test/integration/p1_collaboration_test.go b/backend/test/integration/p1_collaboration_test.go index f3cf0de..a8a0844 100644 --- a/backend/test/integration/p1_collaboration_test.go +++ b/backend/test/integration/p1_collaboration_test.go @@ -276,12 +276,13 @@ func TestCollaboration_MemberAddComment(t *testing.T) { require.Equal(t, 0, detailResp.Code) assert.GreaterOrEqual(t, len(detailResp.Data.Comments), 2, "应有至少 2 条评论") - // 验证 Member 的评论存在 + // 验证 Member 的评论存在,且评论者名称正确(应为 Member 而非 Leader) memberCommentFound := false for _, c := range detailResp.Data.Comments { t.Logf(" Comment by %s: %s", c.AuthorName, c.Content) if c.Content == "DDD 架构很好,我之前用过,推荐!" { memberCommentFound = true + assert.Equal(t, "Member", c.AuthorName, "Member 转发的评论,评论者名称应为 Member 而非 Leader") } } assert.True(t, memberCommentFound, "应能找到 Member 通过转发添加的评论") @@ -290,6 +291,231 @@ func TestCollaboration_MemberAddComment(t *testing.T) { leaderClient.DissolveTeam(teamID) } +// TestCollaboration_MemberViewSharedSessions Member 通过转发查看分享列表和详情 +func TestCollaboration_MemberViewSharedSessions(t *testing.T) { + leader, member, leaderClient, memberClient, teamID := setupTeamWithMembers(t) + defer leader.Stop() + defer member.Stop() + + // === Leader 分享两个会话 === + t.Log("--- Leader 分享会话 ---") + for i := 1; i <= 2; i++ { + shareReq := &domainTeam.ShareSessionRequest{ + SessionID: fmt.Sprintf("view-test-session-%d", i), + Title: fmt.Sprintf("可查看会话 %d", i), + Messages: framework.MakeMessages([]map[string]string{ + {"role": "user", "content": fmt.Sprintf("第 %d 条消息", i)}, + }), + } + resp, err := leaderClient.ShareSession(teamID, shareReq) + require.NoError(t, err) + require.Equal(t, 0, resp.Code, "Leader 分享会话 %d 应成功", i) + t.Logf("Leader shared session %d: %s", i, resp.Data.ShareID) + } + + // === Member 通过转发查看分享列表 === + t.Log("--- Member 查看分享列表(转发到 Leader) ---") + listResp, err := memberClient.GetSharedSessions(teamID, 20, 0) + require.NoError(t, err) + require.Equal(t, 0, listResp.Code, "Member 查看分享列表应成功, message: %s", listResp.Message) + assert.GreaterOrEqual(t, listResp.Data.Total, 2, "应有至少 2 个分享") + t.Logf("Member sees %d shared sessions", listResp.Data.Total) + + // 取第一条分享 ID 用于查看详情 + require.NotEmpty(t, listResp.Data.Sessions, "分享列表不应为空") + shareID := listResp.Data.Sessions[0].ID + + // === Member 通过转发查看分享详情 === + t.Log("--- Member 查看分享详情(转发到 Leader) ---") + detailResp, err := memberClient.GetSharedSessionDetail(teamID, shareID) + require.NoError(t, err) + require.Equal(t, 0, detailResp.Code, "Member 查看分享详情应成功, message: %s", detailResp.Message) + require.NotNil(t, detailResp.Data.Session, "会话详情不应为空") + assert.NotEmpty(t, detailResp.Data.Session.Title) + t.Logf("Member viewed session detail: title=%s", detailResp.Data.Session.Title) + + // 清理 + leaderClient.DissolveTeam(teamID) +} + +// TestCollaboration_CommentCountIncrement 评论数递增验证 +func TestCollaboration_CommentCountIncrement(t *testing.T) { + leader, member, leaderClient, memberClient, teamID := setupTeamWithMembers(t) + defer leader.Stop() + defer member.Stop() + + // === Leader 分享会话 === + t.Log("--- Leader 分享会话 ---") + shareReq := &domainTeam.ShareSessionRequest{ + SessionID: "count-test-session", + Title: "评论数测试", + Messages: framework.MakeMessages([]map[string]string{ + {"role": "user", "content": "测试评论数递增"}, + }), + } + shareResp, err := leaderClient.ShareSession(teamID, shareReq) + require.NoError(t, err) + require.Equal(t, 0, shareResp.Code) + shareID := shareResp.Data.ShareID + + // === 验证初始评论数为 0 === + detailResp, err := leaderClient.GetSharedSessionDetail(teamID, shareID) + require.NoError(t, err) + require.Equal(t, 0, detailResp.Code) + assert.Equal(t, 0, detailResp.Data.Session.CommentCount, "初始评论数应为 0") + + // === 添加 3 条评论(Leader 2 条 + Member 转发 1 条) === + t.Log("--- 添加多条评论 ---") + _, err = leaderClient.AddComment(teamID, shareID, "Leader 第一条评论", nil) + require.NoError(t, err) + + commentResp, err := memberClient.AddComment(teamID, shareID, "Member 转发的评论", nil) + require.NoError(t, err) + require.Equal(t, 0, commentResp.Code, "Member 添加评论应成功(转发到 Leader), message: %s", commentResp.Message) + + _, err = leaderClient.AddComment(teamID, shareID, "Leader 第二条评论", nil) + require.NoError(t, err) + + // === 验证评论数递增到 3 === + t.Log("--- 验证评论数 ---") + detailResp2, err := leaderClient.GetSharedSessionDetail(teamID, shareID) + require.NoError(t, err) + require.Equal(t, 0, detailResp2.Code) + assert.Equal(t, 3, detailResp2.Data.Session.CommentCount, "评论数应递增到 3") + assert.Len(t, detailResp2.Data.Comments, 3, "应有 3 条评论记录") + t.Logf("Comment count: %d, actual comments: %d", detailResp2.Data.Session.CommentCount, len(detailResp2.Data.Comments)) + + // === 验证列表中的评论数也正确 === + listResp, err := leaderClient.GetSharedSessions(teamID, 20, 0) + require.NoError(t, err) + require.Equal(t, 0, listResp.Code) + + for _, s := range listResp.Data.Sessions { + if s.ID == shareID { + assert.Equal(t, 3, s.CommentCount, "列表中的评论数应为 3") + t.Logf("Session in list: comment_count=%d", s.CommentCount) + } + } + + // 清理 + leaderClient.DissolveTeam(teamID) +} + +// TestCollaboration_CommentValidation 评论参数校验 +func TestCollaboration_CommentValidation(t *testing.T) { + framework.RequireDaemonBinary(t) + + leaderDaemon, err := framework.NewTestDaemon(framework.BinaryPath, "comment-validation-leader") + require.NoError(t, err) + require.NoError(t, leaderDaemon.Start()) + defer leaderDaemon.Stop() + + leaderClient := framework.NewAPIClient(leaderDaemon.BaseURL()) + _, teamID, err := leaderClient.MustCreateIdentityAndTeam("Validator", "校验测试团队") + require.NoError(t, err) + + // === 先分享一个会话 === + shareReq := &domainTeam.ShareSessionRequest{ + SessionID: "validation-session", + Title: "校验测试", + Messages: framework.MakeMessages([]map[string]string{ + {"role": "user", "content": "测试"}, + }), + } + shareResp, err := leaderClient.ShareSession(teamID, shareReq) + require.NoError(t, err) + require.Equal(t, 0, shareResp.Code) + shareID := shareResp.Data.ShareID + + // === 空内容评论应失败 === + t.Log("--- 测试空内容评论 ---") + emptyResp, err := leaderClient.AddComment(teamID, shareID, "", nil) + require.NoError(t, err) + assert.NotEqual(t, 0, emptyResp.Code, "空内容评论应失败") + t.Logf("Empty content response: code=%d, message=%s", emptyResp.Code, emptyResp.Message) + + // === 不存在的 shareID 应失败 === + t.Log("--- 测试不存在的 shareID ---") + notFoundResp, err := leaderClient.AddComment(teamID, "non-existent-share-id", "这条评论不该成功", nil) + require.NoError(t, err) + assert.NotEqual(t, 0, notFoundResp.Code, "不存在的 shareID 应失败") + t.Logf("Not found response: code=%d, message=%s", notFoundResp.Code, notFoundResp.Message) + + // === 不存在的 teamID 应失败 === + t.Log("--- 测试不存在的 teamID ---") + badTeamResp, err := leaderClient.AddComment("non-existent-team-id", shareID, "这条评论不该成功", nil) + require.NoError(t, err) + assert.NotEqual(t, 0, badTeamResp.Code, "不存在的 teamID 应失败") + t.Logf("Bad team response: code=%d, message=%s", badTeamResp.Code, badTeamResp.Message) + + // === 带 mentions 的正常评论应成功 === + t.Log("--- 测试带 mentions 的评论 ---") + mentionResp, err := leaderClient.AddComment(teamID, shareID, "@someone 你看看这个", []string{"someone-id"}) + require.NoError(t, err) + require.Equal(t, 0, mentionResp.Code, "带 mentions 的评论应成功") + assert.NotEmpty(t, mentionResp.Data.CommentID) + t.Logf("Comment with mentions: %s", mentionResp.Data.CommentID) + + // 清理 + leaderClient.DissolveTeam(teamID) +} + +// TestCollaboration_MemberCommentRoundtrip Member 评论完整往返验证 +func TestCollaboration_MemberCommentRoundtrip(t *testing.T) { + leader, member, leaderClient, memberClient, teamID := setupTeamWithMembers(t) + defer leader.Stop() + defer member.Stop() + + // === Leader 分享会话 === + t.Log("--- Leader 分享会话 ---") + shareReq := &domainTeam.ShareSessionRequest{ + SessionID: "roundtrip-session", + Title: "评论往返测试", + Messages: framework.MakeMessages([]map[string]string{ + {"role": "user", "content": "测试评论往返"}, + }), + } + shareResp, err := leaderClient.ShareSession(teamID, shareReq) + require.NoError(t, err) + require.Equal(t, 0, shareResp.Code) + shareID := shareResp.Data.ShareID + + // === Member 添加评论(转发到 Leader) === + t.Log("--- Member 添加评论 ---") + memberComment, err := memberClient.AddComment(teamID, shareID, "Member 的评论,包含中文和 emoji 🎉", nil) + require.NoError(t, err) + require.Equal(t, 0, memberComment.Code, "Member 添加评论应成功, message: %s", memberComment.Message) + memberCommentID := memberComment.Data.CommentID + assert.NotEmpty(t, memberCommentID, "评论 ID 不应为空") + t.Logf("Member comment ID: %s", memberCommentID) + + // === Leader 添加评论 === + t.Log("--- Leader 添加评论 ---") + leaderComment, err := leaderClient.AddComment(teamID, shareID, "Leader 回复 Member 的评论", nil) + require.NoError(t, err) + require.Equal(t, 0, leaderComment.Code) + + // === Member 通过转发查看详情,验证两条评论都存在 === + t.Log("--- Member 查看评论(转发到 Leader) ---") + detailResp, err := memberClient.GetSharedSessionDetail(teamID, shareID) + require.NoError(t, err) + require.Equal(t, 0, detailResp.Code, "Member 查看详情应成功, message: %s", detailResp.Message) + assert.Len(t, detailResp.Data.Comments, 2, "应有 2 条评论") + + // 验证评论内容和顺序(按 created_at ASC) + if len(detailResp.Data.Comments) >= 2 { + assert.Equal(t, "Member 的评论,包含中文和 emoji 🎉", detailResp.Data.Comments[0].Content, "第一条应是 Member 的评论") + assert.Equal(t, "Leader 回复 Member 的评论", detailResp.Data.Comments[1].Content, "第二条应是 Leader 的评论") + } + + for _, c := range detailResp.Data.Comments { + t.Logf(" Comment by %s: %s (at %s)", c.AuthorName, c.Content, c.CreatedAt) + } + + // 清理 + leaderClient.DissolveTeam(teamID) +} + // TestCollaboration_NetworkInterfaces 网络接口查询 func TestCollaboration_NetworkInterfaces(t *testing.T) { framework.RequireDaemonBinary(t) diff --git a/co-extension/src/extension.ts b/co-extension/src/extension.ts index 2ee65d8..da8aa69 100644 --- a/co-extension/src/extension.ts +++ b/co-extension/src/extension.ts @@ -262,9 +262,10 @@ export function activate(context: vscode.ExtensionContext): void { } const session = sessionResp.data.data.session; + const messages = sessionResp.data.data.messages || []; // 5. 将消息格式从后端模型 (type/text) 转换为共享会话格式 (role/content) - const normalizedMessages = (session.messages || []).map( + const normalizedMessages = messages.map( (msg: { type?: string; text?: string; role?: string; content?: string }) => ({ role: msg.role || (msg.type === "ai" ? "assistant" : msg.type) || "user", content: msg.content || msg.text || "", @@ -275,6 +276,7 @@ export function activate(context: vscode.ExtensionContext): void { await axios.post( `http://localhost:19960/api/v1/team/${targetTeamId}/sessions/share`, { + session_id: item.composerId, title: session.name || item.label, messages: normalizedMessages, description: description || undefined diff --git a/co-extension/src/webview/components/Team/SharedSessionDetail.tsx b/co-extension/src/webview/components/Team/SharedSessionDetail.tsx index 678f08e..1ca77e1 100644 --- a/co-extension/src/webview/components/Team/SharedSessionDetail.tsx +++ b/co-extension/src/webview/components/Team/SharedSessionDetail.tsx @@ -1,9 +1,12 @@ /** * 共享会话详情组件 * 显示会话内容和评论区 + * - 左右布局:User 靠左,Assistant 靠右 + * - 连续同角色消息自动合并为一个气泡 + * - AI 回复过长时默认截断,可展开 */ -import React, { useState, useCallback, useRef, useEffect } from "react"; +import React, { useState, useCallback, useRef, useEffect, useMemo } from "react"; import { useTranslation } from "react-i18next"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; @@ -18,6 +21,12 @@ interface SessionMessage { content: string; } +// 合并后的消息组(连续同角色消息合并为一组) +interface MergedMessage { + role: string; + contents: string[]; +} + // 共享会话详情 interface SharedSession { id: string; @@ -47,6 +56,78 @@ interface SharedSessionDetailProps { onBack: () => void; } +/** 将连续同角色消息合并为一组 */ +function mergeMessages(messages: SessionMessage[]): MergedMessage[] { + if (!messages || messages.length === 0) return []; + + const merged: MergedMessage[] = []; + let current: MergedMessage | null = null; + + for (const msg of messages) { + if (current && current.role === msg.role) { + // 同角色,追加到当前组 + current.contents.push(msg.content); + } else { + // 新角色,开始新组 + if (current) merged.push(current); + current = { role: msg.role, contents: [msg.content] }; + } + } + if (current) merged.push(current); + + return merged; +} + +/** 可折叠的消息内容组件 */ +const CollapsibleContent: React.FC<{ + contents: string[]; + role: string; +}> = ({ contents, role }) => { + const [expanded, setExpanded] = useState(false); + const contentRef = useRef(null); + const [needsCollapse, setNeedsCollapse] = useState(false); + + // 内容渲染后检测是否需要折叠(高度超过 150px) + useEffect(() => { + if (contentRef.current) { + setNeedsCollapse(contentRef.current.scrollHeight > 150); + } + }, [contents]); + + // Assistant 消息才做折叠,User 消息通常很短 + const shouldCollapse = role === "assistant" && needsCollapse && !expanded; + + return ( + <> +
+ {contents.map((content, i) => ( + + {i > 0 &&
} + + {content} + +
+ ))} +
+ {role === "assistant" && needsCollapse && ( + + )} + + ); +}; + export const SharedSessionDetail: React.FC = ({ teamId, sessionId, @@ -75,6 +156,12 @@ export const SharedSessionDetail: React.FC = ({ const session = data?.session; const comments = data?.comments || []; + // 合并连续同角色消息 + const mergedMessages = useMemo( + () => mergeMessages(session?.messages || []), + [session?.messages] + ); + // 滚动到评论底部 useEffect(() => { if (comments.length > 0) { @@ -176,26 +263,40 @@ export const SharedSessionDetail: React.FC = ({ {/* 会话内容 */}

{t("session.conversation")}

-
- {session.messages.map((msg, index) => ( -
-
- {msg.role === "user" ? "👤 User" : "🤖 Assistant"} -
-
- - {msg.content} - + + {mergedMessages.length === 0 ? ( +
+ 💬 + + {t("session.noMessages", "暂无对话内容")} + + + {t("session.noMessagesDesc", "该会话未包含可显示的对话记录")} + +
+ ) : ( +
+ {mergedMessages.map((msg, index) => ( +
+
+ + {msg.role === "user" ? "U" : "A"} + + {msg.role === "user" ? "User" : "Assistant"} + {msg.contents.length > 1 && ( + + {msg.contents.length} 条合并 + + )} +
+
-
- ))} -
+ ))} +
+ )}
{/* 评论区 */} diff --git a/co-extension/src/webview/styles/team.css b/co-extension/src/webview/styles/team.css index 73532ad..4f1b70f 100644 --- a/co-extension/src/webview/styles/team.css +++ b/co-extension/src/webview/styles/team.css @@ -1582,28 +1582,29 @@ /* 共享会话详情 */ .cocursor-shared-session-detail { - padding: 0 16px 16px; + padding: 0 12px 16px; } .cocursor-shared-session-detail-header { - margin-bottom: 20px; + margin-bottom: 16px; } .cocursor-shared-session-detail-info { - margin-top: 16px; + margin-top: 10px; } .cocursor-shared-session-detail-info h2 { - margin: 0 0 8px 0; - font-size: 18px; + margin: 0 0 6px 0; + font-size: 15px; font-weight: 600; color: var(--vscode-foreground); + line-height: 1.3; } .cocursor-shared-session-detail-meta { display: flex; - gap: 16px; - font-size: 13px; + gap: 12px; + font-size: 11px; color: var(--vscode-descriptionForeground); flex-wrap: wrap; } @@ -1617,7 +1618,7 @@ font-size: 14px; font-weight: 600; color: var(--vscode-foreground); - margin: 0 0 16px 0; + margin: 0 0 12px 0; padding-bottom: 8px; border-bottom: 1px solid var(--vscode-panel-border); } @@ -1625,52 +1626,220 @@ .cocursor-shared-session-message-list { display: flex; flex-direction: column; - gap: 16px; - max-height: 500px; + gap: 2px; + max-height: 600px; overflow-y: auto; - padding-right: 8px; + padding: 0; } +/* 消息卡片:全宽,通过左侧色条和背景色区分角色 */ .cocursor-shared-session-message { - background: var(--vscode-sideBar-background); - border: 1px solid var(--vscode-panel-border); - border-radius: 8px; - padding: 12px 16px; + padding: 10px 12px; + border-left: 3px solid transparent; + transition: background 0.15s; } +/* User 消息 */ .cocursor-shared-session-message.user { - border-left: 3px solid var(--vscode-charts-blue); + border-left-color: var(--vscode-charts-blue); + background: rgba(79, 193, 255, 0.04); } +/* Assistant 消息 */ .cocursor-shared-session-message.assistant { - border-left: 3px solid var(--vscode-charts-green); + border-left-color: var(--vscode-charts-green); + background: rgba(106, 153, 85, 0.04); +} + +.cocursor-shared-session-message:hover { + background: var(--vscode-list-hoverBackground); } +/* 角色标签行 */ .cocursor-shared-session-message-role { - font-size: 12px; - font-weight: 600; - color: var(--vscode-descriptionForeground); - margin-bottom: 8px; + font-size: 11px; + font-weight: 700; + margin-bottom: 4px; + display: flex; + align-items: center; + gap: 8px; + letter-spacing: 0.3px; +} + +.cocursor-shared-session-message.user .cocursor-shared-session-message-role { + color: var(--vscode-charts-blue); +} + +.cocursor-shared-session-message.assistant .cocursor-shared-session-message-role { + color: var(--vscode-charts-green); +} + +/* 角色图标 */ +.cocursor-msg-role-icon { + width: 18px; + height: 18px; + border-radius: 4px; + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 10px; + font-weight: 700; + flex-shrink: 0; +} + +.cocursor-shared-session-message.user .cocursor-msg-role-icon { + background: rgba(79, 193, 255, 0.15); + color: var(--vscode-charts-blue); } +.cocursor-shared-session-message.assistant .cocursor-msg-role-icon { + background: rgba(106, 153, 85, 0.15); + color: var(--vscode-charts-green); +} + +/* 合并消息标识 */ +.cocursor-msg-merged-badge { + font-size: 10px; + font-weight: 500; + background: rgba(106, 153, 85, 0.15); + color: var(--vscode-charts-green); + padding: 1px 6px; + border-radius: 8px; + letter-spacing: 0; +} + +/* 合并消息分隔线 */ +.cocursor-msg-merged-separator { + border: none; + border-top: 1px dashed var(--vscode-panel-border); + margin: 8px 0; + opacity: 0.4; +} + +/* 消息正文 */ .cocursor-shared-session-message-content { - font-size: 13px; + font-size: 12.5px; line-height: 1.6; color: var(--vscode-foreground); + word-break: break-word; +} + +.cocursor-shared-session-message-content p { + margin: 0 0 6px; } +.cocursor-shared-session-message-content p:last-child { + margin-bottom: 0; +} + +/* 内容折叠态 */ +.cocursor-shared-session-message-content.collapsed { + max-height: 140px; + overflow: hidden; + position: relative; +} + +.cocursor-shared-session-message.user .cocursor-shared-session-message-content.collapsed::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 40px; + background: linear-gradient(transparent, rgba(79, 193, 255, 0.04)); + pointer-events: none; +} + +.cocursor-shared-session-message.assistant .cocursor-shared-session-message-content.collapsed::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 40px; + background: linear-gradient(transparent, rgba(106, 153, 85, 0.04)); + pointer-events: none; +} + +/* 展开/收起按钮 */ +.cocursor-msg-expand-btn { + display: inline-flex; + align-items: center; + gap: 4px; + font-size: 11px; + color: var(--vscode-textLink-foreground); + background: none; + border: none; + cursor: pointer; + padding: 4px 0 0; + margin: 0; + opacity: 0.85; +} + +.cocursor-msg-expand-btn:hover { + opacity: 1; + text-decoration: underline; +} + +.cocursor-msg-expand-arrow { + font-size: 9px; + transition: transform 0.2s; + display: inline-block; +} + +.cocursor-msg-expand-btn.expanded .cocursor-msg-expand-arrow { + transform: rotate(180deg); +} + +/* 代码块 */ .cocursor-shared-session-message-content pre { background: var(--vscode-editor-background); border: 1px solid var(--vscode-panel-border); border-radius: 4px; - padding: 12px; + padding: 8px 10px; overflow-x: auto; - margin: 8px 0; + margin: 6px 0; + font-size: 11.5px; } .cocursor-shared-session-message-content code { font-family: var(--vscode-editor-font-family); + font-size: 11.5px; +} + +/* 内联 code */ +.cocursor-shared-session-message-content p code, +.cocursor-shared-session-message-content li code { + background: rgba(255, 255, 255, 0.06); + padding: 1px 4px; + border-radius: 3px; +} + +/* 空对话状态 */ +.cocursor-shared-session-empty { + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + padding: 40px 16px; + color: var(--vscode-descriptionForeground); +} + +.cocursor-shared-session-empty-icon { + font-size: 28px; + opacity: 0.35; +} + +.cocursor-shared-session-empty-title { + font-size: 13px; + font-weight: 600; +} + +.cocursor-shared-session-empty-desc { font-size: 12px; + text-align: center; + line-height: 1.5; + opacity: 0.7; } /* 评论区 */