package storage import ( "context" "io" "os" "strings" "testing" ) func TestSaveAndOpen(t *testing.T) { dir := t.TempDir() store, err := NewLocalStorage(dir) if err != nil { t.Fatalf("NewLocalStorage: %v", err) } ctx := context.Background() content := "hello, mygo storage" written, err := store.Save(ctx, "test/hello.txt", strings.NewReader(content)) if err != nil { t.Fatalf("Save: %v", err) } if written != int64(len(content)) { t.Errorf("written = %d, want %d", written, len(content)) } reader, err := store.Open(ctx, "test/hello.txt") if err != nil { t.Fatalf("Open: %v", err) } defer reader.Close() got, err := io.ReadAll(reader) if err != nil { t.Fatalf("ReadAll: %v", err) } if string(got) != content { t.Errorf("content = %q, want %q", string(got), content) } // Verify the file exists on disk under the base path. expectedPath := dir + "/test/hello.txt" if _, err := os.Stat(expectedPath); err != nil { t.Errorf("file not found on disk at %s: %v", expectedPath, err) } } func TestDelete(t *testing.T) { dir := t.TempDir() store, err := NewLocalStorage(dir) if err != nil { t.Fatalf("NewLocalStorage: %v", err) } ctx := context.Background() _, err = store.Save(ctx, "to_delete.txt", strings.NewReader("delete me")) if err != nil { t.Fatalf("Save: %v", err) } if err := store.Delete(ctx, "to_delete.txt"); err != nil { t.Fatalf("Delete: %v", err) } _, err = store.Open(ctx, "to_delete.txt") if err == nil { t.Error("Open should fail after delete") } } func TestDeleteIdempotent(t *testing.T) { dir := t.TempDir() store, err := NewLocalStorage(dir) if err != nil { t.Fatalf("NewLocalStorage: %v", err) } ctx := context.Background() // Deleting a non-existent file should not error. if err := store.Delete(ctx, "nonexistent.txt"); err != nil { t.Errorf("Delete nonexistent should be idempotent, got: %v", err) } } func TestPathTraversalRejected(t *testing.T) { dir := t.TempDir() store, err := NewLocalStorage(dir) if err != nil { t.Fatalf("NewLocalStorage: %v", err) } ctx := context.Background() _, err = store.Save(ctx, "../escape.txt", strings.NewReader("malicious")) if err == nil { t.Error("Save should reject path traversal") } else if !strings.Contains(err.Error(), "path traversal") { t.Errorf("expected path traversal error, got: %v", err) } _, err = store.Open(ctx, "../escape.txt") if err == nil { t.Error("Open should reject path traversal") } else if !strings.Contains(err.Error(), "path traversal") { t.Errorf("expected path traversal error, got: %v", err) } err = store.Delete(ctx, "../escape.txt") if err == nil { t.Error("Delete should reject path traversal") } else if !strings.Contains(err.Error(), "path traversal") { t.Errorf("expected path traversal error, got: %v", err) } } func TestOpenMissingFile(t *testing.T) { dir := t.TempDir() store, err := NewLocalStorage(dir) if err != nil { t.Fatalf("NewLocalStorage: %v", err) } ctx := context.Background() _, err = store.Open(ctx, "no/such/file.txt") if err == nil { t.Error("Open should error for missing file") } else if !strings.Contains(err.Error(), "not found on disk") { t.Errorf("expected 'not found on disk' error, got: %v", err) } }