package persistence import ( "context" "fmt" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.yandata.net/iod/iod/go-trustlog/api/logger" "go.yandata.net/iod/iod/go-trustlog/api/model" ) func TestOperationRepository_Query(t *testing.T) { ctx := context.Background() log := logger.NewNopLogger() db := setupTestDB(t) defer db.Close() repo := NewOperationRepository(db, log) // 准备测试数据 now := time.Now() testOps := []struct { opID string opSource string opType string status TrustlogStatus time time.Time }{ {"op-001", "DOIP", "Create", StatusNotTrustlogged, now.Add(-3 * time.Hour)}, {"op-002", "DOIP", "Update", StatusTrustlogged, now.Add(-2 * time.Hour)}, {"op-003", "IRP", "Create", StatusNotTrustlogged, now.Add(-1 * time.Hour)}, {"op-004", "IRP", "Delete", StatusTrustlogged, now}, } for _, testOp := range testOps { op := createTestOperation(t, testOp.opID) op.OpSource = model.Source(testOp.opSource) op.OpType = testOp.opType op.Timestamp = testOp.time err := repo.Save(ctx, op, testOp.status) require.NoError(t, err) } t.Run("Query all operations", func(t *testing.T) { req := &OperationQueryRequest{ PageSize: 10, PageNumber: 1, } result, err := repo.Query(ctx, req) require.NoError(t, err) assert.NotNil(t, result) assert.Equal(t, int64(4), result.Total) assert.Len(t, result.Operations, 4) assert.Len(t, result.Statuses, 4) }) t.Run("Query by OpSource", func(t *testing.T) { opSource := "DOIP" req := &OperationQueryRequest{ OpSource: &opSource, PageSize: 10, PageNumber: 1, } result, err := repo.Query(ctx, req) require.NoError(t, err) assert.Equal(t, int64(2), result.Total) assert.Len(t, result.Operations, 2) for _, op := range result.Operations { assert.Equal(t, "DOIP", string(op.OpSource)) } }) t.Run("Query by OpType", func(t *testing.T) { opType := "Create" req := &OperationQueryRequest{ OpType: &opType, PageSize: 10, PageNumber: 1, } result, err := repo.Query(ctx, req) require.NoError(t, err) assert.Equal(t, int64(2), result.Total) }) t.Run("Query by TrustlogStatus", func(t *testing.T) { status := StatusNotTrustlogged req := &OperationQueryRequest{ TrustlogStatus: &status, PageSize: 10, PageNumber: 1, } result, err := repo.Query(ctx, req) require.NoError(t, err) assert.Equal(t, int64(2), result.Total) for _, s := range result.Statuses { assert.Equal(t, StatusNotTrustlogged, s) } }) t.Run("Query with time range", func(t *testing.T) { timeFrom := now.Add(-2*time.Hour - 30*time.Minute) timeTo := now.Add(-30 * time.Minute) req := &OperationQueryRequest{ TimeFrom: &timeFrom, TimeTo: &timeTo, PageSize: 10, PageNumber: 1, } result, err := repo.Query(ctx, req) require.NoError(t, err) assert.True(t, result.Total >= 2) // 应该包含 op-002 和 op-003 }) t.Run("Query with pagination", func(t *testing.T) { req := &OperationQueryRequest{ PageSize: 2, PageNumber: 1, } result, err := repo.Query(ctx, req) require.NoError(t, err) assert.Equal(t, int64(4), result.Total) assert.Len(t, result.Operations, 2) assert.Equal(t, 2, result.TotalPages) // 查询第二页 req.PageNumber = 2 result, err = repo.Query(ctx, req) require.NoError(t, err) assert.Len(t, result.Operations, 2) }) t.Run("Query with ordering DESC", func(t *testing.T) { req := &OperationQueryRequest{ PageSize: 10, PageNumber: 1, OrderBy: "timestamp", OrderDesc: true, } result, err := repo.Query(ctx, req) require.NoError(t, err) assert.Len(t, result.Operations, 4) // 验证降序排列 for i := 1; i < len(result.Operations); i++ { // 后面的时间应该早于或等于前面的时间 assert.True(t, result.Operations[i].Timestamp.Before(result.Operations[i-1].Timestamp) || result.Operations[i].Timestamp.Equal(result.Operations[i-1].Timestamp)) } }) t.Run("Query by OpID", func(t *testing.T) { opID := "op-001" req := &OperationQueryRequest{ OpID: &opID, PageSize: 10, PageNumber: 1, } result, err := repo.Query(ctx, req) require.NoError(t, err) assert.Equal(t, int64(1), result.Total) assert.Len(t, result.Operations, 1) assert.Equal(t, "op-001", result.Operations[0].OpID) }) t.Run("Query with Doid LIKE", func(t *testing.T) { doid := "test-repo" req := &OperationQueryRequest{ Doid: &doid, PageSize: 10, PageNumber: 1, } result, err := repo.Query(ctx, req) require.NoError(t, err) assert.True(t, result.Total >= 4) // 所有记录的 doid 都包含 "test-repo" }) } func TestOperationRepository_Count(t *testing.T) { ctx := context.Background() log := logger.NewNopLogger() db := setupTestDB(t) defer db.Close() repo := NewOperationRepository(db, log) // 准备测试数据 for i := 0; i < 5; i++ { op := createTestOperation(t, fmt.Sprintf("count-op-%d", i)) status := StatusNotTrustlogged if i%2 == 0 { status = StatusTrustlogged } err := repo.Save(ctx, op, status) require.NoError(t, err) } t.Run("Count all", func(t *testing.T) { req := &OperationQueryRequest{} count, err := repo.Count(ctx, req) require.NoError(t, err) assert.True(t, count >= 5) }) t.Run("Count by status", func(t *testing.T) { status := StatusTrustlogged req := &OperationQueryRequest{ TrustlogStatus: &status, } count, err := repo.Count(ctx, req) require.NoError(t, err) assert.True(t, count >= 3) // i=0,2,4 三条记录 }) } func TestPersistenceClient_QueryOperations(t *testing.T) { if testing.Short() { t.Skip("Skipping integration test in short mode") } ctx := context.Background() log := logger.NewNopLogger() db := setupTestDB(t) defer db.Close() // 初始化 PersistenceManager config := PersistenceConfig{ Strategy: StrategyDBOnly, } manager := NewPersistenceManager(db, config, log) defer manager.Close() // 创建 PersistenceClient client := &PersistenceClient{ manager: manager, logger: log, } // 准备测试数据 for i := 0; i < 3; i++ { op := createTestOperation(t, fmt.Sprintf("client-op-%d", i)) err := manager.GetOperationRepo().Save(ctx, op, StatusNotTrustlogged) require.NoError(t, err) } t.Run("QueryOperations", func(t *testing.T) { req := &OperationQueryRequest{ PageSize: 10, PageNumber: 1, } result, err := client.QueryOperations(ctx, req) require.NoError(t, err) assert.NotNil(t, result) assert.True(t, result.Total >= 3) }) t.Run("CountOperations", func(t *testing.T) { req := &OperationQueryRequest{} count, err := client.CountOperations(ctx, req) require.NoError(t, err) assert.True(t, count >= 3) }) t.Run("GetOperationByID", func(t *testing.T) { op, status, err := client.GetOperationByID(ctx, "client-op-0") require.NoError(t, err) assert.NotNil(t, op) assert.Equal(t, "client-op-0", op.OpID) assert.Equal(t, StatusNotTrustlogged, status) }) }