-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#720 Initial commit for listing Plans and Plan Accounts #732
Conversation
* Includes basic testing for Listing Plans and the Accounts linked to a Plan (including stubs)
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lackerman, this is a fantastic start!
It seems that we'll need to make some new decisions for this issue, because these endpoints offer something no other GitHub API endpoints have offered in the past: the alternative stubbed endpoints. /cc @gmlewis
I will think a little more about this, but so far, I think we should factor out that stubbed bool
argument from each method. Perhaps, instead, it should be a new option that we add to github.Client
. What do you think about that?
Aside from that, I spotted and pointed out some minor issues with missing periods at ends of sentences, and missing ,omitempty
JSON tag options.
github/apps_marketplace.go
Outdated
Plan *MarketplacePlan `json:"plan"` | ||
} | ||
|
||
// MarketplacePlanAccount represents a GitHub Account (user or organization) on a specific plan |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I think we should strive to have all sentences in Go documentation to have no spelling or grammar mistakes, and to include periods at ends of sentences. So, I'll point out that you're missing a period at the end of this sentence.
github/apps_marketplace.go
Outdated
MarketplacePurchase *MarketplacePurchase `json:"marketplace_purchase"` | ||
} | ||
|
||
// ListPlans lists all plans for your Marketplace listing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also missing a period at end of this sentence.
github/apps_marketplace.go
Outdated
return i, resp, nil | ||
} | ||
|
||
// ListPlanAccounts lists all GitHub accounts (user or organization) on a specific plan |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this one.
github/apps_marketplace.go
Outdated
YearlyPriceInCents *int `json:"yearly_price_in_cents"` | ||
PriceModel *string `json:"price_model"` | ||
UnitName *string `json:"unit_name"` | ||
Bullets *[]string `json:"bullets"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency with other structs that we map to GitHub responses, all of these should have ,omitempty
JSON tag option. E.g., see:
Lines 26 to 52 in 511f540
type Issue struct { | |
ID *int `json:"id,omitempty"` | |
Number *int `json:"number,omitempty"` | |
State *string `json:"state,omitempty"` | |
Locked *bool `json:"locked,omitempty"` | |
Title *string `json:"title,omitempty"` | |
Body *string `json:"body,omitempty"` | |
User *User `json:"user,omitempty"` | |
Labels []Label `json:"labels,omitempty"` | |
Assignee *User `json:"assignee,omitempty"` | |
Comments *int `json:"comments,omitempty"` | |
ClosedAt *time.Time `json:"closed_at,omitempty"` | |
CreatedAt *time.Time `json:"created_at,omitempty"` | |
UpdatedAt *time.Time `json:"updated_at,omitempty"` | |
ClosedBy *User `json:"closed_by,omitempty"` | |
URL *string `json:"url,omitempty"` | |
HTMLURL *string `json:"html_url,omitempty"` | |
Milestone *Milestone `json:"milestone,omitempty"` | |
PullRequestLinks *PullRequestLinks `json:"pull_request,omitempty"` | |
Repository *Repository `json:"repository,omitempty"` | |
Reactions *Reactions `json:"reactions,omitempty"` | |
Assignees []*User `json:"assignees,omitempty"` | |
// TextMatches is only populated from search results that request text matches | |
// See: search.go and https://developer.github.com/v3/search/#text-match-metadata | |
TextMatches []TextMatch `json:"text_matches,omitempty"` | |
} |
It doesn't make a difference for unmarshaling JSON, but it does for marshaling. I don't think these will be marshaled (since we're receiving data from GitHub API, not sending these upstream). So, the only reason to do it is to maintain consistency.
See issue #537 for some more background information on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering why they were there. I didn't realise that they had no impact on unmarshalling (but it makes perfect sense). Happy to maintain the consistency.
I signed it! |
CLAs look good, thanks! |
@shurcooL Regarding
I'm so happy you said that. The flag felt like suck a hack. Not sure I have enough context or experience to comment on the preferred solution, but I'm happy to implement it ;). |
Hi @shurcooL, could you perhaps tell me why the build is failing? I see it's during the |
622c3d3
to
9157290
Compare
@lackerman You need to run the command |
Nice work on resolving the build failure.
Great! The next step here, as far as I can tell, is to factor out that Looking at it a bit closer, I think we can move it into // 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
} Then, users can set it to true if they wish: client := github.NewClient(nil)
client.MarketplaceService.Stubbed = true
// ... |
Hi @shurcooL what about using a Options wrapper? // MarketplaceOptions specifies the optional parameters to the Marketplace service methods
type MarketplaceOptions struct {
// 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
ListOptions
} And then only passing
Or is this pattern specifically used for optional query parameters in the Url? |
I think it largely depends on how often one wants to set Stubbed to true. From my current understanding how it's meant to be used, it makes more sense to me to set it once for the entire service while doing testing, rather than for each individual endpoint via the options. So, unless I'm not understanding the use case properly, I still prefer my @gmlewis @elliott-beach Do you have thoughts/preferences on how to deal with the stubbed parameter? |
Hi @shurcooL, this is probably due to my own ignorance of the language, but when I try your suggested implementation, I get:
since the Service is of type |
@lackerman You wouldn't be able to reuse -c.Marketplace = (*MarketplaceService)(&c.common)
+c.Marketplace = &MarketplaceService{client: c} |
Thanks for the help @shurcooL. Please could I ask you to explain the difference between the following two calling conventions: |
@lackerman It works for other services because they're defined as type ActivityService service So You can find more information about this in #389 and #390 that introduced it. Note, this is a pretty advanced trick, it's not commonly done, and the benefits it offers are nice but not critical. |
Ah, a colleague pointed out that it's just a type cast. Due to the syntax |
Yes, it is. Although if you want to be precise about terms, it's a "type conversion". See https://golang.org/ref/spec#Conversions:
Hence |
…tead of service Added a flag, `stubbed` to the MarketplaceService struct to set whether or not the Service should called the stubbed endpoints
Hi @shurcooL, I've completed the unit tests and performed a basic test to my account on one of the stubbed endpoints and it appears to work as expected. |
Good to hear! I'm not seeing any new commits. Did you mean to push something that implements the changes we discussed above? |
@shurcooL, sad panda...yeah, I forgot to push. It's pushed now. |
github/apps_marketplace.go
Outdated
// GitHub API docs: https://developer.github.com/v3/apps/marketplace/ | ||
Stubbed bool | ||
|
||
ListOptions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ListOptions
probably doesn't belong here in a service struct, does it? I'm guessing we forgot to remove it from back when we considered a MarketplaceOptions
wrapper, yeah?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yurp, pushed a fix.
@shurcooL fixed the issue you pointed out. |
Sorry for the delay - yes, I like the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @lackerman for doing this! I have just a few things to fix if you don't mind.
github/apps_marketplace.go
Outdated
@@ -0,0 +1,180 @@ | |||
// Copyright 2013 The go-github AUTHORS. All rights reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/2013/2017/
// 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. | ||
// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: lines 23-24 are unnecessary due to line 16 above. Please remove them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmlewis See https://github.com/google/go-github/pull/732/files#r148168072 for why I think it's still helpful to include them. It just so happens the URL matches the one for the service, I wish we could link to a more specific section, but I don't see one...
github/apps_marketplace.go
Outdated
// MarketplacePlanAccount represents a GitHub Account (user or organization) on a specific plan. | ||
type MarketplacePlanAccount struct { | ||
URL *string `json:"url,omitempty"` | ||
AccountType *string `json:"type,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to not call this Type
(instead of AccountType
)?
I say this because it seems stuttery to me... e.g. account.AccountType
vs account.Type
.
github/apps_marketplace.go
Outdated
NextBillingDate *string `json:"next_billing_date,omitempty"` | ||
UnitCount *int `json:"unit_count,omitempty"` | ||
Plan *MarketplacePlan `json:"plan,omitempty"` | ||
MarketplacePlanAccount *MarketplacePlanAccount `json:"account,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/MarketPlanAccount/Account/
Let's keep the names matching as closely to the JSON tag as possible.
github/apps_marketplace.go
Outdated
// TODO: remove custom Accept header when this API fully launches. | ||
req.Header.Set("Accept", mediaTypeMarketplacePreview) | ||
|
||
var i []*MarketplacePlan |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/i/plans/
i
usually connotes an index and since this variable is significant and not just any ordinary temp value, I think giving it a meaningful name here improves readability.
github/apps_marketplace.go
Outdated
// TODO: remove custom Accept header when this API fully launches. | ||
req.Header.Set("Accept", mediaTypeMarketplacePreview) | ||
|
||
var i []*MarketplacePlanAccount |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/i/accounts/
github/apps_marketplace.go
Outdated
// TODO: remove custom Accept header when this API fully launches. | ||
req.Header.Set("Accept", mediaTypeMarketplacePreview) | ||
|
||
var i []*MarketplacePurchase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/i/purchases/
github/apps_marketplace_test.go
Outdated
@@ -0,0 +1,202 @@ | |||
// Copyright 2013 The go-github AUTHORS. All rights reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/2013/2017/
}) | ||
|
||
opt := &ListOptions{Page: 1, PerPage: 2} | ||
client.Marketplace.Stubbed = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm... I wish we didn't use a package global client
for unit testing, as this will prevent unit tests from all being run in parallel in the future.
Ideally, we would have something like:
client, teardown := setup()
defer teardown()
for each test. No action is needed in this PR, but I'll file a new issue and point here for motivation.
github/github.go
Outdated
@@ -143,6 +146,7 @@ type Client struct { | |||
Licenses *LicensesService | |||
Migrations *MigrationService | |||
Reactions *ReactionsService | |||
Marketplace *MarketplaceService |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's also move this one two lines up to keep this list sorted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have no problem moving it up, but note that there are items higher in the list which are not sorted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you mind sorting them while you are here, please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Thanks @gmlewis for the extra pair of eyes, really appreciate the suggestions. |
github/apps_marketplace.go
Outdated
@@ -162,13 +160,13 @@ func (s *MarketplaceService) ListMarketplacePurchasesForUser(ctx context.Context | |||
// TODO: remove custom Accept header when this API fully launches. | |||
req.Header.Set("Accept", mediaTypeMarketplacePreview) | |||
|
|||
var i []*MarketplacePurchase | |||
resp, err := s.client.Do(ctx, req, &i) | |||
var purchaces []*MarketplacePurchase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s/purchaces/purchases/
github/github.go
Outdated
@@ -136,16 +139,17 @@ type Client struct { | |||
Gists *GistsService | |||
Git *GitService | |||
Gitignores *GitignoresService | |||
Licenses *LicensesService |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Licenses
after Issues
, please. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will it ever end... :P Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @lackerman!
LGTM.
Awaiting second LGTM before merging.
github/apps_marketplace.go
Outdated
// 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. | ||
Stubbed bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This Stubbed
field is quite unusual and may cause people to seek more information about it. I think it's worth it to include a link to GitHub API documentation for it as well here, as I suggested in #732 (comment):
// 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
This is also a way of us hinting that it's not our own invention specific to go-github
Go library, but a GitHub API feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gmlewis Does that sound good to you?
If so, I can apply it and merge. Edit: @lackerman has already pushed ecac90f.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one suggested change about Stubbed
field documentation, see comment above. Otherwise LGTM.
@shurcooL, updated |
@shurcooL not sure why the build failed after adding a comment line |
We have some issues with gen-accessors right now, I've filed #778 for it. But fixing that is out of scope of this PR, so just re-generate the package, and it should be fine. |
@shurcooL ready to be merged |
Merged. Thank you @lackerman! |
NOTE This is currently awaiting scrutiny as it's my first contribution to the project. I would appreciate any feedback (good or bad) and the 👍 if it's ok to carry on with the rest of the implementation for #720