diff --git a/CHANGELOG.md b/CHANGELOG.md index eff075f..bc06ef6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +## [0.7.1] - 2022-09-07 + +### Added + +- Added support for additional status codes. + ## [0.7.0] - 2022-08-24 ### Added diff --git a/go.mod b/go.mod index 6ad6ea2..690128f 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( ) require ( - github.com/cjlapao/common-go v0.0.25 // indirect + github.com/cjlapao/common-go v0.0.27 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/uuid v1.3.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index 7152909..f58c068 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/cjlapao/common-go v0.0.25 h1:/a5SdWGtOFzXceM1RnB3v4hgUK8woMo9Ma/XRgCQ87g= github.com/cjlapao/common-go v0.0.25/go.mod h1:OyTAY388jfEj8uaRzx0uYneFghKDLL5KP+ewSydlQ5g= +github.com/cjlapao/common-go v0.0.27 h1:7k8R1Mz2LAudnPb1kaqQ/l+Ba7uL92FG7Rqp9W67mGM= +github.com/cjlapao/common-go v0.0.27/go.mod h1:OyTAY388jfEj8uaRzx0uYneFghKDLL5KP+ewSydlQ5g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -18,5 +20,6 @@ github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zI github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/mock_entity.go b/internal/mock_entity.go new file mode 100644 index 0000000..4e93d99 --- /dev/null +++ b/internal/mock_entity.go @@ -0,0 +1,22 @@ +package internal + +import ( + absser "github.com/microsoft/kiota-abstractions-go/serialization" +) + +type MockEntity struct { +} + +type MockEntityAble interface { + absser.Parsable +} + +func (e *MockEntity) Serialize(writer absser.SerializationWriter) error { + return nil +} +func (e *MockEntity) GetFieldDeserializers() map[string]func(absser.ParseNode) error { + return make(map[string]func(absser.ParseNode) error) +} +func MockEntityFactory(parseNode absser.ParseNode) (absser.Parsable, error) { + return &MockEntity{}, nil +} diff --git a/internal/mock_parse_node_factory.go b/internal/mock_parse_node_factory.go new file mode 100644 index 0000000..51fec66 --- /dev/null +++ b/internal/mock_parse_node_factory.go @@ -0,0 +1,96 @@ +package internal + +import ( + "time" + + "github.com/google/uuid" + absser "github.com/microsoft/kiota-abstractions-go/serialization" +) + +type MockParseNodeFactory struct { +} + +func (e *MockParseNodeFactory) GetValidContentType() (string, error) { + return "application/json", nil +} +func (e *MockParseNodeFactory) GetRootParseNode(contentType string, content []byte) (absser.ParseNode, error) { + return &MockParseNode{}, nil +} + +type MockParseNode struct { +} + +func (e *MockParseNode) GetChildNode(index string) (absser.ParseNode, error) { + return nil, nil +} +func (e *MockParseNode) GetCollectionOfObjectValues(ctor absser.ParsableFactory) ([]absser.Parsable, error) { + return nil, nil +} +func (e *MockParseNode) GetCollectionOfPrimitiveValues(targetType string) ([]interface{}, error) { + return nil, nil +} +func (e *MockParseNode) GetCollectionOfEnumValues(parser absser.EnumFactory) ([]interface{}, error) { + return nil, nil +} +func (e *MockParseNode) GetObjectValue(ctor absser.ParsableFactory) (absser.Parsable, error) { + return &MockEntity{}, nil +} +func (e *MockParseNode) GetStringValue() (*string, error) { + return nil, nil +} +func (e *MockParseNode) GetBoolValue() (*bool, error) { + return nil, nil + +} +func (e *MockParseNode) GetInt8Value() (*int8, error) { + return nil, nil + +} +func (e *MockParseNode) GetByteValue() (*byte, error) { + return nil, nil + +} +func (e *MockParseNode) GetFloat32Value() (*float32, error) { + return nil, nil + +} +func (e *MockParseNode) GetFloat64Value() (*float64, error) { + return nil, nil + +} +func (e *MockParseNode) GetInt32Value() (*int32, error) { + return nil, nil + +} +func (e *MockParseNode) GetInt64Value() (*int64, error) { + return nil, nil + +} +func (e *MockParseNode) GetTimeValue() (*time.Time, error) { + return nil, nil + +} +func (e *MockParseNode) GetISODurationValue() (*absser.ISODuration, error) { + return nil, nil + +} +func (e *MockParseNode) GetTimeOnlyValue() (*absser.TimeOnly, error) { + return nil, nil + +} +func (e *MockParseNode) GetDateOnlyValue() (*absser.DateOnly, error) { + return nil, nil + +} +func (e *MockParseNode) GetUUIDValue() (*uuid.UUID, error) { + return nil, nil + +} +func (e *MockParseNode) GetEnumValue(parser absser.EnumFactory) (interface{}, error) { + return nil, nil + +} +func (e *MockParseNode) GetByteArrayValue() ([]byte, error) { + return nil, nil + +} diff --git a/nethttp_request_adapter.go b/nethttp_request_adapter.go index d0029bb..2ed2f68 100644 --- a/nethttp_request_adapter.go +++ b/nethttp_request_adapter.go @@ -386,7 +386,13 @@ func (a *NetHttpRequestAdapter) SendPrimitiveAsync(ctx context.Context, requestI return nil, err } if typeName == "[]byte" { - return ioutil.ReadAll(response.Body) + res, err := ioutil.ReadAll(response.Body) + if err != nil { + return nil, err + } else if len(res) == 0 { + return nil, nil + } + return res, nil } parseNode, err := a.getRootParseNode(response) if err != nil { diff --git a/nethttp_request_adapter_test.go b/nethttp_request_adapter_test.go index f872e4c..8c71f14 100644 --- a/nethttp_request_adapter_test.go +++ b/nethttp_request_adapter_test.go @@ -9,6 +9,7 @@ import ( abs "github.com/microsoft/kiota-abstractions-go" absauth "github.com/microsoft/kiota-abstractions-go/authentication" + "github.com/microsoft/kiota-http-go/internal" "github.com/stretchr/testify/assert" ) @@ -74,3 +75,139 @@ func TestItDoesntFailOnEmptyContentType(t *testing.T) { assert.Nil(t, err) assert.Nil(t, res) } + +func TestItReturnsUsableStreamOnStream(t *testing.T) { + statusCodes := []int{200, 201, 202, 203, 206} + + for i := 0; i < len(statusCodes); i++ { + + testServer := httptest.NewServer(nethttp.HandlerFunc(func(res nethttp.ResponseWriter, req *nethttp.Request) { + res.WriteHeader(statusCodes[i]) + res.Write([]byte("test")) + })) + defer func() { testServer.Close() }() + authProvider := &absauth.AnonymousAuthenticationProvider{} + adapter, err := NewNetHttpRequestAdapter(authProvider) + assert.Nil(t, err) + assert.NotNil(t, adapter) + + uri, err := url.Parse(testServer.URL) + assert.Nil(t, err) + assert.NotNil(t, uri) + request := abs.NewRequestInformation() + request.SetUri(*uri) + request.Method = abs.GET + + res, err2 := adapter.SendPrimitiveAsync(context.TODO(), request, "[]byte", nil) + assert.Nil(t, err2) + assert.NotNil(t, res) + assert.Equal(t, 4, len(res.([]byte))) + } +} + +func TestItReturnsNilOnStream(t *testing.T) { + statusCodes := []int{200, 201, 202, 203, 204} + + for i := 0; i < len(statusCodes); i++ { + + testServer := httptest.NewServer(nethttp.HandlerFunc(func(res nethttp.ResponseWriter, req *nethttp.Request) { + res.WriteHeader(statusCodes[i]) + })) + defer func() { testServer.Close() }() + authProvider := &absauth.AnonymousAuthenticationProvider{} + adapter, err := NewNetHttpRequestAdapter(authProvider) + assert.Nil(t, err) + assert.NotNil(t, adapter) + + uri, err := url.Parse(testServer.URL) + assert.Nil(t, err) + assert.NotNil(t, uri) + request := abs.NewRequestInformation() + request.SetUri(*uri) + request.Method = abs.GET + + res, err2 := adapter.SendPrimitiveAsync(context.TODO(), request, "[]byte", nil) + assert.Nil(t, err2) + assert.Nil(t, res) + } +} + +func TestSendNoContentDoesntFailOnOtherCodes(t *testing.T) { + statusCodes := []int{200, 201, 202, 203, 204, 206} + + for i := 0; i < len(statusCodes); i++ { + + testServer := httptest.NewServer(nethttp.HandlerFunc(func(res nethttp.ResponseWriter, req *nethttp.Request) { + res.WriteHeader(statusCodes[i]) + })) + defer func() { testServer.Close() }() + authProvider := &absauth.AnonymousAuthenticationProvider{} + adapter, err := NewNetHttpRequestAdapter(authProvider) + assert.Nil(t, err) + assert.NotNil(t, adapter) + + uri, err := url.Parse(testServer.URL) + assert.Nil(t, err) + assert.NotNil(t, uri) + request := abs.NewRequestInformation() + request.SetUri(*uri) + request.Method = abs.GET + + err2 := adapter.SendNoContentAsync(context.TODO(), request, nil) + assert.Nil(t, err2) + } +} + +func TestSendReturnNilOnNoContent(t *testing.T) { + statusCodes := []int{200, 201, 202, 203, 204, 205} + + for i := 0; i < len(statusCodes); i++ { + + testServer := httptest.NewServer(nethttp.HandlerFunc(func(res nethttp.ResponseWriter, req *nethttp.Request) { + res.WriteHeader(statusCodes[i]) + })) + defer func() { testServer.Close() }() + authProvider := &absauth.AnonymousAuthenticationProvider{} + adapter, err := NewNetHttpRequestAdapter(authProvider) + assert.Nil(t, err) + assert.NotNil(t, adapter) + + uri, err := url.Parse(testServer.URL) + assert.Nil(t, err) + assert.NotNil(t, uri) + request := abs.NewRequestInformation() + request.SetUri(*uri) + request.Method = abs.GET + + res, err2 := adapter.SendAsync(context.TODO(), request, internal.MockEntityFactory, nil) + assert.Nil(t, err2) + assert.Nil(t, res) + } +} + +func TestSendReturnsObjectOnContent(t *testing.T) { + statusCodes := []int{200, 201, 202, 203, 204, 205} + + for i := 0; i < len(statusCodes); i++ { + + testServer := httptest.NewServer(nethttp.HandlerFunc(func(res nethttp.ResponseWriter, req *nethttp.Request) { + res.WriteHeader(statusCodes[i]) + })) + defer func() { testServer.Close() }() + authProvider := &absauth.AnonymousAuthenticationProvider{} + adapter, err := NewNetHttpRequestAdapterWithParseNodeFactory(authProvider, &internal.MockParseNodeFactory{}) + assert.Nil(t, err) + assert.NotNil(t, adapter) + + uri, err := url.Parse(testServer.URL) + assert.Nil(t, err) + assert.NotNil(t, uri) + request := abs.NewRequestInformation() + request.SetUri(*uri) + request.Method = abs.GET + + res, err2 := adapter.SendAsync(context.TODO(), request, internal.MockEntityFactory, nil) + assert.Nil(t, err2) + assert.Nil(t, res) + } +}