package media import ( "bytes" "context" "errors" "io" "strings" "testing" ) func TestLocalSaveOpenDelete(t *testing.T) { ctx := context.Background() store, err := NewLocal(t.TempDir()) if err != nil { t.Fatalf("NewLocal: %v", err) } payload := []byte("hello attachment") if err := store.Save(ctx, "a/b/file.txt", bytes.NewReader(payload)); err != nil { t.Fatalf("Save: %v", err) } rc, err := store.Open(ctx, "a/b/file.txt") if err != nil { t.Fatalf("Open: %v", err) } got, err := io.ReadAll(rc) rc.Close() if err != nil { t.Fatalf("ReadAll: %v", err) } if !bytes.Equal(got, payload) { t.Fatalf("content = %q, want %q", got, payload) } if err := store.Delete(ctx, "a/b/file.txt"); err != nil { t.Fatalf("Delete: %v", err) } if err := store.Delete(ctx, "a/b/file.txt"); err != nil { t.Fatalf("Delete idempotent: %v", err) } if _, err := store.Open(ctx, "a/b/file.txt"); !errors.Is(err, ErrNotFound) { t.Fatalf("Open after delete = %v, want ErrNotFound", err) } } func TestLocalPathTraversalRejected(t *testing.T) { store, err := NewLocal(t.TempDir()) if err != nil { t.Fatalf("NewLocal: %v", err) } err = store.Save(context.Background(), "../../etc/evil", strings.NewReader("x")) if err == nil { t.Fatal("Save with traversal key = nil, want error") } } func TestIsImage(t *testing.T) { cases := map[string]bool{ "image/png": true, "image/jpeg": true, "image/gif": true, "image/webp": true, "application/pdf": false, "text/plain": false, } for ct, want := range cases { if got := IsImage(ct); got != want { t.Errorf("IsImage(%q) = %v, want %v", ct, got, want) } } }