diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 69b64d4b..615b7215 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -19,9 +19,6 @@ jobs: - uses: actions/checkout@v4 - name: Setup Go uses: actions/setup-go@v4 - - name: Install dependencies - run: | - go get . - name: Build run: go build -v ./... - name: Test with the Go CLI diff --git a/test/api_test.go b/test/api_test.go index db8501d1..e02ae878 100644 --- a/test/api_test.go +++ b/test/api_test.go @@ -2,7 +2,6 @@ package test import ( "math/rand" - "testing" "time" "github.com/caarlos0/env/v10" @@ -46,10 +45,6 @@ type card struct { cardType models.CardType } -func TestAPISuite(t *testing.T) { - suite.Run(t, new(APISuite)) -} - func (s *APISuite) SetupTest() { s.fkr = faker.NewWithSeed(rand.NewSource(time.Now().Unix())) diff --git a/test/component_allocations_test.go b/test/component_allocations_test.go new file mode 100644 index 00000000..80eda5d7 --- /dev/null +++ b/test/component_allocations_test.go @@ -0,0 +1,195 @@ +package test + +import ( + "context" + "fmt" + "net/http" + "testing" + + "github.com/maxio-com/ab-golang-sdk/errors" + "github.com/maxio-com/ab-golang-sdk/models" + "github.com/stretchr/testify/suite" +) + +type ComponentAlocationSuite struct { + APISuite +} + +func TestComponentSuite(t *testing.T) { + suite.Run(t, new(ComponentAlocationSuite)) +} + +type OnOffComponent struct { + Name string `json:"name"` + Prices []Price `json:"prices"` + PricingScheme string `json:"pricing_scheme"` + PricePoint []PricePoint `json:"price_points"` + UnitPrice string `json:"unit_price"` +} + +type PricePoint struct { + Name string `json:"name"` + Prices []Price `json:"prices"` + PricingScheme string `json:"pricing_scheme,omitempty"` +} + +type OnOffBody struct { + OnOffComponent OnOffComponent `json:"on_off_component"` +} + +type QuantityBasedComponent struct { + Name string `json:"name"` + UnitName string `json:"unit_name"` + PricingScheme string `json:"pricing_scheme"` + AllowFractionalQuantities bool `json:"allow_fractional_quantities"` + PricePoint []PricePoint `json:"price_points"` + UnitPrice string `json:"unit_price"` +} + +type QuantityBody struct { + QuantityBasedComponent QuantityBasedComponent `json:"quantity_based_component"` +} + +func (s *ComponentAlocationSuite) TestComponentAllocations() { + ctx := context.Background() + + customer := s.createCustomer(ctx) + pf := s.createProductFamily(ctx) + product := s.createProduct(ctx, *pf.Id) + subscription := s.newSubscription(customer, product, "", []models.CreateSubscriptionComponent{}) + subResp, err := s.client.SubscriptionsController().CreateSubscription(ctx, &models.CreateSubscriptionRequest{Subscription: subscription}) + s.NoError(err) + s.Equal(http.StatusCreated, subResp.Response.StatusCode) + + onOffResp, err := s.client.ComponentsController().CreateComponent( + ctx, + *pf.Id, + models.ComponentKindPath_ONOFFCOMPONENTS, + interfacePtr(OnOffBody{ + OnOffComponent: OnOffComponent{ + Name: "One of component", + Prices: []Price{ + { + StartingQuantity: 1, + UnitPrice: 1, + }, + }, + PricePoint: []PricePoint{ + { + Name: "test price point", + Prices: []Price{ + { + StartingQuantity: 1, + UnitPrice: 1, + }, + }, + }, + }, + UnitPrice: "100", + }, + }), + ) + s.NoError(err) + s.Equal(http.StatusCreated, onOffResp.Response.StatusCode) + + quantityResp, err := s.client.ComponentsController().CreateComponent( + ctx, + *pf.Id, + models.ComponentKindPath_QUANTITYBASEDCOMPONENTS, + interfacePtr(QuantityBody{ + QuantityBasedComponent: QuantityBasedComponent{ + Name: "Quantity based", + UnitName: "test unit", + PricingScheme: string(models.PricingScheme_PERUNIT), + AllowFractionalQuantities: true, + PricePoint: []PricePoint{ + { + Name: "Other price point", + Prices: []Price{ + { + StartingQuantity: 1, + UnitPrice: 1, + }, + }, + PricingScheme: string(models.PricingScheme_PERUNIT), + }, + }, + UnitPrice: "100", + }, + }), + ) + s.NoError(err) + s.Equal(http.StatusCreated, quantityResp.Response.StatusCode) + + cases := []struct { + name string + allocations []models.CreateAllocation + assert func(t *testing.T, response models.ApiResponse[models.AllocationPreviewResponse], input []models.CreateAllocation, err error) + }{ + { + name: "valid", + allocations: []models.CreateAllocation{ + { + Quantity: 1, + ComponentId: onOffResp.Data.Component.Id, + Memo: strPtr("foo"), + }, + { + Quantity: 10.3, + ComponentId: quantityResp.Data.Component.Id, + Memo: strPtr("bar"), + }, + }, + assert: func(t *testing.T, response models.ApiResponse[models.AllocationPreviewResponse], expected []models.CreateAllocation, err error) { + s.NoError(err) + s.Equal(http.StatusOK, response.Response.StatusCode) + + prevAllocations := response.Data.AllocationPreview.Allocations + s.Equal(float64(1), *prevAllocations[0].Quantity) + s.Equal(fmt.Sprintf("%.1f", expected[1].Quantity), *prevAllocations[1].Quantity) + + allocationsResp, err := s.client.SubscriptionComponentsController().AllocateComponents( + ctx, + *subResp.Data.Subscription.Id, + &models.AllocateComponents{ + Allocations: expected, + }, + ) + s.NoError(err) + s.Equal(http.StatusCreated, allocationsResp.Response.StatusCode) + + responseAllocations := allocationsResp.Data + s.Equal(float64(1), *responseAllocations[0].Allocation.Quantity) + s.Equal(fmt.Sprintf("%.1f", expected[1].Quantity), *responseAllocations[1].Allocation.Quantity) + }, + }, + { + name: "unprocessable entity", + allocations: []models.CreateAllocation{ + { + Quantity: 50, + ComponentId: onOffResp.Data.Component.Id, + }, + }, + assert: func(t *testing.T, response models.ApiResponse[models.AllocationPreviewResponse], input []models.CreateAllocation, err error) { + s.Equal(errors.NewComponentAllocationError(422, "Unprocessable Entity (WebDAV)").Error(), err.Error()) + // cant check errors map here because it comes empty + s.Equal(http.StatusUnprocessableEntity, response.Response.StatusCode) + }, + }, + } + + for _, c := range cases { + s.T().Run(c.name, func(t *testing.T) { + previewResp, err := s.client.SubscriptionComponentsController().PreviewAllocations( + ctx, + *subResp.Data.Subscription.Id, + &models.PreviewAllocationsRequest{ + Allocations: c.allocations, + }, + ) + + c.assert(t, previewResp, c.allocations, err) + }) + } +} diff --git a/test/invoice_test.go b/test/invoice_test.go index 54e2482e..1c1d1d2e 100644 --- a/test/invoice_test.go +++ b/test/invoice_test.go @@ -8,9 +8,18 @@ import ( "github.com/maxio-com/ab-golang-sdk/errors" "github.com/maxio-com/ab-golang-sdk/models" + "github.com/stretchr/testify/suite" ) -func (s *APISuite) TestInvoice() { +type InvoiceSuite struct { + APISuite +} + +func TestInvoiceSuite(t *testing.T) { + suite.Run(t, new(InvoiceSuite)) +} + +func (s *InvoiceSuite) TestInvoice() { ctx := context.Background() customer := s.createCustomer(ctx) diff --git a/test/metafields_test.go b/test/metafields_test.go index 9d0f0d39..72eb82dd 100644 --- a/test/metafields_test.go +++ b/test/metafields_test.go @@ -7,8 +7,17 @@ import ( "testing" "github.com/maxio-com/ab-golang-sdk/models" + "github.com/stretchr/testify/suite" ) +type MetafieldsSuite struct { + APISuite +} + +func TestMetafieldsSuite(t *testing.T) { + suite.Run(t, new(MetafieldsSuite)) +} + // this structure has to be defined at this point since default json // marshaller does not work with marshalling enum as optional interface // for single metafield requests. @@ -21,7 +30,7 @@ type metafield struct { Enum []string `json:"enum"` } -func (s *APISuite) TestMetafields() { +func (s *MetafieldsSuite) TestMetafields() { ctx := context.Background() customer := s.createCustomer(ctx) @@ -46,6 +55,7 @@ func (s *APISuite) TestMetafields() { resourceType models.ResourceType metafields interface{} assert func(t *testing.T, resp models.ApiResponse[[]models.Metafield], err error) + afterTest func(t *testing.T, metafields []models.Metafield) }{ { name: "subscriptions", @@ -137,6 +147,18 @@ func (s *APISuite) TestMetafields() { s.Len(rSubs.Data, 1) s.Equal(subs.Id, rSubs.Data[0].Subscription.Id) }, + afterTest: func(t *testing.T, metafields []models.Metafield) { + for _, metafield := range metafields { + resp, err := s.client.CustomFieldsController().DeleteMetafield( + ctx, + models.ResourceType_SUBSCRIPTIONS, + metafield.Name, + ) + + s.NoError(err) + s.Equal(http.StatusOK, resp.StatusCode) + } + }, }, { name: "customers", @@ -187,6 +209,18 @@ func (s *APISuite) TestMetafields() { s.Equal(radioField.Name, customerResp.Data[0].Name) s.Equal("option 2", *customerResp.Data[0].Value) }, + afterTest: func(t *testing.T, metafields []models.Metafield) { + for _, metafield := range metafields { + resp, err := s.client.CustomFieldsController().DeleteMetafield( + ctx, + models.ResourceType_CUSTOMERS, + metafield.Name, + ) + + s.NoError(err) + s.Equal(http.StatusOK, resp.StatusCode) + } + }, }, } @@ -201,6 +235,7 @@ func (s *APISuite) TestMetafields() { ) c.assert(t, resp, err) + c.afterTest(t, resp.Data) }) } } diff --git a/test/site_test.go b/test/site_test.go index d7cd0b4c..e3789073 100644 --- a/test/site_test.go +++ b/test/site_test.go @@ -7,9 +7,18 @@ import ( advancedbilling "github.com/maxio-com/ab-golang-sdk" "github.com/maxio-com/ab-golang-sdk/models" + "github.com/stretchr/testify/suite" ) -func (s *APISuite) TestReadSite() { +type SiteSuite struct { + APISuite +} + +func TestSiteSuite(t *testing.T) { + suite.Run(t, new(SiteSuite)) +} + +func (s *SiteSuite) TestReadSite() { cases := []struct { name string client advancedbilling.ClientInterface diff --git a/test/subscription_test.go b/test/subscription_test.go index c589879f..fbac5625 100644 --- a/test/subscription_test.go +++ b/test/subscription_test.go @@ -8,9 +8,18 @@ import ( advancedbilling "github.com/maxio-com/ab-golang-sdk" "github.com/maxio-com/ab-golang-sdk/models" + "github.com/stretchr/testify/suite" ) -func (s *APISuite) TestSubscriptionCreate() { +type SubscriptionSuite struct { + APISuite +} + +func TestSubscriptionSuite(t *testing.T) { + suite.Run(t, new(SubscriptionSuite)) +} + +func (s *SubscriptionSuite) TestSubscriptionCreate() { ctx := context.Background() customer := s.createCustomer(ctx)