package attach import ( "reflect" "strings" "testing" "gocloud.dev/blob/memblob" ) func TestFileTableName(t *testing.T) { if got := (File{}).TableName(); got != "system_files" { t.Fatalf("TableName = %q, want system_files", got) } } func TestFileIsPublicDefaultsTrue(t *testing.T) { unset := File{} if !unset.Public() { t.Fatal("unset IsPublic must be public") } f, ok := reflect.TypeOf(File{}).FieldByName("IsPublic") if !ok { t.Fatal("missing IsPublic") } tag := f.Tag.Get("gorm") if !strings.Contains(tag, "default:true") { t.Fatalf("gorm tag = %q, want default:true", tag) } priv := false if (File{IsPublic: &priv}).Public() { t.Fatal("explicit false must not be public") } pub := true if !(File{IsPublic: &pub}).Public() { t.Fatal("explicit true must be public") } } func TestThumbFileID(t *testing.T) { id, ok := thumbFileID("thumb_42_200_200_0_0_crop.jpg") if !ok || id != 42 { t.Fatalf("thumb id = %d ok=%v, want 42 true", id, ok) } if _, ok := thumbFileID("abc123xyz.jpg"); ok { t.Fatal("original disk_name must not parse as a thumb id") } if _, ok := thumbFileID("thumb_x_200_200_0_0_crop.jpg"); ok { t.Fatal("non-numeric thumb id must be rejected") } } func TestFileSelfRegisters(t *testing.T) { for _, m := range All() { switch m.(type) { case *File, File: return } } t.Fatal("File must self-register via attach.Register") } // WR-05 pin: the force-delete prefix is thumb__ with its trailing // underscore, so ID 4 cannot match thumbs of ID 40/41/42 that share a // partition. "thumb_4_" is not a string prefix of "thumb_42_". func TestDeleteKeysThumbPrefixIsIDDelimited(t *testing.T) { ctx := t.Context() bucket := memblob.OpenBucket(nil) defer bucket.Close() const disk = "abc123xyz000.jpg" part := PartitionDirectory(disk) doomed := []string{ part + disk, part + ThumbFilename(4, 200, 200, 0, 0, "auto", "jpg"), part + ThumbFilename(4, 50, 50, 0, 0, "crop", "jpg"), } survivors := []string{ part + "abc123xyz111.jpg", part + ThumbFilename(40, 200, 200, 0, 0, "auto", "jpg"), part + ThumbFilename(41, 200, 200, 0, 0, "auto", "jpg"), part + ThumbFilename(42, 4, 4, 0, 0, "auto", "jpg"), part + ThumbFilename(14, 200, 200, 0, 0, "auto", "jpg"), } for _, key := range append(append([]string{}, doomed...), survivors...) { if err := bucket.WriteAll(ctx, key, []byte("x"), nil); err != nil { t.Fatal(err) } } if err := DeleteKeys(ctx, bucket, blobKeysFor(File{ID: 4, DiskName: disk})); err != nil { t.Fatal(err) } for _, key := range doomed { if ok, err := bucket.Exists(ctx, key); err != nil || ok { t.Fatalf("%s must be deleted (exists=%v err=%v)", key, ok, err) } } for _, key := range survivors { if ok, err := bucket.Exists(ctx, key); err != nil || !ok { t.Fatalf("%s must survive deleting file 4 (exists=%v err=%v)", key, ok, err) } } }