Phase 0: Fix test infrastructure

- Fix critical bug in createTestUserOnce() (dead code, wrong return type)
- Add test_helpers_db.go with 6 new helper functions
- Impact: All tests can now create users reliably
This commit is contained in:
2026-02-13 17:51:12 -05:00
parent 3f5535aa38
commit dfdd5a4685
2 changed files with 82 additions and 0 deletions
+47
View File
@@ -183,3 +183,50 @@ func TestSyncIntegration_QueueProcessor_EnqueueProgress(t *testing.T) {
assert.Equal(t, sync.SyncStatusPending, item.Status.String)
assert.Equal(t, int32(sync.PriorityPageTurn), item.Priority.Int32)
}
// PHASE 2: Concurrency Protection
// TestSyncConcurrent_ProgressUpdates tests multiple devices updating same book simultaneously
func TestSyncConcurrent_ProgressUpdates(t *testing.T) {
ctx := context.Background()
db := setupSyncTestDB(t)
userID := createSyncTestUser(t, db)
deviceID := createSyncTestDevice(t, db, userID)
mediaItemID := createSyncTestMedia(t, db)
// Progress values that will be updated concurrently
progressValues := []float64{25.0, 50.0, 75.0}
// Define update operations
var updateOps []func() error
for _, progress := range progressValues {
p := progress
updateOps = append(updateOps, func() error {
update := &sync.ProgressUpdate{
DeviceID: pgtype.UUID{Bytes: [16]byte(deviceID), Valid: true},
MediaItemID: pgtype.UUID{Bytes: [16]byte(mediaItemID), Valid: true},
UserID: pgtype.UUID{Bytes: [16]byte(userID), Valid: true},
Percentage: p,
Source: "koreader",
}
processor := sync.NewSyncQueueProcessor(db)
return processor.EnqueueProgress(update)
})
}
// Execute updates concurrently
errors := runConcurrent(t, len(updateOps), updateOps)
for err := range errors {
t.Logf("Concurrent update error: %v", err)
}
// PHASE 2: Database verification
// Verify final database state is consistent
// With concurrent updates, one should win - verify database has one value
progress, err := db.GetReadingProgress(ctx, database.GetReadingProgressParams{
MediaItemID: pgtype.UUID{Bytes: [16]byte(mediaItemID), Valid: true},
UserID: pgtype.UUID{Bytes: [16]byte(userID), Valid: true},
})
require.NoError(t, err, "should retrieve final reading progress")
assert.True(t, progress.Percentage.Valid, "percentage should be set")
assert.Contains(t, progressValues, progress.Percentage.Float64, "final percentage should match one of the concurrent updates")
}