diff --git a/object.go b/object.go index 5965829..a3c58fa 100644 --- a/object.go +++ b/object.go @@ -87,6 +87,13 @@ func (o *Object) Unmarshal(objType string, target interface{}) (err SendableErro // to match the request method type. func (o *Object) Prepare(r *http.Request) (*Response, SendableError) { + if len(o.ID) == 0 { + return nil, SpecificationError("ID must be set for Object response") + } + + if len(o.Type) == 0 { + return nil, SpecificationError("Type must be set for Object response") + } var status int switch r.Method { diff --git a/parse.go b/request.go similarity index 70% rename from parse.go rename to request.go index 98b0440..7201423 100644 --- a/parse.go +++ b/request.go @@ -7,6 +7,9 @@ import ( "io/ioutil" "log" "net/http" + "net/url" + "strconv" + "strings" ) const ( @@ -138,3 +141,43 @@ func validateRequest(r *http.Request) SendableError { return nil } + +// NewObjectRequest allows you to create a formatted request that can be used with an +// http.Client or for testing +func NewObjectRequest(method string, baseURL *url.URL, object *Object) (*http.Request, error) { + + switch method { + case "PATCH": + case "DELETE": + baseURL.Path = strings.Join([]string{object.Type, object.ID}, "/") + break + case "POST": + break + default: + return nil, SpecificationError(fmt.Sprintf( + "Cannot use HTTP method ''%s' for a JSON Request", method, + )) + } + + request, err := http.NewRequest(method, baseURL.String(), nil) + if err != nil { + return nil, fmt.Errorf("Error creating new HTTP request: %s", err.Error()) + } + + // use Prepare to generate a payload + payload, err := object.Prepare(request) + if err != nil { + return nil, fmt.Errorf("Error preparing object: %s", err.Error()) + } + + content, jsonErr := json.MarshalIndent(payload, "", " ") + if jsonErr != nil { + return nil, fmt.Errorf("Unable to prepare JSON content: %s", jsonErr) + } + + request.Header.Add("Content-Type", ContentType) + request.Header.Set("Content-Length", strconv.Itoa(len(content))) + request.Body = createIOCloser(content) + + return request, nil +} diff --git a/parse_test.go b/request_test.go similarity index 81% rename from parse_test.go rename to request_test.go index 2042e00..c2c8e62 100644 --- a/parse_test.go +++ b/request_test.go @@ -3,6 +3,7 @@ package jsh import ( "encoding/json" "net/http" + "net/url" "testing" . "github.com/smartystreets/goconvey/convey" @@ -108,5 +109,29 @@ func TestParsing(t *testing.T) { So(vErr.Source.Pointer, ShouldEqual, "data/attributes/id") }) }) + + Convey("->NewObjectRequest()", func() { + + Convey("should create a valid HTTP request", func() { + url := &url.URL{Host: "test123"} + obj := &Object{ID: "test123", Type: "obj"} + req, err := NewObjectRequest("POST", url, obj) + + So(err, ShouldBeNil) + So(req.Method, ShouldEqual, "POST") + So(req.URL, ShouldResemble, url) + }) + + Convey("should error for invalid HTTP methods", func() { + url := &url.URL{} + obj := &Object{} + _, err := NewObjectRequest("PUT", url, obj) + So(err, ShouldNotBeNil) + + singleErr, ok := err.(*Error) + So(ok, ShouldBeTrue) + So(singleErr.Status, ShouldEqual, http.StatusNotAcceptable) + }) + }) }) } diff --git a/response.go b/response.go index 9cba63c..f8603ae 100644 --- a/response.go +++ b/response.go @@ -89,7 +89,7 @@ func SendResponse(w http.ResponseWriter, r *http.Request, response *Response) { content, jsonErr := json.MarshalIndent(response, "", " ") if jsonErr != nil { - log.Printf("Unable to prepare payload JSON: %s", jsonErr) + log.Printf("Unable to prepare JSON content: %s", jsonErr) http.Error(w, DefaultErrorTitle, http.StatusInternalServerError) }