Skip to content

Commit

Permalink
Reworked examples, create campaign test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
mrz1836 committed Jun 4, 2021
1 parent e8f8aec commit ed17507
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 35 deletions.
2 changes: 1 addition & 1 deletion advertiser_profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (a *AdvertiserProfile) permitFields() {
// For more information: https://docs.tonicpow.com/#b3a62d35-7778-4314-9321-01f5266c3b51
func (c *Client) GetAdvertiserProfile(profileID uint64) (profile *AdvertiserProfile, err error) {

// Must have an id
// Must have an ID
if profileID == 0 {
err = fmt.Errorf("missing field: %s", fieldID)
return
Expand Down
73 changes: 39 additions & 34 deletions campaigns.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,44 @@ func (c *Campaign) permitFields() {
c.PublicGUID = ""
}

// CreateCampaign will make a new campaign
// CreateCampaign will make a new campaign for the associated advertiser profile
//
// For more information: https://docs.tonicpow.com/#b67e92bf-a481-44f6-a31d-26e6e0c521b1
func (c *Client) CreateCampaign(campaign *Campaign) (err error) {
func (c *Client) CreateCampaign(campaign *Campaign) error {

// Basic requirements
if campaign.AdvertiserProfileID == 0 {
err = fmt.Errorf("missing required attribute: %s", fieldAdvertiserProfileID)
return
return fmt.Errorf("missing required attribute: %s", fieldAdvertiserProfileID)
} else if len(campaign.Title) == 0 {
return fmt.Errorf("missing required attribute: %s", fieldTitle)
} else if len(campaign.Description) == 0 {
return fmt.Errorf("missing required attribute: %s", fieldDescription)
} else if len(campaign.TargetURL) == 0 {
return fmt.Errorf("missing required attribute: %s", fieldTargetURL)
}

// Fire the Request
var response StandardResponse
var err error
if response, err = c.Request(
http.MethodPost,
"/"+modelCampaign,
nil, http.StatusCreated,
campaign, http.StatusCreated,
); err != nil {
return
return err
}

// Convert model response
err = json.Unmarshal(response.Body, &campaign)
return
return json.Unmarshal(response.Body, &campaign)
}

// GetCampaign will get an existing campaign
// GetCampaign will get an existing campaign by ID
// This will return an Error if the campaign is not found (404)
//
// For more information: https://docs.tonicpow.com/#b827446b-be34-4678-b347-33c4f63dbf9e
func (c *Client) GetCampaign(campaignID uint64) (campaign *Campaign, err error) {

// Must have an id
// Must have an ID
if campaignID == 0 {
err = fmt.Errorf("missing required attribute: %s", fieldID)
return
Expand All @@ -71,13 +76,13 @@ func (c *Client) GetCampaign(campaignID uint64) (campaign *Campaign, err error)
return
}

// GetCampaignBySlug will get an existing campaign
// GetCampaignBySlug will get an existing campaign by slug
// This will return an Error if the campaign is not found (404)
//
// For more information: https://docs.tonicpow.com/#b827446b-be34-4678-b347-33c4f63dbf9e
func (c *Client) GetCampaignBySlug(slug string) (campaign *Campaign, err error) {

// Must have an id
// Must have a slug
if len(slug) == 0 {
err = fmt.Errorf("missing required attribute: %s", fieldSlug)
return
Expand Down Expand Up @@ -126,7 +131,27 @@ func (c *Client) UpdateCampaign(campaign *Campaign) (err error) {
return
}

// ListCampaigns will return a list of active campaigns
// CampaignsFeed will return a feed of active campaigns
// This will return an Error if no campaigns are found (404)
//
// For more information: https://docs.tonicpow.com/#b3fe69d3-24ba-4c2a-a485-affbb0a738de
func (c *Client) CampaignsFeed(feedType feedType) (feed string, err error) {

// Fire the Request
var response StandardResponse
if response, err = c.Request(
http.MethodGet,
fmt.Sprintf("/%s/feed?%s=%s", modelCampaign, fieldFeedType, feedType),
nil, http.StatusOK,
); err != nil {
return
}

feed = string(response.Body)
return
}

// ListCampaigns will return a list of campaigns
// This will return an Error if the campaign is not found (404)
//
// For more information: https://docs.tonicpow.com/#c1b17be6-cb10-48b3-a519-4686961ff41c
Expand Down Expand Up @@ -168,7 +193,7 @@ func (c *Client) ListCampaigns(page, resultsPerPage int, sortBy, sortOrder, sear
return
}

// ListCampaignsByURL will return a list of active campaigns
// ListCampaignsByURL will return a list of campaigns
// This will return an Error if the url is not found (404)
//
// todo: update with list campaigns functionality
Expand Down Expand Up @@ -211,23 +236,3 @@ func (c *Client) ListCampaignsByURL(targetURL string, page, resultsPerPage int,
err = json.Unmarshal(response.Body, &results)
return
}

// CampaignsFeed will return a feed of active campaigns
// This will return an Error if no campaigns are found (404)
//
// For more information: https://docs.tonicpow.com/#b3fe69d3-24ba-4c2a-a485-affbb0a738de
func (c *Client) CampaignsFeed(feedType feedType) (feed string, err error) {

// Fire the Request
var response StandardResponse
if response, err = c.Request(
http.MethodGet,
fmt.Sprintf("/%s/feed?%s=%s", modelCampaign, fieldFeedType, feedType),
nil, http.StatusOK,
); err != nil {
return
}

feed = string(response.Body)
return
}
190 changes: 190 additions & 0 deletions campaigns_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
package tonicpow

import (
"fmt"
"net/http"
"testing"

"github.com/stretchr/testify/assert"
)

// newTestCampaign will return a dummy example for tests
func newTestCampaign() *Campaign {
return &Campaign{
Expand Down Expand Up @@ -57,3 +65,185 @@ func newTestCampaignResults(currentPage, resultsPerPage int) *CampaignResults {
ResultsPerPage: resultsPerPage,
}
}

// TestClient_CreateCampaign will test the method CreateCampaign()
func TestClient_CreateCampaign(t *testing.T) {
// t.Parallel() (Cannot run in parallel - issues with overriding the mock client)

t.Run("create a campaign (success)", func(t *testing.T) {
client, err := newTestClient()
assert.NoError(t, err)
assert.NotNil(t, client)

campaign := newTestCampaign()

endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelCampaign)

err = mockResponseData(http.MethodPost, endpoint, http.StatusCreated, campaign)
assert.NoError(t, err)

err = client.CreateCampaign(campaign)
assert.NoError(t, err)
assert.NotNil(t, campaign)
assert.Equal(t, testCampaignID, campaign.ID)
})

t.Run("missing advertiser profile id", func(t *testing.T) {
client, err := newTestClient()
assert.NoError(t, err)
assert.NotNil(t, client)

campaign := newTestCampaign()
campaign.AdvertiserProfileID = 0

endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelCampaign)

err = mockResponseData(http.MethodPost, endpoint, http.StatusCreated, campaign)
assert.NoError(t, err)

err = client.CreateCampaign(campaign)
assert.Error(t, err)
})

t.Run("missing campaign title", func(t *testing.T) {
client, err := newTestClient()
assert.NoError(t, err)
assert.NotNil(t, client)

campaign := newTestCampaign()
campaign.Title = ""

endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelCampaign)

err = mockResponseData(http.MethodPost, endpoint, http.StatusCreated, campaign)
assert.NoError(t, err)

err = client.CreateCampaign(campaign)
assert.Error(t, err)
})

t.Run("missing campaign description", func(t *testing.T) {
client, err := newTestClient()
assert.NoError(t, err)
assert.NotNil(t, client)

campaign := newTestCampaign()
campaign.Description = ""

endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelCampaign)

err = mockResponseData(http.MethodPost, endpoint, http.StatusCreated, campaign)
assert.NoError(t, err)

err = client.CreateCampaign(campaign)
assert.Error(t, err)
})

t.Run("missing campaign target url", func(t *testing.T) {
client, err := newTestClient()
assert.NoError(t, err)
assert.NotNil(t, client)

campaign := newTestCampaign()
campaign.TargetURL = ""

endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelCampaign)

err = mockResponseData(http.MethodPost, endpoint, http.StatusCreated, campaign)
assert.NoError(t, err)

err = client.CreateCampaign(campaign)
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)

campaign := newTestCampaign()

endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelCampaign)

err = mockResponseData(http.MethodPost, endpoint, http.StatusBadRequest, campaign)
assert.NoError(t, err)

err = client.CreateCampaign(campaign)
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)

campaign := newTestCampaign()

endpoint := fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelCampaign)

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.CreateCampaign(campaign)
assert.Error(t, err)
assert.Equal(t, apiError.Message, err.Error())
})
}

// ExampleClient_CreateCampaign example using CreateCampaign()
//
// See more examples in /examples/
func ExampleClient_CreateCampaign() {

// Load the client (using test client for example only)
client, err := newTestClient()
if err != nil {
fmt.Printf("error loading client: %s", err.Error())
return
}

// For mocking
responseCampaign := newTestCampaign()

// Mock response (for example only)
_ = mockResponseData(
http.MethodPost,
fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelCampaign),
http.StatusCreated,
responseCampaign,
)

// Create campaign (using mocking response)
if err = client.CreateCampaign(responseCampaign); err != nil {
fmt.Printf("error creating campaign: " + err.Error())
return
}
fmt.Printf("created campaign: %s", responseCampaign.Title)
// Output:created campaign: TonicPow
}

// BenchmarkClient_CreateCampaign benchmarks the method CreateCampaign()
func BenchmarkClient_CreateCampaign(b *testing.B) {
client, _ := newTestClient()
campaign := newTestCampaign()
_ = mockResponseData(
http.MethodPost,
fmt.Sprintf("%s/%s", EnvironmentDevelopment.apiURL, modelCampaign),
http.StatusCreated,
campaign,
)
for i := 0; i < b.N; i++ {
_ = client.CreateCampaign(campaign)
}
}
2 changes: 2 additions & 0 deletions definitions.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const (
fieldCurrentPage = "current_page"
fieldCustomDimensions = "custom_dimensions"
fieldDelayInMinutes = "delay_in_minutes"
fieldDescription = "description"
fieldExpired = "expired"
fieldFeedType = "feed_type"
fieldGoalID = "goal_id"
Expand All @@ -34,6 +35,7 @@ const (
fieldSortBy = "sort_by"
fieldSortOrder = "sort_order"
fieldTargetURL = "target_url"
fieldTitle = "title"
fieldUserID = "user_id"
fieldVisitorSessionGUID = "tncpw_session"

Expand Down
File renamed without changes.
30 changes: 30 additions & 0 deletions examples/advertiser_profiles/list_apps/list_apps.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
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 the apps
var results *tonicpow.AppResults
if results, err = client.ListAppsByAdvertiserProfile(
23, 1, 5, "", "",
); err != nil {
log.Fatalf("error in ListAppsByAdvertiserProfile: %s", err.Error())
}

log.Printf("results: %d", results.Results)
}
Loading

0 comments on commit ed17507

Please sign in to comment.