package repository import ( "app-cloudep-member-server/pkg/domain/entity" "app-cloudep-member-server/pkg/domain/repository" "context" "testing" "time" mgo "code.30cm.net/digimon/library-go/mongo" "github.com/alicebob/miniredis/v2" "github.com/stretchr/testify/assert" "github.com/zeromicro/go-zero/core/stores/cache" "github.com/zeromicro/go-zero/core/stores/redis" "go.mongodb.org/mongo-driver/bson/primitive" ) func SetupTestAccountUIDRepository(db string) (repository.AccountUIDRepository, func(), error) { h, p, tearDown, err := startMongoContainer() if err != nil { return nil, nil, err } s, _ := miniredis.Run() conf := &mgo.Conf{ Schema: Schema, Host: h, Port: p, Database: db, MaxStaleness: 300, MaxPoolSize: 100, MinPoolSize: 100, MaxConnIdleTime: 300, Compressors: []string{}, EnableStandardReadWriteSplitMode: false, ConnectTimeoutMs: 3000, } cacheConf := cache.CacheConf{ cache.NodeConf{ RedisConf: redis.RedisConf{ Host: s.Addr(), Type: redis.NodeType, }, Weight: 100, }, } cacheOpts := []cache.Option{ cache.WithExpiry(1000 * time.Microsecond), cache.WithNotFoundExpiry(1000 * time.Microsecond), } param := AccountUIDRepositoryParam{ Conf: conf, CacheConf: cacheConf, CacheOpts: cacheOpts, } repo := NewAccountUIDRepository(param) _, _ = repo.Index20241226001UP(context.Background()) return repo, tearDown, nil } func TestDefaultAccountUidModel_Insert(t *testing.T) { repo, tearDown, err := SetupTestAccountUIDRepository("testDB") defer tearDown() assert.NoError(t, err) tests := []struct { name string accountUid *entity.AccountUID expectError bool }{ { name: "Valid AccountUid insert", accountUid: &entity.AccountUID{ LoginID: "testlogin1", UID: "testuid1", Type: 1, }, expectError: false, }, { name: "Insert with missing UID", accountUid: &entity.AccountUID{ LoginID: "testlogin2", Type: 2, }, expectError: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // 執行插入測試帳戶 UID err := repo.Insert(context.Background(), tt.accountUid) if tt.expectError { assert.Error(t, err, "插入操作應該失敗") } else { assert.NoError(t, err, "插入操作應該成功") // 驗證 ObjectID 和時間戳是否生成 assert.NotZero(t, tt.accountUid.ID, "應生成 ID") assert.NotNil(t, tt.accountUid.CreateAt, "CreateAt 應被設置") assert.NotNil(t, tt.accountUid.UpdateAt, "UpdateAt 應被設置") // 驗證插入的時間是否合理 now := time.Now().UTC().UnixNano() assert.LessOrEqual(t, *tt.accountUid.CreateAt, now, "CreateAt 應在當前時間之前") assert.LessOrEqual(t, *tt.accountUid.UpdateAt, now, "UpdateAt 應在當前時間之前") // 驗證插入的資料是否正確 insertedAccountUid, err := repo.FindOne(context.Background(), tt.accountUid.ID.Hex()) assert.NoError(t, err, "應該可以找到插入的帳號 UID 資料") assert.Equal(t, tt.accountUid.LoginID, insertedAccountUid.LoginID, "LoginID 應相同") assert.Equal(t, tt.accountUid.UID, insertedAccountUid.UID, "UID 應相同") assert.Equal(t, tt.accountUid.Type, insertedAccountUid.Type, "Type 應相同") } }) } } func TestDefaultAccountUidModel_FindOne(t *testing.T) { repo, tearDown, err := SetupTestAccountUIDRepository("testDB") defer tearDown() assert.NoError(t, err) // 準備測試資料 accountUid := &entity.AccountUID{ LoginID: "testlogin", UID: "testuid", Type: 1, } err = repo.Insert(context.Background(), accountUid) assert.NoError(t, err, "應成功插入測試資料") tests := []struct { name string id string expectError bool expectedUID string }{ { name: "Valid FindOne", id: accountUid.ID.Hex(), expectError: false, expectedUID: accountUid.UID, }, { name: "Invalid ObjectID", id: "invalid_id", expectError: true, }, { name: "Non-existent ObjectID", id: primitive.NewObjectID().Hex(), expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result, err := repo.FindOne(context.Background(), tt.id) if tt.expectError { assert.Error(t, err) } else { assert.NoError(t, err) assert.Equal(t, tt.expectedUID, result.UID, "找到的 UID 應符合預期") } }) } } func TestDefaultAccountUidModel_Update(t *testing.T) { repo, tearDown, err := SetupTestAccountUIDRepository("testDB") defer tearDown() assert.NoError(t, err) // 準備測試資料 accountUid := &entity.AccountUID{ LoginID: "testlogin", UID: "testuid", Type: 1, } err = repo.Insert(context.Background(), accountUid) assert.NoError(t, err) updatedUID := "updatedUID" accountUid.UID = updatedUID // 執行更新操作 _, err = repo.Update(context.Background(), accountUid) assert.NoError(t, err, "應成功更新資料") // 確認更新結果 updatedAccountUid, err := repo.FindOne(context.Background(), accountUid.ID.Hex()) assert.NoError(t, err, "應能找到更新後的資料") assert.Equal(t, updatedUID, updatedAccountUid.UID, "更新後的 UID 應符合預期") } func TestDefaultAccountUidModel_Delete(t *testing.T) { repo, tearDown, err := SetupTestAccountUIDRepository("testDB") defer tearDown() assert.NoError(t, err) // 準備測試資料 accountUid := &entity.AccountUID{ LoginID: "testlogin", UID: "testuid", Type: 1, } err = repo.Insert(context.Background(), accountUid) assert.NoError(t, err) // 執行刪除操作 count, err := repo.Delete(context.Background(), accountUid.ID.Hex()) assert.NoError(t, err, "應成功刪除資料") assert.Equal(t, int64(1), count, "刪除數量應為 1") // 確認資料已被刪除 _, err = repo.FindOne(context.Background(), accountUid.ID.Hex()) assert.Error(t, err, "應無法找到已刪除的資料") assert.Equal(t, ErrNotFound, err, "應返回 ErrNotFound 錯誤") } func TestCustomAccountUidModel_FindUIDByLoginID(t *testing.T) { repo, tearDown, err := SetupTestAccountUIDRepository("testDB") defer tearDown() assert.NoError(t, err) // 準備測試資料 accountUid := &entity.AccountUID{ LoginID: "testloginid", UID: "testuid", Type: 1, } err = repo.Insert(context.Background(), accountUid) assert.NoError(t, err, "應成功插入測試資料") tests := []struct { name string loginID string expectError bool expectedUID string }{ { name: "Valid FindUIDByLoginID", loginID: "testloginid", expectError: false, expectedUID: "testuid", }, { name: "Non-existent LoginID", loginID: "nonexistent", expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result, err := repo.FindUIDByLoginID(context.Background(), tt.loginID) if tt.expectError { assert.Error(t, err) assert.Equal(t, ErrNotFound, err, "應返回 ErrNotFound 錯誤") } else { assert.NoError(t, err, "應成功找到符合的記錄") assert.Equal(t, tt.expectedUID, result.UID, "找到的 UID 應符合預期") } }) } }