diff --git a/erc721/server.go b/erc721/server.go index 9fc7592..37e18d1 100644 --- a/erc721/server.go +++ b/erc721/server.go @@ -37,9 +37,9 @@ type MetadataServer struct { // Metadata and Image are responsible for returning a token's metadata and // image, respectively (surprise, surprise!). If Contract is non-nil, the - // token is guaranteed to exist if Metadata/Image is called. Only 200, 404, - // and 500 are allowed as HTTP codes, and these will be propagated to the - // end user. + // token is guaranteed to exist if Metadata/Image is called. Only 200, 400, + // 404 and 500 are allowed as HTTP codes, and these will be propagated to + // the end user. Metadata func(Interface, *TokenID, httprouter.Params) (md *Metadata, httpCode int, err error) Image func(Interface, *TokenID, httprouter.Params) (img io.Reader, contentType string, httpCode int, err error) } @@ -131,6 +131,10 @@ type tokenDataFunc func(Interface, *TokenID, httprouter.Params) (body io.Reader, // tokenDataHandler is a generic handler for any token data, abstracting shared // logic from the metadata and image handlers. func (s *MetadataServer) tokenDataHandler(w http.ResponseWriter, r *http.Request, params httprouter.Params, fnName string, fn tokenDataFunc) error { + if fn == nil { + return errorf(400, "unsupported method %s", fnName) + } + id, err := s.tokenID(params) if err != nil { return errorf(500, "%T.tokenID(%+v): %v", s, params, err) @@ -146,7 +150,7 @@ func (s *MetadataServer) tokenDataHandler(w http.ResponseWriter, r *http.Request switch code { case 200: - case 404, 500: + case 400, 404, 500: return errorf(code, "%s", err) default: return errorf(500, "unsupported code %d returned by %s(%s)", code, fnName, id) diff --git a/erc721/server_test.go b/erc721/server_test.go index a06bf73..0a63d6d 100644 --- a/erc721/server_test.go +++ b/erc721/server_test.go @@ -79,15 +79,22 @@ func TestMetadataServer(t *testing.T) { ) tests := []struct { - Name string - ExternalImageURL string + Name string + ExternalImageURL string + Image func(_ Interface, id *TokenID, params httprouter.Params) (io.Reader, string, int, error) + wantInternalImageCode int }{ { Name: "Internal images", + Image: func(_ Interface, id *TokenID, params httprouter.Params) (io.Reader, string, int, error) { + return strings.NewReader(fmt.Sprintf("Image %s", id)), imageType, 200, nil + }, + wantInternalImageCode: 200, }, { - Name: "External images", - ExternalImageURL: "http://foo.bar", + Name: "External images", + ExternalImageURL: "http://foo.bar", + wantInternalImageCode: 400, }, } @@ -108,15 +115,17 @@ func TestMetadataServer(t *testing.T) { return &md, 200, nil }, - Image: func(_ Interface, id *TokenID, params httprouter.Params) (io.Reader, string, int, error) { - return strings.NewReader(fmt.Sprintf("Image %s", id)), imageType, 200, nil - }, + Image: tt.Image, } baseURL, get := start(t, srv) tokenURL := func(id int) string { // Note the use of %x as we set TokenIDBase to 16. return fmt.Sprintf("%s/metadata/%x", baseURL, id) } + internalImageURL := func(id int) string { + // Note the use of %x as we set TokenIDBase to 16. + return fmt.Sprintf("%s/image/%x", baseURL, id) + } for id := 0; id < totalSupply; id++ { t.Run(fmt.Sprintf("token %d", id), func(t *testing.T) { @@ -191,6 +200,15 @@ func TestMetadataServer(t *testing.T) { } }) }) + + t.Run("internal image code", func(t *testing.T) { + path := internalImageURL(id) + resp := get(t, path) + if got, want := resp.StatusCode, tt.wantInternalImageCode; got != want { + t.Errorf("HTTP GET %q: got code %v, want %v", path, got, want) + } + }) + }) } diff --git a/package.json b/package.json index 905cb51..46c75bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@divergencetech/ethier", - "version": "0.40.0", + "version": "0.40.1", "description": "Golang and Solidity SDK to make Ethereum development ethier", "main": "\"\"", "scripts": {