package repository import ( "context" "fmt" "testing" "time" "code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/entity" "code.30cm.net/digimon/app-cloudep-permission-server/pkg/domain/repository" mgo "code.30cm.net/digimon/library-go/mongo" "github.com/stretchr/testify/assert" "go.mongodb.org/mongo-driver/bson/primitive" ) func SetupTestUserRoleRepository(db string) (repository.UserRoleRepository, func(), error) { h, p, tearDown, err := startMongoContainer() if err != nil { return nil, nil, err } conf := &mgo.Conf{ Schema: Schema, Host: fmt.Sprintf("%s:%s", h, p), Database: db, MaxStaleness: 300, MaxPoolSize: 100, MinPoolSize: 100, MaxConnIdleTime: 300, Compressors: []string{}, EnableStandardReadWriteSplitMode: false, ConnectTimeoutMs: 3000, } param := UserRoleRepositoryParam{ Conf: conf, } repo := NewUserRoleRepository(param) _, _ = repo.Index20250225UP(context.Background()) return repo, tearDown, nil } func TestUserRoleRepository_CreateUserRole(t *testing.T) { repo, tearDown, err := SetupTestUserRoleRepository("testDB") assert.NoError(t, err) defer tearDown() testCases := []struct { name string input entity.UserRole expectErr bool }{ { name: "成功新增使用者角色", input: entity.UserRole{ UID: "user_123", RoleID: "role_456", }, expectErr: false, }, { name: "異常:無效的輸入", input: entity.UserRole{ RoleID: "role_456", }, expectErr: true, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { err := repo.CreateUserRole(context.Background(), tc.input) if tc.expectErr { assert.Error(t, err, "應該返回錯誤") } else { assert.NoError(t, err, "不應該返回錯誤") // 檢查資料是否真的被插入 var inserted entity.UserRole inserted, err = repo.GetByUserID(context.Background(), tc.input.UID) assert.NoError(t, err, "應該能找到插入的資料") assert.Equal(t, tc.input.UID, inserted.UID, "UID 應該匹配") assert.Equal(t, tc.input.RoleID, inserted.RoleID, "RoleID 應該匹配") assert.NotZero(t, inserted.CreateAt, "CreateAt 應該被設定") assert.NotZero(t, inserted.UpdateAt, "UpdateAt 應該被設定") } }) } } func TestUserRoleRepository_UpdateUserRole(t *testing.T) { repo, tearDown, err := SetupTestUserRoleRepository("testDB") assert.NoError(t, err) defer tearDown() // 先插入測試數據 existingUserRole := entity.UserRole{ ID: primitive.NewObjectID(), UID: "user_123", RoleID: "role_123", CreateAt: time.Now().UTC().UnixNano(), UpdateAt: time.Now().UTC().UnixNano(), } err = repo.CreateUserRole(context.Background(), existingUserRole) assert.NoError(t, err, "初始化數據應該成功") testCases := []struct { name string uid string newRoleID string expectErr bool expectedRole string }{ { name: "成功更新使用者角色", uid: "user_123", newRoleID: "role_456", expectErr: false, expectedRole: "role_456", }, { name: "異常:更新的 UID 不存在", uid: "non_existent_user", newRoleID: "role_789", expectErr: true, expectedRole: "", }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { _, err = repo.UpdateUserRole(context.Background(), tc.uid, tc.newRoleID) if tc.expectErr { assert.Error(t, err, "應該返回錯誤") } else { assert.NoError(t, err, "不應該返回錯誤") // 檢查資料是否真的被更新 found, err := repo.GetByUserID(context.Background(), tc.uid) assert.NoError(t, err, "應該能找到更新後的資料") assert.Equal(t, tc.expectedRole, found.RoleID, "RoleID 應該匹配更新的值") assert.NotZero(t, found.UpdateAt, "UpdateAt 應該被更新") } }) } } func TestUserRoleRepository_CountUsersByRole(t *testing.T) { repo, tearDown, err := SetupTestUserRoleRepository("testDB") assert.NoError(t, err) defer tearDown() // 先插入測試數據 testUsers := []entity.UserRole{ {ID: primitive.NewObjectID(), UID: "user_1", RoleID: "role_admin"}, {ID: primitive.NewObjectID(), UID: "user_2", RoleID: "role_admin"}, {ID: primitive.NewObjectID(), UID: "user_3", RoleID: "role_user"}, {ID: primitive.NewObjectID(), UID: "user_4", RoleID: "role_user"}, {ID: primitive.NewObjectID(), UID: "user_5", RoleID: "role_user"}, } for _, user := range testUsers { err := repo.CreateUserRole(context.Background(), user) assert.NoError(t, err, "應該成功插入測試數據") } testCases := []struct { name string expectedData []repository.RoleUserCount expectErr bool }{ { name: "成功統計角色使用者數量", expectedData: []repository.RoleUserCount{ {RoleID: "role_admin", Count: 2}, {RoleID: "role_user", Count: 3}, }, expectErr: false, }, //{ // name: "無資料時回傳空結果", // expectedData: []repository.RoleUserCount{}, // expectErr: false, //}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { result, err := repo.CountUsersByRole(context.Background()) if tc.expectErr { assert.Error(t, err, "應該返回錯誤") } else { assert.NoError(t, err, "不應該返回錯誤") assert.ElementsMatch(t, tc.expectedData, result, "結果應該匹配預期的使用者數量統計") } }) } } // TestUserRoleRepository_GetUsersByRoleID 測試 GetUsersByRoleID 查詢指定 RoleID 的使用者 func TestUserRoleRepository_GetUsersByRoleID(t *testing.T) { repo, tearDown, err := SetupTestUserRoleRepository("testDB") assert.NoError(t, err) defer tearDown() // 插入測試數據 testUsers := []entity.UserRole{ {ID: primitive.NewObjectID(), UID: "user_1", RoleID: "role_admin"}, {ID: primitive.NewObjectID(), UID: "user_2", RoleID: "role_admin"}, {ID: primitive.NewObjectID(), UID: "user_3", RoleID: "role_user"}, {ID: primitive.NewObjectID(), UID: "user_4", RoleID: "role_user"}, {ID: primitive.NewObjectID(), UID: "user_5", RoleID: "role_user"}, } for _, user := range testUsers { err := repo.CreateUserRole(context.Background(), user) assert.NoError(t, err, "應該成功插入測試數據") } // 測試案例 testCases := []struct { name string roleID string expectedData []entity.UserRole expectErr bool }{ { name: "成功查詢 role_admin 的使用者", roleID: "role_admin", expectedData: []entity.UserRole{ {UID: "user_1", RoleID: "role_admin"}, {UID: "user_2", RoleID: "role_admin"}, }, expectErr: false, }, { name: "成功查詢 role_user 的使用者", roleID: "role_user", expectedData: []entity.UserRole{ {UID: "user_3", RoleID: "role_user"}, {UID: "user_4", RoleID: "role_user"}, {UID: "user_5", RoleID: "role_user"}, }, expectErr: false, }, { name: "查詢 role_guest,應回傳空陣列", roleID: "role_guest", expectedData: []entity.UserRole{}, expectErr: false, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { result, err := repo.GetUsersByRoleID(context.Background(), tc.roleID) if tc.expectErr { assert.Error(t, err, "應該返回錯誤") } else { assert.NoError(t, err, "不應該返回錯誤") compute := make([]entity.UserRole, 0, len(result)) res := make([]entity.UserRole, 0, len(result)) for _, item := range result { compute = append(compute, entity.UserRole{ RoleID: item.RoleID, UID: item.UID, }) } for _, item := range tc.expectedData { res = append(res, entity.UserRole{ RoleID: item.RoleID, UID: item.UID, }) } assert.ElementsMatch(t, compute, res, "結果應該匹配預期的使用者列表") } }) } } // TestUserRoleRepository_GetAll 測試 GetAll 取得所有使用者角色 func TestUserRoleRepository_GetAll(t *testing.T) { repo, tearDown, err := SetupTestUserRoleRepository("testDB") assert.NoError(t, err) defer tearDown() // 插入測試數據 testUsers := []entity.UserRole{ {ID: primitive.NewObjectID(), UID: "user_1", RoleID: "role_admin"}, {ID: primitive.NewObjectID(), UID: "user_2", RoleID: "role_editor"}, {ID: primitive.NewObjectID(), UID: "user_3", RoleID: "role_viewer"}, } for _, user := range testUsers { err := repo.CreateUserRole(context.Background(), user) assert.NoError(t, err, "應該成功插入測試數據") } // 測試案例 testCases := []struct { name string expectedData []*entity.UserRole expectErr bool }{ { name: "成功獲取所有使用者角色", expectedData: []*entity.UserRole{ {UID: "user_1", RoleID: "role_admin"}, {UID: "user_2", RoleID: "role_editor"}, {UID: "user_3", RoleID: "role_viewer"}, }, expectErr: false, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { result, err := repo.GetAll(context.Background()) if tc.expectErr { assert.Error(t, err, "應該返回錯誤") } else { assert.NoError(t, err, "不應該返回錯誤") assert.Len(t, result, len(tc.expectedData), "結果應該包含正確數量的使用者角色") //assert.ElementsMatch(t, tc.expectedData, result, "結果應該匹配預期的使用者角色") } }) } }