package usecase import ( "backend/pkg/permission/domain/entity" "backend/pkg/permission/domain/permission" mockRepo "backend/pkg/permission/mock/repository" "context" "errors" "testing" "github.com/stretchr/testify/assert" "go.mongodb.org/mongo-driver/v2/bson" "go.uber.org/mock/gomock" ) func TestPermissionUseCase_GetAll(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockPermRepo := mockRepo.NewMockPermissionRepository(mockCtrl) uc := NewPermissionUseCase(PermissionUseCaseParam{ PermRepo: mockPermRepo, }) ctx := context.Background() tests := []struct { name string mockSetup func() wantCount int wantErr bool }{ { name: "成功獲取所有權限", mockSetup: func() { perms := []*entity.Permission{ {ID: bson.NewObjectID(), Name: "user.list", State: permission.RecordActive}, {ID: bson.NewObjectID(), Name: "user.create", State: permission.RecordActive}, } mockPermRepo.EXPECT().ListActive(ctx).Return(perms, nil) }, wantCount: 2, wantErr: false, }, { name: "沒有權限", mockSetup: func() { mockPermRepo.EXPECT().ListActive(ctx).Return([]*entity.Permission{}, nil) }, wantCount: 0, wantErr: false, }, { name: "Repository 錯誤", mockSetup: func() { mockPermRepo.EXPECT().ListActive(ctx).Return(nil, errors.New("db error")) }, wantCount: 0, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.mockSetup() result, err := uc.GetAll(ctx) if tt.wantErr { assert.Error(t, err) } else { assert.NoError(t, err) assert.Len(t, result, tt.wantCount) } }) } } func TestPermissionUseCase_GetTree(t *testing.T) { ctx := context.Background() tests := []struct { name string mockSetup func(*mockRepo.MockPermissionRepository) wantErr bool }{ { name: "成功獲取權限樹", mockSetup: func(mockPermRepo *mockRepo.MockPermissionRepository) { perms := []*entity.Permission{ { ID: bson.NewObjectID(), Name: "user", State: permission.RecordActive, ParentID: bson.ObjectID{}, }, { ID: bson.NewObjectID(), Name: "user.list", State: permission.RecordActive, ParentID: bson.NewObjectID(), }, } mockPermRepo.EXPECT().ListActive(ctx).Return(perms, nil) }, wantErr: false, }, { name: "Repository 錯誤", mockSetup: func(mockPermRepo *mockRepo.MockPermissionRepository) { mockPermRepo.EXPECT().ListActive(ctx).Return(nil, errors.New("db error")) }, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // 為每個測試案例創建新的 mock controller 和 usecase 實例,避免快取問題 mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockPermRepo := mockRepo.NewMockPermissionRepository(mockCtrl) tt.mockSetup(mockPermRepo) uc := NewPermissionUseCase(PermissionUseCaseParam{ PermRepo: mockPermRepo, }) result, err := uc.GetTree(ctx) if tt.wantErr { assert.Error(t, err) } else { assert.NoError(t, err) assert.NotNil(t, result) } }) } } func TestPermissionUseCase_GetByHTTP(t *testing.T) { mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockPermRepo := mockRepo.NewMockPermissionRepository(mockCtrl) uc := NewPermissionUseCase(PermissionUseCaseParam{ PermRepo: mockPermRepo, }) ctx := context.Background() tests := []struct { name string path string method string mockSetup func() wantNil bool wantErr bool }{ { name: "成功找到權限", path: "/api/users", method: "GET", mockSetup: func() { perm := &entity.Permission{ ID: bson.NewObjectID(), Name: "user.list", HTTPPath: "/api/users", HTTPMethod: "GET", State: permission.RecordActive, } mockPermRepo.EXPECT().FindByHTTP(ctx, "/api/users", "GET").Return(perm, nil) }, wantNil: false, wantErr: false, }, { name: "找不到權限", path: "/api/unknown", method: "POST", mockSetup: func() { mockPermRepo.EXPECT().FindByHTTP(ctx, "/api/unknown", "POST").Return(nil, errors.New("not found")) }, wantNil: true, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.mockSetup() result, err := uc.GetByHTTP(ctx, tt.path, tt.method) if tt.wantErr { assert.Error(t, err) } else { assert.NoError(t, err) } if tt.wantNil { assert.Nil(t, result) } else { assert.NotNil(t, result) } }) } } func TestPermissionUseCase_ExpandPermissions(t *testing.T) { ctx := context.Background() tests := []struct { name string perms permission.Permissions mockSetup func(*mockRepo.MockPermissionRepository) wantCount int wantErr bool }{ { name: "成功展開權限", perms: permission.Permissions{ "user": permission.Open, "user.list": permission.Open, "user.create": permission.Open, }, mockSetup: func(mockPermRepo *mockRepo.MockPermissionRepository) { allPerms := []*entity.Permission{ {ID: bson.NewObjectID(), Name: "user", State: permission.RecordActive}, {ID: bson.NewObjectID(), Name: "user.list", State: permission.RecordActive}, {ID: bson.NewObjectID(), Name: "user.create", State: permission.RecordActive}, } mockPermRepo.EXPECT().ListActive(ctx).Return(allPerms, nil) }, wantCount: 3, wantErr: false, }, { name: "空權限列表", perms: permission.Permissions{}, mockSetup: func(mockPermRepo *mockRepo.MockPermissionRepository) { mockPermRepo.EXPECT().ListActive(ctx).Return([]*entity.Permission{}, nil) }, wantCount: 0, wantErr: false, }, { name: "Repository 錯誤", perms: permission.Permissions{"user": permission.Open}, mockSetup: func(mockPermRepo *mockRepo.MockPermissionRepository) { mockPermRepo.EXPECT().ListActive(ctx).Return(nil, errors.New("db error")) }, wantCount: 0, wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // 為每個測試案例創建新的 mock controller 和 usecase 實例,避免快取問題 mockCtrl := gomock.NewController(t) defer mockCtrl.Finish() mockPermRepo := mockRepo.NewMockPermissionRepository(mockCtrl) tt.mockSetup(mockPermRepo) uc := NewPermissionUseCase(PermissionUseCaseParam{ PermRepo: mockPermRepo, }) result, err := uc.ExpandPermissions(ctx, tt.perms) if tt.wantErr { assert.Error(t, err) } else { assert.NoError(t, err) assert.Len(t, result, tt.wantCount) } }) } } // GetUsersByPermission is not in PermissionRepository interface, skip this test // func TestPermissionUseCase_GetUsersByPermission(t *testing.T) { // mockCtrl := gomock.NewController(t) // defer mockCtrl.Finish() // // mockPermRepo := mockRepo.NewMockPermissionRepository(mockCtrl) // // uc := NewPermissionUseCase(PermissionUseCaseParam{ // PermRepo: mockPermRepo, // }) // ctx := context.Background() // // tests := []struct { // name string // permissionUID string // mockSetup func() // wantCount int // wantErr bool // }{ // { // name: "成功獲取使用者列表", // permissionUID: "perm123", // mockSetup: func() { // mockPermRepo.EXPECT().GetUsersByPermission(ctx, "perm123").Return([]string{"user1", "user2"}, nil) // }, // wantCount: 2, // wantErr: false, // }, // } // // for _, tt := range tests { // t.Run(tt.name, func(t *testing.T) { // tt.mockSetup() // // result, err := uc.GetUsersByPermission(ctx, tt.permissionUID) // // if tt.wantErr { // assert.Error(t, err) // } else { // assert.NoError(t, err) // assert.Len(t, result, tt.wantCount) // } // }) // } // }