package user import ( "context" "testing" "tercul/internal/app/authz" "tercul/internal/domain" platform_auth "tercul/internal/platform/auth" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) type UserCommandsSuite struct { suite.Suite repo *mockUserRepository authzSvc *authz.Service commands *UserCommands } func (s *UserCommandsSuite) SetupTest() { s.repo = &mockUserRepository{} workRepo := &mockWorkRepoForUserTests{} s.authzSvc = authz.NewService(workRepo) s.commands = NewUserCommands(s.repo, s.authzSvc) } func TestUserCommandsSuite(t *testing.T) { suite.Run(t, new(UserCommandsSuite)) } func (s *UserCommandsSuite) TestUpdateUser_Success_Self() { // Arrange ctx := platform_auth.ContextWithUserID(context.Background(), 1) input := UpdateUserInput{ID: 1, Username: strPtr("new_username")} s.repo.getByIDFunc = func(ctx context.Context, id uint) (*domain.User, error) { return &domain.User{BaseModel: domain.BaseModel{ID: 1}}, nil } // Act updatedUser, err := s.commands.UpdateUser(ctx, input) // Assert assert.NoError(s.T(), err) assert.NotNil(s.T(), updatedUser) assert.Equal(s.T(), "new_username", updatedUser.Username) } func (s *UserCommandsSuite) TestUpdateUser_Success_Admin() { // Arrange ctx := platform_auth.ContextWithAdminUser(context.Background(), 99) // Admin user input := UpdateUserInput{ID: 1, Username: strPtr("new_username_by_admin")} s.repo.getByIDFunc = func(ctx context.Context, id uint) (*domain.User, error) { return &domain.User{BaseModel: domain.BaseModel{ID: 1}}, nil } // Act updatedUser, err := s.commands.UpdateUser(ctx, input) // Assert assert.NoError(s.T(), err) assert.NotNil(s.T(), updatedUser) assert.Equal(s.T(), "new_username_by_admin", updatedUser.Username) } func (s *UserCommandsSuite) TestUpdateUser_Forbidden() { // Arrange ctx := platform_auth.ContextWithUserID(context.Background(), 2) // Different user input := UpdateUserInput{ID: 1, Username: strPtr("forbidden_username")} s.repo.getByIDFunc = func(ctx context.Context, id uint) (*domain.User, error) { return &domain.User{BaseModel: domain.BaseModel{ID: 1}}, nil } // Act _, err := s.commands.UpdateUser(ctx, input) // Assert assert.Error(s.T(), err) assert.ErrorIs(s.T(), err, domain.ErrForbidden) } func (s *UserCommandsSuite) TestUpdateUser_Unauthorized() { // Arrange ctx := context.Background() // No user in context input := UpdateUserInput{ID: 1, Username: strPtr("unauthorized_username")} // Act _, err := s.commands.UpdateUser(ctx, input) // Assert assert.Error(s.T(), err) assert.ErrorIs(s.T(), err, domain.ErrUnauthorized) } // Helper to get a pointer to a string func strPtr(s string) *string { return &s }