package db import ( "context" "testing" "github.com/stretchr/testify/require" "gorm.io/gorm" ) func uploadImageCount(t *testing.T, conn *gorm.DB, id uint) int64 { t.Helper() var count int64 require.NoError(t, conn.Unscoped().Model(&UploadImage{}).Where("id = ?", id).Count(&count).Error) return count } func TestUploadImagesDeleteByQuestionIDOutbox(t *testing.T) { setR2TestConfig(t) conn, _ := newTestDB(t) ctx := context.Background() images := NewUploadImagesStore(conn) tasks := NewR2DeleteTaskStore(conn) first, err := images.Create(ctx, CreateUploadImageOptions{QuestionID: 1, Key: "unique.webp"}) require.NoError(t, err) duplicate, err := images.Create(ctx, CreateUploadImageOptions{QuestionID: 1, Key: "unique.webp"}) require.NoError(t, err) shared, err := images.Create(ctx, CreateUploadImageOptions{QuestionID: 1, Key: "shared.webp"}) require.NoError(t, err) require.NoError(t, conn.WithContext(ctx).Create(&UploadImageQuestion{ UploadImageID: shared.ID, QuestionID: 2, }).Error) require.NoError(t, images.DeleteByQuestionID(ctx, 1)) require.Zero(t, uploadImageCount(t, conn, first.ID)) require.Zero(t, uploadImageCount(t, conn, duplicate.ID)) require.Equal(t, int64(1), uploadImageCount(t, conn, shared.ID)) due, err := tasks.ListDue(ctx, 10) require.NoError(t, err) require.Len(t, due, 1, "重复 key 必须去重,共享主体不得入队") require.Equal(t, "unique.webp", due[0].Key) require.NoError(t, images.DeleteByQuestionID(ctx, 2)) require.Zero(t, uploadImageCount(t, conn, shared.ID)) due, err = tasks.ListDue(ctx, 10) require.NoError(t, err) require.Len(t, due, 2) require.ElementsMatch(t, []string{"unique.webp", "shared.webp"}, []string{due[0].Key, due[1].Key}) } func TestUploadImagesReplaceDeletesOnlyOrphanedPrevious(t *testing.T) { setR2TestConfig(t) conn, _ := newTestDB(t) ctx := context.Background() images := NewUploadImagesStore(conn) tasks := NewR2DeleteTaskStore(conn) old, err := images.Create(ctx, CreateUploadImageOptions{ Type: UploadImageQuestionTypeAnswer, QuestionID: 10, Key: "old.webp", }) require.NoError(t, err) shared, err := images.Create(ctx, CreateUploadImageOptions{ Type: UploadImageQuestionTypeAnswer, QuestionID: 10, Key: "shared-old.webp", }) require.NoError(t, err) require.NoError(t, conn.WithContext(ctx).Create(&UploadImageQuestion{ Type: UploadImageQuestionTypeAnswer, UploadImageID: shared.ID, QuestionID: 11, }).Error) newImage, err := images.Create(ctx, CreateUploadImageOptions{ Type: UploadImageQuestionTypeAnswer, QuestionID: 10, Key: "new.webp", IsDeletingPrevious: true, }) require.NoError(t, err) require.Zero(t, uploadImageCount(t, conn, old.ID)) require.Equal(t, int64(1), uploadImageCount(t, conn, shared.ID)) require.Equal(t, int64(1), uploadImageCount(t, conn, newImage.ID)) due, err := tasks.ListDue(ctx, 10) require.NoError(t, err) require.Len(t, due, 1) require.Equal(t, "old.webp", due[0].Key) require.NotEqual(t, newImage.Key, due[0].Key) }