Conversation
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## master #2973 +/- ##
========================================
Coverage 97.71% 97.71%
========================================
Files 151 152 +1
Lines 13072 13241 +169
========================================
+ Hits 12773 12939 +166
- Misses 211 213 +2
- Partials 88 89 +1 ☔ View full report in Codecov by Sentry. |
|
CodeCov hasn't updated as of last commit, but I think it should increase the coverage to close to 100% for the new file. |
github/copilot.go
Outdated
| InactiveThisCycle int64 `json:"inactive_this_cycle"` | ||
| } | ||
|
|
||
| type CopilotSeats struct { |
There was a problem hiding this comment.
Missing godoc-style comment.
| "github.com/google/go-cmp/cmp" | ||
| ) | ||
|
|
||
| // Test invalid JSON responses, vlaid responses are covered in the other tests |
There was a problem hiding this comment.
| // Test invalid JSON responses, vlaid responses are covered in the other tests | |
| // Test invalid JSON responses, valid responses are covered in the other tests |
|
Thanks @gmlewis, I'll add in the changes! My bad on the http method being PUT, I was doing some other work with S3 and I think I carried that context over. |
| } | ||
|
|
||
| var copilotSeats *CopilotSeats | ||
| resp, err := s.client.Do(ctx, req, &copilotSeats) |
There was a problem hiding this comment.
How are we handling pagination here for more than 100 users?
There was a problem hiding this comment.
Will be adding support for this, thanks for the callout 🙏
There was a problem hiding this comment.
pagination works in current version
WillAbides
left a comment
There was a problem hiding this comment.
This looks good over all. I realize I left quite a few comments, but they are mostly nit-picks about naming and comments.
github/copilot.go
Outdated
| return nil, nil, err | ||
| } | ||
|
|
||
| var SeatCancellations *SeatCancellations |
There was a problem hiding this comment.
The var name should be downcased "seatCancellations"
There was a problem hiding this comment.
Will do, my bad there
github/copilot.go
Outdated
| return nil, nil, err | ||
| } | ||
|
|
||
| var SeatCancellations *SeatCancellations |
There was a problem hiding this comment.
Downcase seatCancellations
| // CopilotSeatDetails represents the details of a Copilot for Business seat. | ||
| // Assignee can either be a User, Team, or Organization. | ||
| type CopilotSeatDetails struct { | ||
| Assignee interface{} `json:"assignee"` |
There was a problem hiding this comment.
It may be ok to use *User here. There are a few other places where we use *User and let users distinguish using the Type field. @gmlewis will know what the preferred method is.
There was a problem hiding this comment.
I feel like this might be a better option since we're explicitly setting the correct type for the field, but both approaches leave type-checking to the end user.
There are minor differences as far as I'm aware between the types, e.g. Team has no Login field, but has a Name field, which both User and Organization have. Login is used for the username in the case of a user, whereas Name is used for team name.
I'll leave you guys with these thoughts and will be happy to make changes based on what you think.
There was a problem hiding this comment.
That's a good point about Team being different. I think this might be the best way to handle it after all.
github/copilot.go
Outdated
|
|
||
| // AddCopilotTeams Adds teams to the Copilot for Business subscription for an organization | ||
| // | ||
| // https://docs.github.com/en/rest/copilot/copilot-for-business#add-teams-to-the-copilot-for-business-subscription-for-an-organization |
There was a problem hiding this comment.
| // https://docs.github.com/en/rest/copilot/copilot-for-business#add-teams-to-the-copilot-for-business-subscription-for-an-organization | |
| // GitHub API docs: https://docs.github.com/en/rest/copilot/copilot-for-business#add-teams-to-the-copilot-for-business-subscription-for-an-organization |
github/copilot.go
Outdated
|
|
||
| // RemoveCopilotUsers Removes users from the Copilot for Business subscription for an organization | ||
| // | ||
| // https://docs.github.com/en/rest/copilot/copilot-for-business#remove-users-from-the-copilot-for-business-subscription-for-an-organization |
There was a problem hiding this comment.
| // https://docs.github.com/en/rest/copilot/copilot-for-business#remove-users-from-the-copilot-for-business-subscription-for-an-organization | |
| // GitHub API docs: https://docs.github.com/en/rest/copilot/copilot-for-business#remove-users-from-the-copilot-for-business-subscription-for-an-organization |
github/copilot.go
Outdated
|
|
||
| // GetSeatDetails Gets Copilot for Business seat assignment details for a user | ||
| // | ||
| // https://docs.github.com/en/rest/copilot/copilot-for-business#get-copilot-for-business-seat-assignment-details-for-a-user |
There was a problem hiding this comment.
| // https://docs.github.com/en/rest/copilot/copilot-for-business#get-copilot-for-business-seat-assignment-details-for-a-user | |
| // GitHub API docs: https://docs.github.com/en/rest/copilot/copilot-for-business#get-copilot-for-business-seat-assignment-details-for-a-user |
|
Thank you, @WillAbides for your review feedback and @gauraw10 for your excellent pagination question which I seem to frequently forget about until it becomes an issue later, unfortunately. It is definitely better to add pagination support up front rather than later. 😁 I've got some work to do but see that there are some questions for me, so I will try to circle back later this afternoon and address them. |
github/copilot_test.go
Outdated
| tests := map[string]struct { | ||
| data string | ||
| want *CopilotSeatDetails | ||
| wantErr bool | ||
| }{ |
There was a problem hiding this comment.
This could be:
tests := map[string]struct {
name string
data string
} {
{
name: "invalid JSON",
data: `{`,
},
...
}
Two things changed here:
- Make it a slice instead of a map for defined order when testing.
- Because this only tests invalid, the "want" and "wantErr" fields are always the same.
There was a problem hiding this comment.
I can make that change but want your thoughts on keeping the want and wantErr fields. Reason being is as of right now I'm only testing invalid cases and the unmarshaling isn't too complex, but in the future we might be adding valid cases here.
There was a problem hiding this comment.
I'll defer to your judgement on want and wantErr. We may or may not need them in the future, and it doesn't hurt anything to keep them around.
github/copilot_test.go
Outdated
| seatDetails := &CopilotSeatDetails{} | ||
|
|
||
| t.Run(name, func(t *testing.T) { | ||
| err := seatDetails.UnmarshalJSON([]byte(tc.data)) |
There was a problem hiding this comment.
It's better to test with json.Unmarshal instead of directly calling UnmarshalJSON because that is how users will call it.
Co-authored-by: WillAbides <233500+WillAbides@users.noreply.github.com> Co-authored-by: Glenn Lewis <6598971+gmlewis@users.noreply.github.com>
|
Watching the conversations go by, I'm wondering if it might be nice to have 3 helper methods on the struct like Thoughts? |
|
@gmlewis Would that be while keeping |
Yes, that's what I was thinking might be nice, but I'm open to ideas. |
|
I think that |
|
Good call, I wanted to expand coverage for that 🙂 What do you think about not returning errors for unmarshaling the Assignee field once we've done the type assertions? I'm not sure we would get errors there since we know the map matches the type of the struct we're unmarshaling into, and I can't think of a way to test for that. |
|
In general, I would much rather have untested error branches than trust our assumption that an error can't happen and end up with a panic. Even though codecov puts a big, ugly ❌ on your PR, it isn't a hard rule that test coverage can't decrease. That said, I think it will be possible to cover those cases with just the right json data. Let me have a look and see if I can come up with something. |
|
@o-sama I see you have already cases that should cover those lines but don't. I think the problem is the comma at the end of |
|
Ah good catch @WillAbides, it's always the commas 🙃 |
OK, first let me resolve the merge conflicts, @zetaab - then maybe @valbeat has time to take a look at this one. |
Fixes: google#2996.
|
@zetaab - you yourself could move this PR along by performing a review and giving it an LGTM+Approval. |
zetaab
left a comment
There was a problem hiding this comment.
I could not find anything else than that one type change. I am currently coding against this PR and it was little bit weird that the type is not similar than other timestamps.
| // Assignee can either be a User, Team, or Organization. | ||
| Assignee interface{} `json:"assignee"` | ||
| AssigningTeam *Team `json:"assigning_team,omitempty"` | ||
| PendingCancellationDate *string `json:"pending_cancellation_date,omitempty"` |
There was a problem hiding this comment.
type should be *Timestamp instead that it works in similar way than other time fields.
| } | ||
|
|
||
| var copilotSeats *CopilotSeats | ||
| resp, err := s.client.Do(ctx, req, &copilotSeats) |
There was a problem hiding this comment.
pagination works in current version
zetaab
left a comment
There was a problem hiding this comment.
actually that PendingCancellationDate field is date so perhaps leave it like this.
LGTM
|
Thank you, @zetaab ! |
Closes #2938.