From 726f90f29ca49b797afd4f7674282336810146dc Mon Sep 17 00:00:00 2001 From: Neur0toxine Date: Mon, 8 Nov 2021 13:25:56 +0300 Subject: [PATCH] fix `order[items][][properties][]` unmarshaling for empty values --- marshaling.go | 34 ++++++++++++++++++++++++++++++++++ marshaling_test.go | 26 ++++++++++++++++++++++++++ types.go | 33 +++++++++++++++++---------------- 3 files changed, 77 insertions(+), 16 deletions(-) diff --git a/marshaling.go b/marshaling.go index 6a924d2..9d969a5 100644 --- a/marshaling.go +++ b/marshaling.go @@ -92,6 +92,40 @@ func (p *OrderPayments) UnmarshalJSON(data []byte) error { return nil } +func (p *Properties) UnmarshalJSON(data []byte) error { + var i interface{} + var m Properties + if err := json.Unmarshal(data, &i); err != nil { + return err + } + + switch e := i.(type) { + case map[string]interface{}: + m = make(Properties, len(e)) + for idx, val := range e { + var res Property + err := unmarshalMap(val.(map[string]interface{}), &res) + if err != nil { + return err + } + m[idx] = res + } + case []interface{}: + m = make(Properties, len(e)) + for idx, val := range e { + var res Property + err := unmarshalMap(val.(map[string]interface{}), &res) + if err != nil { + return err + } + m[strconv.Itoa(idx)] = res + } + } + + *p = m + return nil +} + func unmarshalMap(m map[string]interface{}, v interface{}) (err error) { var data []byte data, err = json.Marshal(m) diff --git a/marshaling_test.go b/marshaling_test.go index 30f08e8..4b70ff7 100644 --- a/marshaling_test.go +++ b/marshaling_test.go @@ -38,6 +38,9 @@ func TestAPIErrorsList_UnmarshalJSON(t *testing.T) { assert.Len(t, list, 2) assert.Equal(t, list["a"], "first") assert.Equal(t, list["b"], "second") + + require.NoError(t, json.Unmarshal([]byte(`[]`), &list)) + assert.Len(t, list, 0) } func TestCustomFieldsList_UnmarshalJSON(t *testing.T) { @@ -52,6 +55,9 @@ func TestCustomFieldsList_UnmarshalJSON(t *testing.T) { assert.Len(t, list, 2) assert.Equal(t, list["a"], "first") assert.Equal(t, list["b"], "second") + + require.NoError(t, json.Unmarshal([]byte(`[]`), &list)) + assert.Len(t, list, 0) } func TestOrderPayments_UnmarshalJSON(t *testing.T) { @@ -66,4 +72,24 @@ func TestOrderPayments_UnmarshalJSON(t *testing.T) { assert.Len(t, list, 2) assert.Equal(t, list["a"], OrderPayment{ID: 1}) assert.Equal(t, list["b"], OrderPayment{ID: 2}) + + require.NoError(t, json.Unmarshal([]byte(`[]`), &list)) + assert.Len(t, list, 0) +} + +func TestProperties_UnmarshalJSON(t *testing.T) { + var list Properties + + require.NoError(t, json.Unmarshal([]byte(`[{"code": "first"}, {"code": "second"}]`), &list)) + assert.Len(t, list, 2) + assert.Equal(t, list["0"], Property{Code: "first"}) + assert.Equal(t, list["1"], Property{Code: "second"}) + + require.NoError(t, json.Unmarshal([]byte(`{"a": {"code": "first"}, "b": {"code": "second"}}`), &list)) + assert.Len(t, list, 2) + assert.Equal(t, list["a"], Property{Code: "first"}) + assert.Equal(t, list["b"], Property{Code: "second"}) + + require.NoError(t, json.Unmarshal([]byte(`[]`), &list)) + assert.Len(t, list, 0) } diff --git a/types.go b/types.go index 8a6f403..1c7579b 100644 --- a/types.go +++ b/types.go @@ -275,6 +275,7 @@ Order related types type OrderPayments map[string]OrderPayment type StringMap map[string]string +type Properties map[string]Property // Order type. type Order struct { @@ -442,22 +443,22 @@ type OrderPayment struct { // OrderItem type. type OrderItem struct { - ID int `json:"id,omitempty"` - InitialPrice float32 `json:"initialPrice,omitempty"` - PurchasePrice float32 `json:"purchasePrice,omitempty"` - DiscountTotal float32 `json:"discountTotal,omitempty"` - DiscountManualAmount float32 `json:"discountManualAmount,omitempty"` - DiscountManualPercent float32 `json:"discountManualPercent,omitempty"` - ProductName string `json:"productName,omitempty"` - VatRate string `json:"vatRate,omitempty"` - CreatedAt string `json:"createdAt,omitempty"` - Quantity float32 `json:"quantity,omitempty"` - Status string `json:"status,omitempty"` - Comment string `json:"comment,omitempty"` - IsCanceled bool `json:"isCanceled,omitempty"` - Offer Offer `json:"offer,omitempty"` - Properties map[string]Property `json:"properties,omitempty"` - PriceType *PriceType `json:"priceType,omitempty"` + ID int `json:"id,omitempty"` + InitialPrice float32 `json:"initialPrice,omitempty"` + PurchasePrice float32 `json:"purchasePrice,omitempty"` + DiscountTotal float32 `json:"discountTotal,omitempty"` + DiscountManualAmount float32 `json:"discountManualAmount,omitempty"` + DiscountManualPercent float32 `json:"discountManualPercent,omitempty"` + ProductName string `json:"productName,omitempty"` + VatRate string `json:"vatRate,omitempty"` + CreatedAt string `json:"createdAt,omitempty"` + Quantity float32 `json:"quantity,omitempty"` + Status string `json:"status,omitempty"` + Comment string `json:"comment,omitempty"` + IsCanceled bool `json:"isCanceled,omitempty"` + Offer Offer `json:"offer,omitempty"` + Properties Properties `json:"properties,omitempty"` + PriceType *PriceType `json:"priceType,omitempty"` } // OrdersHistoryRecord type.