package handler import ( "context" "testing" "git.logidex.ru/fakz9/logidex-id/internal/api/user/domain" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) // MockUserService implements service.UserService type MockUserService struct { mock.Mock } func (m *MockUserService) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*domain.User, error) { args := m.Called(ctx, phoneNumber) if args.Get(0) == nil { return nil, args.Error(1) } return args.Get(0).(*domain.User), args.Error(1) } func (m *MockUserService) GetUserByUuid(ctx context.Context, uuid string) (*domain.User, error) { args := m.Called(ctx, uuid) if args.Get(0) == nil { return nil, args.Error(1) } return args.Get(0).(*domain.User), args.Error(1) } func (m *MockUserService) CreateUser(ctx context.Context, phoneNumber string) (*domain.User, error) { args := m.Called(ctx, phoneNumber) if args.Get(0) == nil { return nil, args.Error(1) } return args.Get(0).(*domain.User), args.Error(1) } func (m *MockUserService) VerifyUser(ctx context.Context, uuid string) (*domain.User, error) { args := m.Called(ctx, uuid) if args.Get(0) == nil { return nil, args.Error(1) } return args.Get(0).(*domain.User), args.Error(1) } func TestNewUserHandler(t *testing.T) { mockService := &MockUserService{} handler := NewUserHandler(mockService) assert.NotNil(t, handler) assert.Equal(t, mockService, handler.service) assert.Implements(t, (*StrictServerInterface)(nil), handler) } func TestUserHandler_GetUserById(t *testing.T) { tests := []struct { name string userId string setupMock func(*MockUserService) expectedStatus int expectError bool expectedMsg string }{ { name: "successful user retrieval", userId: "123e4567-e89b-12d3-a456-426614174000", setupMock: func(m *MockUserService) { user := &domain.User{ Uuid: "123e4567-e89b-12d3-a456-426614174000", PhoneNumber: "+79161234567", } m.On("GetUserByUuid", mock.Anything, "123e4567-e89b-12d3-a456-426614174000"). Return(user, nil).Once() }, expectedStatus: 200, // Fixed copier bug expectError: false, }, { name: "user not found", userId: "nonexistent-uuid", setupMock: func(m *MockUserService) { m.On("GetUserByUuid", mock.Anything, "nonexistent-uuid"). Return(nil, domain.ErrUserNotFound{PhoneNumber: "nonexistent-uuid"}).Once() }, expectedStatus: 404, expectError: true, expectedMsg: "User not found with phone number: nonexistent-uuid", }, { name: "service error", userId: "error-uuid", setupMock: func(m *MockUserService) { m.On("GetUserByUuid", mock.Anything, "error-uuid"). Return(nil, assert.AnError).Once() }, expectedStatus: 404, expectError: true, expectedMsg: assert.AnError.Error(), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { mockService := &MockUserService{} handler := &UserHandler{service: mockService} ctx := context.Background() tt.setupMock(mockService) request := GetUserByIdRequestObject{ UserId: tt.userId, } result, err := handler.GetUserById(ctx, request) assert.NoError(t, err) // Handler should not return errors, only response objects if tt.expectedStatus == 200 { response, ok := result.(GetUserById200JSONResponse) assert.True(t, ok, "Expected 200 response type") _ = response // Just to avoid unused variable error } else { response, ok := result.(GetUserById404JSONResponse) assert.True(t, ok, "Expected 404 response type") assert.Equal(t, tt.expectedMsg, response.Message) _ = response // Use the variable to avoid unused error } mockService.AssertExpectations(t) }) } } func TestUserHandler_CreateUser(t *testing.T) { mockService := &MockUserService{} handler := &UserHandler{service: mockService} ctx := context.Background() t.Run("create user not implemented", func(t *testing.T) { request := CreateUserRequestObject{} // This should panic as per the current implementation assert.Panics(t, func() { _, _ = handler.CreateUser(ctx, request) }, "CreateUser should panic as it's not implemented") }) } func TestUserHandler_EdgeCases(t *testing.T) { t.Run("empty user ID should be handled gracefully", func(t *testing.T) { mockService := &MockUserService{} handler := &UserHandler{service: mockService} ctx := context.Background() mockService.On("GetUserByUuid", mock.Anything, ""). Return(nil, domain.ErrUserNotFound{PhoneNumber: ""}).Once() request := GetUserByIdRequestObject{ UserId: "", } result, err := handler.GetUserById(ctx, request) assert.NoError(t, err) response, ok := result.(GetUserById404JSONResponse) assert.True(t, ok) assert.Contains(t, response.Message, "User not found") mockService.AssertExpectations(t) }) t.Run("special characters in user ID", func(t *testing.T) { mockService := &MockUserService{} handler := &UserHandler{service: mockService} ctx := context.Background() specialUserId := "user@#$%^&*()" mockService.On("GetUserByUuid", mock.Anything, specialUserId). Return(nil, domain.ErrUserNotFound{PhoneNumber: specialUserId}).Once() request := GetUserByIdRequestObject{ UserId: specialUserId, } result, err := handler.GetUserById(ctx, request) assert.NoError(t, err) response, ok := result.(GetUserById404JSONResponse) assert.True(t, ok) _ = response // Use the variable to avoid unused error mockService.AssertExpectations(t) }) }