Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion clients/ipfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
"time"

Expand Down Expand Up @@ -101,10 +103,19 @@ func (p *pinataClient) PinContent(ctx context.Context, filename, fileContentType
}

func (p *pinataClient) Unpin(ctx context.Context, cid string) error {
return p.DoRequest(ctx, Request{
err := p.DoRequest(ctx, Request{
Method: "DELETE",
URL: "/pinning/unpin/" + cid,
}, nil)
if err != nil {
var httpErr *HTTPStatusError
if errors.As(err, &httpErr) && httpErr.Status == http.StatusBadRequest &&
strings.Contains(httpErr.Body, "CURRENT_USER_HAS_NOT_PINNED_CID") {
glog.Warningf("IPFS CID %s not pinned by current account, skipping unpin", cid)
return nil
}
}
return err
}

func (p *pinataClient) List(ctx context.Context, pageSize, pageOffset int) (pl *PinList, next int, err error) {
Expand Down
73 changes: 73 additions & 0 deletions clients/ipfs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package clients

import (
"context"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/require"
)

func TestPinataUnpin_NotPinnedByCurrentUser(t *testing.T) {
// Simulate Pinata returning CURRENT_USER_HAS_NOT_PINNED_CID on DELETE
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write([]byte(`{"error":{"reason":"CURRENT_USER_HAS_NOT_PINNED_CID","details":"The current user has not pinned the cid: bafkrei123","message":"The current user has not pinned the cid: bafkrei123"}}`))
}))
defer srv.Close()

client := &pinataClient{
BaseClient: BaseClient{
BaseUrl: srv.URL,
BaseHeaders: map[string]string{
"Authorization": "Bearer test-jwt",
},
},
}

err := client.Unpin(context.Background(), "bafkrei123")
require.NoError(t, err, "Unpin should not return an error when CID is not pinned by current user")
}

func TestPinataUnpin_OtherError(t *testing.T) {
// Simulate a different 400 error (not CURRENT_USER_HAS_NOT_PINNED_CID)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
_, _ = w.Write([]byte(`{"error":{"reason":"SOME_OTHER_ERROR","message":"Something else went wrong"}}`))
}))
defer srv.Close()

client := &pinataClient{
BaseClient: BaseClient{
BaseUrl: srv.URL,
BaseHeaders: map[string]string{
"Authorization": "Bearer test-jwt",
},
},
}

err := client.Unpin(context.Background(), "bafkrei123")
require.Error(t, err, "Unpin should return an error for other HTTP 400 errors")
}

func TestPinataUnpin_Success(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
defer srv.Close()

client := &pinataClient{
BaseClient: BaseClient{
BaseUrl: srv.URL,
BaseHeaders: map[string]string{
"Authorization": "Bearer test-jwt",
},
},
}

err := client.Unpin(context.Background(), "bafkrei123")
require.NoError(t, err, "Unpin should succeed on 200")
}
Loading