From 6d1da9585d13ee1b988641e2bdf274d4f8d36b16 Mon Sep 17 00:00:00 2001 From: mrz1836 Date: Fri, 4 Jun 2021 16:50:32 -0400 Subject: [PATCH] Starting goal test coverage --- definitions.go | 2 +- examples/goals/create/create.go | 39 ++++ examples/goals/get/get.go | 29 +++ goals.go | 6 +- goals_test.go | 309 +++++++++++++++++++++++++++++++- 5 files changed, 381 insertions(+), 4 deletions(-) create mode 100644 examples/goals/create/create.go create mode 100644 examples/goals/get/get.go diff --git a/definitions.go b/definitions.go index 0a9c628..10457a8 100644 --- a/definitions.go +++ b/definitions.go @@ -5,7 +5,7 @@ import ( ) const ( - // Config defaults + // Package configuration defaults apiVersion string = "v1" defaultHTTPTimeout = 10 * time.Second // Default timeout for all GET requests in seconds defaultRetryCount int = 2 // Default retry count for HTTP requests diff --git a/examples/goals/create/create.go b/examples/goals/create/create.go new file mode 100644 index 0000000..de47048 --- /dev/null +++ b/examples/goals/create/create.go @@ -0,0 +1,39 @@ +package main + +import ( + "log" + "os" + + "github.com/tonicpow/go-tonicpow" +) + +func main() { + + // Load the api client + client, err := tonicpow.NewClient( + tonicpow.WithAPIKey(os.Getenv("TONICPOW_API_KEY")), + tonicpow.WithEnvironmentString(os.Getenv("TONICPOW_ENVIRONMENT")), + ) + if err != nil { + log.Fatalf("error in NewClient: %s", err.Error()) + } + + // Start goal + goal := &tonicpow.Goal{ + CampaignID: 23, + Description: "Example goal description", + MaxPerPromoter: 1, + Name: "example_goal", + PayoutRate: 0.01, + PayoutType: "flat", + Title: "Example Goal", + } + + // Create a goal + err = client.CreateGoal(goal) + if err != nil { + log.Fatalf("error in CreateGoal: %s", err.Error()) + } + + log.Printf("created goal: %d", goal.ID) +} diff --git a/examples/goals/get/get.go b/examples/goals/get/get.go new file mode 100644 index 0000000..dbbc493 --- /dev/null +++ b/examples/goals/get/get.go @@ -0,0 +1,29 @@ +package main + +import ( + "log" + "os" + + "github.com/tonicpow/go-tonicpow" +) + +func main() { + + // Load the api client + client, err := tonicpow.NewClient( + tonicpow.WithAPIKey(os.Getenv("TONICPOW_API_KEY")), + tonicpow.WithEnvironmentString(os.Getenv("TONICPOW_ENVIRONMENT")), + ) + if err != nil { + log.Fatalf("error in NewClient: %s", err.Error()) + } + + // Get a goal + var goal *tonicpow.Goal + goal, err = client.GetGoal(13) + if err != nil { + log.Fatalf("error in GetGoal: %s", err.Error()) + } + + log.Printf("goal: %s", goal.Name) +} diff --git a/goals.go b/goals.go index 54f601d..df821f5 100644 --- a/goals.go +++ b/goals.go @@ -9,7 +9,6 @@ import ( // permitFields will remove fields that cannot be used func (g *Goal) permitFields() { g.CampaignID = 0 - g.Payouts = 0 } // CreateGoal will make a new goal @@ -21,6 +20,9 @@ func (c *Client) CreateGoal(goal *Goal) (err error) { if goal.CampaignID == 0 { err = fmt.Errorf(fmt.Sprintf("missing required attribute: %s", fieldCampaignID)) return + } else if len(goal.Name) == 0 { + err = fmt.Errorf(fmt.Sprintf("missing required attribute: %s", fieldName)) + return } // Fire the Request @@ -43,7 +45,7 @@ func (c *Client) CreateGoal(goal *Goal) (err error) { // For more information: https://docs.tonicpow.com/#48d7bbc8-5d7b-4078-87b7-25f545c3deaf func (c *Client) GetGoal(goalID uint64) (goal *Goal, err error) { - // Must have an id + // Must have an ID if goalID == 0 { err = fmt.Errorf("missing required attribute: %s", fieldID) return diff --git a/goals_test.go b/goals_test.go index 0d466db..f98fb04 100644 --- a/goals_test.go +++ b/goals_test.go @@ -1,5 +1,13 @@ package tonicpow +import ( + "fmt" + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + // newTestGoal will return a dummy example for tests func newTestGoal() *Goal { return &Goal{ @@ -8,8 +16,307 @@ func newTestGoal() *Goal { ID: testGoalID, MaxPerPromoter: 1, Name: "example_goal", - PayoutRate: 1, + PayoutRate: 0.01, PayoutType: "flat", Title: "Example Goal", } } + +// TestClient_CreateGoal will test the method CreateGoal() +func TestClient_CreateGoal(t *testing.T) { + // t.Parallel() (Cannot run in parallel - issues with overriding the mock client) + + t.Run("create a goal (success)", func(t *testing.T) { + client, err := newTestClient() + assert.NoError(t, err) + assert.NotNil(t, client) + + goal := newTestGoal() + + endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelGoal) + + err = mockResponseData(http.MethodPost, endpoint, http.StatusCreated, goal) + assert.NoError(t, err) + + err = client.CreateGoal(goal) + assert.NoError(t, err) + assert.NotNil(t, goal) + assert.Equal(t, testGoalID, goal.ID) + }) + + t.Run("missing campaign id", func(t *testing.T) { + client, err := newTestClient() + assert.NoError(t, err) + assert.NotNil(t, client) + + goal := newTestGoal() + goal.CampaignID = 0 + + endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelGoal) + + err = mockResponseData(http.MethodPost, endpoint, http.StatusCreated, goal) + assert.NoError(t, err) + + err = client.CreateGoal(goal) + assert.Error(t, err) + }) + + t.Run("missing goal name", func(t *testing.T) { + client, err := newTestClient() + assert.NoError(t, err) + assert.NotNil(t, client) + + goal := newTestGoal() + goal.Name = "" + + endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelGoal) + + err = mockResponseData(http.MethodPost, endpoint, http.StatusCreated, goal) + assert.NoError(t, err) + + err = client.CreateGoal(goal) + assert.Error(t, err) + }) + + t.Run("error from api (status code)", func(t *testing.T) { + client, err := newTestClient() + assert.NoError(t, err) + assert.NotNil(t, client) + + goal := newTestGoal() + + endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelGoal) + + err = mockResponseData(http.MethodPost, endpoint, http.StatusBadRequest, goal) + assert.NoError(t, err) + + err = client.CreateGoal(goal) + assert.Error(t, err) + }) + + t.Run("error from api (api error)", func(t *testing.T) { + client, err := newTestClient() + assert.NoError(t, err) + assert.NotNil(t, client) + + goal := newTestGoal() + + endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelGoal) + + apiError := &Error{ + Code: 400, + Data: "field_name", + IPAddress: "127.0.0.1", + Message: "some error message", + Method: http.MethodPut, + RequestGUID: "7f3d97a8fd67ff57861904df6118dcc8", + StatusCode: http.StatusBadRequest, + URL: endpoint, + } + + err = mockResponseData(http.MethodPost, endpoint, http.StatusBadRequest, apiError) + assert.NoError(t, err) + + err = client.CreateGoal(goal) + assert.Error(t, err) + assert.Equal(t, apiError.Message, err.Error()) + }) +} + +// ExampleClient_CreateGoal example using CreateGoal() +// +// See more examples in /examples/ +func ExampleClient_CreateGoal() { + + // Load the client (using test client for example only) + client, err := newTestClient() + if err != nil { + fmt.Printf("error loading client: %s", err.Error()) + return + } + + // Mock response (for example only) + responseGoal := newTestGoal() + _ = mockResponseData( + http.MethodPost, + fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelGoal), + http.StatusCreated, + responseGoal, + ) + + // Create goal (using mocking response) + if err = client.CreateGoal(responseGoal); err != nil { + fmt.Printf("error creating goal: " + err.Error()) + return + } + fmt.Printf("created goal: %s", responseGoal.Name) + // Output:created goal: example_goal +} + +// BenchmarkClient_CreateGoal benchmarks the method CreateGoal() +func BenchmarkClient_CreateGoal(b *testing.B) { + client, _ := newTestClient() + goal := newTestGoal() + _ = mockResponseData( + http.MethodPost, + fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelGoal), + http.StatusCreated, + goal, + ) + for i := 0; i < b.N; i++ { + _ = client.CreateGoal(goal) + } +} + +// TestClient_GetGoal will test the method GetGoal() +func TestClient_GetGoal(t *testing.T) { + // t.Parallel() (Cannot run in parallel - issues with overriding the mock client) + + t.Run("get a goal (success)", func(t *testing.T) { + client, err := newTestClient() + assert.NoError(t, err) + assert.NotNil(t, client) + + goal := newTestGoal() + + endpoint := fmt.Sprintf( + "%s/%s/details/%d", EnvironmentDevelopment.apiURL, + modelGoal, goal.ID, + ) + + err = mockResponseData(http.MethodGet, endpoint, http.StatusOK, goal) + assert.NoError(t, err) + + var newGoal *Goal + newGoal, err = client.GetGoal(goal.ID) + assert.NoError(t, err) + assert.NotNil(t, newGoal) + assert.Equal(t, testGoalID, goal.ID) + }) + + t.Run("missing goal id", func(t *testing.T) { + client, err := newTestClient() + assert.NoError(t, err) + assert.NotNil(t, client) + + goal := newTestGoal() + goal.ID = 0 + + endpoint := fmt.Sprintf( + "%s/%s/details/%d", EnvironmentDevelopment.apiURL, + modelGoal, goal.ID, + ) + + err = mockResponseData(http.MethodGet, endpoint, http.StatusOK, goal) + assert.NoError(t, err) + + var newGoal *Goal + newGoal, err = client.GetGoal(goal.ID) + assert.Error(t, err) + assert.Nil(t, newGoal) + }) + + t.Run("error from api (status code)", func(t *testing.T) { + client, err := newTestClient() + assert.NoError(t, err) + assert.NotNil(t, client) + + goal := newTestGoal() + + endpoint := fmt.Sprintf( + "%s/%s/details/%d", EnvironmentDevelopment.apiURL, + modelGoal, goal.ID, + ) + err = mockResponseData(http.MethodGet, endpoint, http.StatusBadRequest, goal) + assert.NoError(t, err) + + var newGoal *Goal + newGoal, err = client.GetGoal(goal.ID) + assert.Error(t, err) + assert.Nil(t, newGoal) + }) + + t.Run("error from api (api error)", func(t *testing.T) { + client, err := newTestClient() + assert.NoError(t, err) + assert.NotNil(t, client) + + goal := newTestGoal() + + endpoint := fmt.Sprintf( + "%s/%s/details/%d", EnvironmentDevelopment.apiURL, + modelGoal, goal.ID, + ) + + apiError := &Error{ + Code: 400, + Data: "field_name", + IPAddress: "127.0.0.1", + Message: "some error message", + Method: http.MethodPut, + RequestGUID: "7f3d97a8fd67ff57861904df6118dcc8", + StatusCode: http.StatusBadRequest, + URL: endpoint, + } + + err = mockResponseData(http.MethodGet, endpoint, http.StatusBadRequest, apiError) + assert.NoError(t, err) + + var newGoal *Goal + newGoal, err = client.GetGoal(goal.ID) + assert.Error(t, err) + assert.Nil(t, newGoal) + assert.Equal(t, apiError.Message, err.Error()) + }) +} + +// ExampleClient_GetGoal example using GetGoal() +// +// See more examples in /examples/ +func ExampleClient_GetGoal() { + + // Load the client (using test client for example only) + client, err := newTestClient() + if err != nil { + fmt.Printf("error loading client: %s", err.Error()) + return + } + + // Mock response (for example only) + responseGoal := newTestGoal() + _ = mockResponseData( + http.MethodGet, + fmt.Sprintf( + "%s/%s/details/%d", EnvironmentDevelopment.apiURL, + modelGoal, responseGoal.ID, + ), + http.StatusOK, + responseGoal, + ) + + // Get goal (using mocking response) + if responseGoal, err = client.GetGoal(responseGoal.ID); err != nil { + fmt.Printf("error getting goal: " + err.Error()) + return + } + fmt.Printf("goal: %s", responseGoal.Name) + // Output:goal: example_goal +} + +// BenchmarkClient_GetGoal benchmarks the method GetGoal() +func BenchmarkClient_GetGoal(b *testing.B) { + client, _ := newTestClient() + goal := newTestGoal() + _ = mockResponseData( + http.MethodGet, + fmt.Sprintf( + "%s/%s/details/%d", EnvironmentDevelopment.apiURL, + modelGoal, goal.ID, + ), + http.StatusOK, + goal, + ) + for i := 0; i < b.N; i++ { + _, _ = client.GetGoal(goal.ID) + } +}