package handler import ( "baron-sso-backend/internal/domain" "bytes" "context" "encoding/json" "net/http" "net/http/httptest" "testing" "github.com/gofiber/fiber/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) // --- Mocks --- type MockUserGroupService struct { mock.Mock } func (m *MockUserGroupService) Create(ctx context.Context, tenantID string, parentID *string, name, description, unitType string) (*domain.UserGroup, error) { args := m.Called(ctx, tenantID, parentID, name, description, unitType) if args.Get(0) == nil { return nil, args.Error(1) } return args.Get(0).(*domain.UserGroup), args.Error(1) } func (m *MockUserGroupService) Update(ctx context.Context, tenantID, groupID string, name, description, unitType string, parentID *string) (*domain.UserGroup, error) { args := m.Called(ctx, tenantID, groupID, name, description, unitType, parentID) if args.Get(0) == nil { return nil, args.Error(1) } return args.Get(0).(*domain.UserGroup), args.Error(1) } func (m *MockUserGroupService) Delete(ctx context.Context, tenantID, groupID string) error { return m.Called(ctx, tenantID, groupID).Error(0) } func (m *MockUserGroupService) Get(ctx context.Context, id string) (*domain.UserGroup, error) { args := m.Called(ctx, id) if args.Get(0) == nil { return nil, args.Error(1) } return args.Get(0).(*domain.UserGroup), args.Error(1) } func (m *MockUserGroupService) List(ctx context.Context, tenantID string) ([]domain.UserGroup, error) { args := m.Called(ctx, tenantID) return args.Get(0).([]domain.UserGroup), args.Error(1) } func (m *MockUserGroupService) AddMember(ctx context.Context, groupID, userID string) error { return m.Called(ctx, groupID, userID).Error(0) } func (m *MockUserGroupService) RemoveMember(ctx context.Context, groupID, userID string) error { return m.Called(ctx, groupID, userID).Error(0) } func (m *MockUserGroupService) ListRoles(ctx context.Context, groupID string) ([]domain.GroupRole, error) { args := m.Called(ctx, groupID) return args.Get(0).([]domain.GroupRole), args.Error(1) } func (m *MockUserGroupService) AssignRoleToTenant(ctx context.Context, groupID, tenantID, relation string) error { return m.Called(ctx, groupID, tenantID, relation).Error(0) } func (m *MockUserGroupService) RemoveRoleFromTenant(ctx context.Context, groupID, tenantID, relation string) error { return m.Called(ctx, groupID, tenantID, relation).Error(0) } // --- Tests --- func TestUserGroupHandler_List(t *testing.T) { mockSvc := new(MockUserGroupService) h := NewUserGroupHandler(mockSvc) app := fiber.New() app.Get("/tenants/:tenantId/user-groups", h.List) tenantID := "t1" groups := []domain.UserGroup{{ID: "g1", Name: "Group 1"}} mockSvc.On("List", mock.Anything, tenantID).Return(groups, nil) req := httptest.NewRequest("GET", "/tenants/t1/user-groups", nil) resp, _ := app.Test(req) assert.Equal(t, http.StatusOK, resp.StatusCode) var result []domain.UserGroup json.NewDecoder(resp.Body).Decode(&result) assert.Len(t, result, 1) assert.Equal(t, "Group 1", result[0].Name) } func TestUserGroupHandler_Create(t *testing.T) { mockSvc := new(MockUserGroupService) h := NewUserGroupHandler(mockSvc) app := fiber.New() app.Post("/tenants/:tenantId/user-groups", h.Create) body, _ := json.Marshal(map[string]string{"name": "New Group"}) mockSvc.On("Create", mock.Anything, "t1", mock.Anything, "New Group", mock.Anything, mock.Anything).Return(&domain.UserGroup{ID: "g1", Name: "New Group"}, nil) req := httptest.NewRequest("POST", "/tenants/t1/user-groups", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") resp, _ := app.Test(req) assert.Equal(t, http.StatusCreated, resp.StatusCode) } func TestUserGroupHandler_AddMember(t *testing.T) { mockSvc := new(MockUserGroupService) h := NewUserGroupHandler(mockSvc) app := fiber.New() app.Post("/user-groups/:id/members", h.AddMember) groupID := "g1" userID := "u1" body, _ := json.Marshal(map[string]string{"userId": userID}) mockSvc.On("AddMember", mock.Anything, groupID, userID).Return(nil) req := httptest.NewRequest("POST", "/user-groups/g1/members", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") resp, _ := app.Test(req) assert.Equal(t, http.StatusOK, resp.StatusCode) } func TestUserGroupHandler_AssignRole(t *testing.T) { mockSvc := new(MockUserGroupService) h := NewUserGroupHandler(mockSvc) app := fiber.New() app.Post("/user-groups/:id/roles", h.AssignRole) groupID := "g1" targetTenantID := "t2" relation := "manage" body, _ := json.Marshal(map[string]string{"tenantId": targetTenantID, "relation": relation}) mockSvc.On("AssignRoleToTenant", mock.Anything, groupID, targetTenantID, relation).Return(nil) req := httptest.NewRequest("POST", "/user-groups/g1/roles", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") resp, _ := app.Test(req) assert.Equal(t, http.StatusOK, resp.StatusCode) }