Skip to content

Commit

Permalink
Merge pull request #1840 from openmeterio/feat/plan-api-impl
Browse files Browse the repository at this point in the history
fix: Plan Discount JSON serialization
  • Loading branch information
chrisgacsal authored Nov 13, 2024
2 parents 059c02d + d246fc0 commit 63ec6ef
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 21 deletions.
40 changes: 22 additions & 18 deletions openmeter/productcatalog/plan/discount.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,38 +56,49 @@ func (d *Discount) RateCardKeys() []string {
func (d *Discount) MarshalJSON() ([]byte, error) {
var b []byte
var err error
var serde interface{}

switch d.t {
case PercentageDiscountType:
b, err = json.Marshal(d.percentage)
if err != nil {
return nil, fmt.Errorf("failed to json marshal percentage discount: %w", err)
serde = struct {
Type DiscountType `json:"type"`
*PercentageDiscount
}{
Type: PercentageDiscountType,
PercentageDiscount: d.percentage,
}
default:
return nil, fmt.Errorf("invalid discount type: %s", d.t)
return nil, fmt.Errorf("invalid Discount type: %s", d.t)
}

b, err = json.Marshal(serde)
if err != nil {
return nil, fmt.Errorf("failed to JSON serialize Discount: %w", err)
}

return b, nil
}

func (d *Discount) UnmarshalJSON(bytes []byte) error {
meta := &DiscountMeta{}
serde := &struct {
Type DiscountType `json:"type"`
}{}

if err := json.Unmarshal(bytes, meta); err != nil {
return fmt.Errorf("failed to json unmarshal discount type: %w", err)
if err := json.Unmarshal(bytes, serde); err != nil {
return fmt.Errorf("failed to JSON deserialize Discount type: %w", err)
}

switch meta.Type {
switch serde.Type {
case PercentageDiscountType:
v := &PercentageDiscount{}
if err := json.Unmarshal(bytes, v); err != nil {
return fmt.Errorf("failed to json unmarshal percentage discount: %w", err)
return fmt.Errorf("failed to JSON deserialize Discount: %w", err)
}

d.percentage = v
d.t = PercentageDiscountType
default:
return fmt.Errorf("invalid discount type: %s", meta.Type)
return fmt.Errorf("invalid Discount type: %s", serde.Type)
}

return nil
Expand Down Expand Up @@ -127,24 +138,17 @@ func NewDiscountFrom[T PercentageDiscount](v T) Discount {
d := Discount{}

switch any(v).(type) {
case FlatPrice:
case PercentageDiscount:
percentage := any(v).(PercentageDiscount)
d.FromPercentage(percentage)
}

return d
}

type DiscountMeta struct {
// Type of the Discount.
Type DiscountType `json:"type"`
}

var _ Validator = (*PercentageDiscount)(nil)

type PercentageDiscount struct {
DiscountMeta

// Percentage defines percentage of the discount.
Percentage decimal.Decimal `json:"percentage"`

Expand Down
44 changes: 44 additions & 0 deletions openmeter/productcatalog/plan/discount_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package plan

import (
"testing"

decimal "github.com/alpacahq/alpacadecimal"
json "github.com/json-iterator/go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestDiscount_JSON(t *testing.T) {
tests := []struct {
Name string
Discount Discount
ExpectedError bool
}{
{
Name: "Valid",
Discount: NewDiscountFrom(PercentageDiscount{
Percentage: decimal.NewFromFloat(99.9),
RateCards: []string{
"ratecard-1",
"ratecard-2",
},
}),
},
}

for _, test := range tests {
t.Run(test.Name, func(t *testing.T) {
b, err := json.Marshal(&test.Discount)
require.NoError(t, err)

t.Logf("Serialized Discount: %s", string(b))

d := Discount{}
err = json.Unmarshal(b, &d)
require.NoError(t, err)

assert.Equal(t, test.Discount, d)
})
}
}
3 changes: 0 additions & 3 deletions openmeter/productcatalog/plan/httpdriver/mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,6 @@ func AsPlanPhase(a api.PlanPhase, namespace, phaseID string) (plan.Phase, error)
switch discount.Type {
case api.DiscountPercentageTypePercentage:
percentageDiscount := plan.PercentageDiscount{
DiscountMeta: plan.DiscountMeta{
Type: plan.PercentageDiscountType,
},
Percentage: decimal.NewFromFloat(float64(discount.Percentage)),
RateCards: lo.FromPtrOr(discount.RateCards, nil),
}
Expand Down

0 comments on commit 63ec6ef

Please sign in to comment.