Skip to content

Commit

Permalink
Add MarketplaceService for listing Plans and Plan Accounts. (#732)
Browse files Browse the repository at this point in the history
  • Loading branch information
lackerman authored and dmitshur committed Nov 14, 2017
1 parent 8c08f4f commit 8b3951c
Show file tree
Hide file tree
Showing 4 changed files with 582 additions and 3 deletions.
180 changes: 180 additions & 0 deletions github/apps_marketplace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
// Copyright 2017 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package github

import (
"context"
"fmt"
)

// MarketplaceService handles communication with the marketplace related
// methods of the GitHub API.
//
// GitHub API docs: https://developer.github.com/v3/apps/marketplace/
type MarketplaceService struct {
client *Client
// Stubbed controls whether endpoints that return stubbed data are used
// instead of production endpoints. Stubbed data is fake data that's useful
// for testing your GitHub Apps. Stubbed data is hard-coded and will not
// change based on actual subscriptions.
//
// GitHub API docs: https://developer.github.com/v3/apps/marketplace/
Stubbed bool
}

// MarketplacePlan represents a GitHub Apps Marketplace Listing Plan.
type MarketplacePlan struct {
URL *string `json:"url,omitempty"`
AccountsURL *string `json:"accounts_url,omitempty"`
ID *int `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
MonthlyPriceInCents *int `json:"monthly_price_in_cents,omitempty"`
YearlyPriceInCents *int `json:"yearly_price_in_cents,omitempty"`
PriceModel *string `json:"price_model,omitempty"`
UnitName *string `json:"unit_name,omitempty"`
Bullets *[]string `json:"bullets,omitempty"`
}

// MarketplacePurchase represents a GitHub Apps Marketplace Purchase.
type MarketplacePurchase struct {
BillingCycle *string `json:"billing_cycle,omitempty"`
NextBillingDate *string `json:"next_billing_date,omitempty"`
UnitCount *int `json:"unit_count,omitempty"`
Plan *MarketplacePlan `json:"plan,omitempty"`
Account *MarketplacePlanAccount `json:"account,omitempty"`
}

// MarketplacePlanAccount represents a GitHub Account (user or organization) on a specific plan.
type MarketplacePlanAccount struct {
URL *string `json:"url,omitempty"`
Type *string `json:"type,omitempty"`
ID *int `json:"id,omitempty"`
Login *string `json:"login,omitempty"`
Email *string `json:"email,omitempty"`
OrganizationBillingEmail *string `json:"organization_billing_email,omitempty"`
MarketplacePurchase *MarketplacePurchase `json:"marketplace_purchase,omitempty"`
}

// ListPlans lists all plans for your Marketplace listing.
//
// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-plans-for-your-marketplace-listing
func (s *MarketplaceService) ListPlans(ctx context.Context, opt *ListOptions) ([]*MarketplacePlan, *Response, error) {
uri := s.marketplaceURI("plans")
u, err := addOptions(uri, opt)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMarketplacePreview)

var plans []*MarketplacePlan
resp, err := s.client.Do(ctx, req, &plans)
if err != nil {
return nil, resp, err
}

return plans, resp, nil
}

// ListPlanAccountsForPlan lists all GitHub accounts (user or organization) on a specific plan.
//
// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#list-all-github-accounts-user-or-organization-on-a-specific-plan
func (s *MarketplaceService) ListPlanAccountsForPlan(ctx context.Context, planID int, opt *ListOptions) ([]*MarketplacePlanAccount, *Response, error) {
uri := s.marketplaceURI(fmt.Sprintf("plans/%v/accounts", planID))
u, err := addOptions(uri, opt)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMarketplacePreview)

var accounts []*MarketplacePlanAccount
resp, err := s.client.Do(ctx, req, &accounts)
if err != nil {
return nil, resp, err
}

return accounts, resp, nil
}

// ListPlanAccountsForAccount lists all GitHub accounts (user or organization) associated with an account.
//
// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#check-if-a-github-account-is-associated-with-any-marketplace-listing
func (s *MarketplaceService) ListPlanAccountsForAccount(ctx context.Context, accountID int, opt *ListOptions) ([]*MarketplacePlanAccount, *Response, error) {
uri := s.marketplaceURI(fmt.Sprintf("accounts/%v", accountID))
u, err := addOptions(uri, opt)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMarketplacePreview)

var accounts []*MarketplacePlanAccount
resp, err := s.client.Do(ctx, req, &accounts)
if err != nil {
return nil, resp, err
}

return accounts, resp, nil
}

// ListMarketplacePurchasesForUser lists all GitHub marketplace purchases made by a user.
//
// GitHub API docs: https://developer.github.com/v3/apps/marketplace/#get-a-users-marketplace-purchases
func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context, opt *ListOptions) ([]*MarketplacePurchase, *Response, error) {
uri := "user/marketplace_purchases"
if s.Stubbed {
uri = "user/marketplace_purchases/stubbed"
}

u, err := addOptions(uri, opt)
if err != nil {
return nil, nil, err
}

req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}

// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMarketplacePreview)

var purchases []*MarketplacePurchase
resp, err := s.client.Do(ctx, req, &purchases)
if err != nil {
return nil, resp, err
}

return purchases, resp, nil
}

func (s *MarketplaceService) marketplaceURI(endpoint string) string {
url := "marketplace_listing"
if s.Stubbed {
url = "marketplace_listing/stubbed"
}
return url + "/" + endpoint
}
202 changes: 202 additions & 0 deletions github/apps_marketplace_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
// Copyright 2017 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package github

import (
"context"
"fmt"
"net/http"
"reflect"
"testing"
)

func TestMarketplaceService_ListPlans(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/marketplace_listing/plans", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMarketplacePreview)
testFormValues(t, r, values{
"page": "1",
"per_page": "2",
})
fmt.Fprint(w, `[{"id":1}]`)
})

opt := &ListOptions{Page: 1, PerPage: 2}
client.Marketplace.Stubbed = false
plans, _, err := client.Marketplace.ListPlans(context.Background(), opt)
if err != nil {
t.Errorf("Marketplace.ListPlans returned error: %v", err)
}

want := []*MarketplacePlan{{ID: Int(1)}}
if !reflect.DeepEqual(plans, want) {
t.Errorf("Marketplace.ListPlans returned %+v, want %+v", plans, want)
}
}

func TestMarketplaceService_Stubbed_ListPlans(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/marketplace_listing/stubbed/plans", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMarketplacePreview)
fmt.Fprint(w, `[{"id":1}]`)
})

opt := &ListOptions{Page: 1, PerPage: 2}
client.Marketplace.Stubbed = true
plans, _, err := client.Marketplace.ListPlans(context.Background(), opt)
if err != nil {
t.Errorf("Marketplace.ListPlans (Stubbed) returned error: %v", err)
}

want := []*MarketplacePlan{{ID: Int(1)}}
if !reflect.DeepEqual(plans, want) {
t.Errorf("Marketplace.ListPlans (Stubbed) returned %+v, want %+v", plans, want)
}
}

func TestMarketplaceService_ListPlanAccountsForPlan(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/marketplace_listing/plans/1/accounts", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMarketplacePreview)
fmt.Fprint(w, `[{"id":1}]`)
})

opt := &ListOptions{Page: 1, PerPage: 2}
client.Marketplace.Stubbed = false
accounts, _, err := client.Marketplace.ListPlanAccountsForPlan(context.Background(), 1, opt)
if err != nil {
t.Errorf("Marketplace.ListPlanAccountsForPlan returned error: %v", err)
}

want := []*MarketplacePlanAccount{{ID: Int(1)}}
if !reflect.DeepEqual(accounts, want) {
t.Errorf("Marketplace.ListPlanAccountsForPlan returned %+v, want %+v", accounts, want)
}
}

func TestMarketplaceService_Stubbed_ListPlanAccountsForPlan(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/marketplace_listing/stubbed/plans/1/accounts", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMarketplacePreview)
fmt.Fprint(w, `[{"id":1}]`)
})

opt := &ListOptions{Page: 1, PerPage: 2}
client.Marketplace.Stubbed = true
accounts, _, err := client.Marketplace.ListPlanAccountsForPlan(context.Background(), 1, opt)
if err != nil {
t.Errorf("Marketplace.ListPlanAccountsForPlan (Stubbed) returned error: %v", err)
}

want := []*MarketplacePlanAccount{{ID: Int(1)}}
if !reflect.DeepEqual(accounts, want) {
t.Errorf("Marketplace.ListPlanAccountsForPlan (Stubbed) returned %+v, want %+v", accounts, want)
}
}

func TestMarketplaceService_ListPlanAccountsForAccount(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/marketplace_listing/accounts/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMarketplacePreview)
fmt.Fprint(w, `[{"id":1}]`)
})

opt := &ListOptions{Page: 1, PerPage: 2}
client.Marketplace.Stubbed = false
accounts, _, err := client.Marketplace.ListPlanAccountsForAccount(context.Background(), 1, opt)
if err != nil {
t.Errorf("Marketplace.ListPlanAccountsForAccount returned error: %v", err)
}

want := []*MarketplacePlanAccount{{ID: Int(1)}}
if !reflect.DeepEqual(accounts, want) {
t.Errorf("Marketplace.ListPlanAccountsForAccount returned %+v, want %+v", accounts, want)
}
}

func TestMarketplaceService_Stubbed_ListPlanAccountsForAccount(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/marketplace_listing/stubbed/accounts/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMarketplacePreview)
fmt.Fprint(w, `[{"id":1}]`)
})

opt := &ListOptions{Page: 1, PerPage: 2}
client.Marketplace.Stubbed = true
accounts, _, err := client.Marketplace.ListPlanAccountsForAccount(context.Background(), 1, opt)
if err != nil {
t.Errorf("Marketplace.ListPlanAccountsForAccount (Stubbed) returned error: %v", err)
}

want := []*MarketplacePlanAccount{{ID: Int(1)}}
if !reflect.DeepEqual(accounts, want) {
t.Errorf("Marketplace.ListPlanAccountsForAccount (Stubbed) returned %+v, want %+v", accounts, want)
}
}

func TestMarketplaceService_ListMarketplacePurchasesForUser(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/user/marketplace_purchases", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMarketplacePreview)
fmt.Fprint(w, `[{"billing_cycle":"monthly"}]`)
})

opt := &ListOptions{Page: 1, PerPage: 2}
client.Marketplace.Stubbed = false
purchases, _, err := client.Marketplace.ListMarketplacePurchasesForUser(context.Background(), opt)
if err != nil {
t.Errorf("Marketplace.ListMarketplacePurchasesForUser returned error: %v", err)
}

want := []*MarketplacePurchase{{BillingCycle: String("monthly")}}
if !reflect.DeepEqual(purchases, want) {
t.Errorf("Marketplace.ListMarketplacePurchasesForUser returned %+v, want %+v", purchases, want)
}
}

func TestMarketplaceService_Stubbed_ListMarketplacePurchasesForUser(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc("/user/marketplace_purchases/stubbed", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMarketplacePreview)
fmt.Fprint(w, `[{"billing_cycle":"monthly"}]`)
})

opt := &ListOptions{Page: 1, PerPage: 2}
client.Marketplace.Stubbed = true
purchases, _, err := client.Marketplace.ListMarketplacePurchasesForUser(context.Background(), opt)
if err != nil {
t.Errorf("Marketplace.ListMarketplacePurchasesForUser returned error: %v", err)
}

want := []*MarketplacePurchase{{BillingCycle: String("monthly")}}
if !reflect.DeepEqual(purchases, want) {
t.Errorf("Marketplace.ListMarketplacePurchasesForUser returned %+v, want %+v", purchases, want)
}
}
Loading

0 comments on commit 8b3951c

Please sign in to comment.