Skip to content

Commit c747583

Browse files
committed
make GetReposContentsByOwnerByRepoByPath path optional
This PR also updates from v69-v71 as a side effect of re-running mock generation. This change extends the work done by @szesch based on the PR commentary in migueleliasweb#81
1 parent 478be8d commit c747583

10 files changed

+179
-50
lines changed

go.mod

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
module github.com/migueleliasweb/go-github-mock
22

3-
go 1.23
3+
go 1.23.0
4+
5+
toolchain go1.24.1
46

57
require (
68
github.com/buger/jsonparser v1.1.1
7-
github.com/google/go-github/v69 v69.2.0
9+
github.com/google/go-github/v71 v71.0.0
810
github.com/gorilla/mux v1.8.0
911
golang.org/x/mod v0.17.0
1012
golang.org/x/text v0.19.0

go.sum

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
22
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
33
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
4-
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
5-
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
6-
github.com/google/go-github/v69 v69.2.0 h1:wR+Wi/fN2zdUx9YxSmYE0ktiX9IAR/BeePzeaUUbEHE=
7-
github.com/google/go-github/v69 v69.2.0/go.mod h1:xne4jymxLR6Uj9b7J7PyTpkMYstEMMwGZa0Aehh1azM=
4+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
5+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
6+
github.com/google/go-github/v71 v71.0.0 h1:Zi16OymGKZZMm8ZliffVVJ/Q9YZreDKONCr+WUd0Z30=
7+
github.com/google/go-github/v71 v71.0.0/go.mod h1:URZXObp2BLlMjwu0O8g4y6VBneUj2bCHgnI8FfgZ51M=
88
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
99
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
1010
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=

main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"strings"
1212

1313
"github.com/buger/jsonparser"
14-
"github.com/google/go-github/v69/github"
14+
"github.com/google/go-github/v71/github"
1515

1616
"github.com/migueleliasweb/go-github-mock/src/gen"
1717
"golang.org/x/mod/modfile"
@@ -161,7 +161,7 @@ func updateGoGithubDep() {
161161
}
162162
}
163163

164-
// e.g. "v69.2.0" => "v69"
164+
// e.g. "v71.0.0" => "v69"
165165
latestGoGithubPath := "github.com/google/go-github/" + strings.Split(*releaseInfo.TagName, ".")[0]
166166
latestGoGithubVersion := *releaseInfo.TagName
167167

src/gen/gen_mutations.go

+17-14
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,22 @@ import (
66
"strings"
77
)
88

9-
var enabledMutators = map[string]func(ScrapeResult) ScrapeResult{
10-
"/repos/{owner}/{repo}/contents/{path}": allowExtendedLastParamMutatorHelper(),
11-
"/repos/{owner}/{repo}/git/ref/{ref}": allowExtendedLastParamMutatorHelper(),
12-
"/repos/{owner}/{repo}/git/refs/{ref}": allowExtendedLastParamMutatorHelper(), // thanks for the consistency, GitHub
13-
"/repos/{owner}/{repo}/commits/{ref}": allowExtendedLastParamMutatorHelper(), // thanks for not base64encode the parameter, GitHub
14-
"/repos/{owner}/{repo}/issues/{issue_number}/labels/{name}": allowExtendedLastParamMutatorHelper(),
15-
"/orgs/{org}/actions/runners/{runner_id}/labels/{name}": allowExtendedLastParamMutatorHelper(),
16-
"/repos/{owner}/{repo}/labels/{name}": allowExtendedLastParamMutatorHelper(),
9+
const (
10+
OptionalLastParameter = "{%s:.*}"
11+
ExtendedLastParameter = "{%s:.+}"
12+
)
13+
14+
var enabledMutations = map[string]string{
15+
"/repos/{owner}/{repo}/contents/{path}": OptionalLastParameter,
16+
"/repos/{owner}/{repo}/git/ref/{ref}": ExtendedLastParameter,
17+
"/repos/{owner}/{repo}/git/refs/{ref}": ExtendedLastParameter,
18+
"/repos/{owner}/{repo}/commits/{ref}": ExtendedLastParameter,
19+
"/repos/{owner}/{repo}/issues/{issue_number}/labels/{name}": ExtendedLastParameter,
20+
"/orgs/{org}/actions/runners/{runner_id}/labels/{name}": ExtendedLastParameter,
21+
"/repos/{owner}/{repo}/labels/{name}": ExtendedLastParameter,
1722
}
1823

19-
// allowExtendedLastParamMutatorHelper mutates the last param of the endpoint pattern
20-
// allowing it to have any characters (including slashes)
21-
func allowExtendedLastParamMutatorHelper() func(ScrapeResult) ScrapeResult {
24+
func mutator(formatString string) func(ScrapeResult) ScrapeResult {
2225
return func(sr ScrapeResult) ScrapeResult {
2326
endpointSplits := strings.Split(sr.EndpointPattern, "/")
2427
lastParam := endpointSplits[len(endpointSplits)-1]
@@ -27,7 +30,7 @@ func allowExtendedLastParamMutatorHelper() func(ScrapeResult) ScrapeResult {
2730

2831
lastParamCleaned := r.FindString(lastParam)
2932

30-
endpointSplits[len(endpointSplits)-1] = fmt.Sprintf("{%s:.+}", lastParamCleaned)
33+
endpointSplits[len(endpointSplits)-1] = fmt.Sprintf(formatString, lastParamCleaned)
3134

3235
sr.EndpointPattern = strings.Join(endpointSplits, "/")
3336

@@ -40,8 +43,8 @@ func allowExtendedLastParamMutatorHelper() func(ScrapeResult) ScrapeResult {
4043
// There are some edge cases due to inconsistencies between GitHub's OpenAPI definition
4144
// compared to the real world.
4245
func applyMutation(sr ScrapeResult) ScrapeResult {
43-
if mutator, found := enabledMutators[sr.EndpointPattern]; found {
44-
return mutator(sr)
46+
if mutation, found := enabledMutations[sr.EndpointPattern]; found {
47+
return mutator(mutation)(sr)
4548
}
4649

4750
return sr

src/mock/endpointpattern.go

+73-23
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ var GetCodesOfConductByKey EndpointPattern = EndpointPattern{
157157
Method: "GET",
158158
}
159159

160+
var PostCredentialsRevoke EndpointPattern = EndpointPattern{
161+
Pattern: "/credentials/revoke",
162+
Method: "POST",
163+
}
164+
160165
var GetEmojis EndpointPattern = EndpointPattern{
161166
Pattern: "/emojis",
162167
Method: "GET",
@@ -842,6 +847,31 @@ var DeleteOrgsBlocksByOrgByUsername EndpointPattern = EndpointPattern{
842847
Method: "DELETE",
843848
}
844849

850+
var GetOrgsCampaignsByOrg EndpointPattern = EndpointPattern{
851+
Pattern: "/orgs/{org}/campaigns",
852+
Method: "GET",
853+
}
854+
855+
var PostOrgsCampaignsByOrg EndpointPattern = EndpointPattern{
856+
Pattern: "/orgs/{org}/campaigns",
857+
Method: "POST",
858+
}
859+
860+
var GetOrgsCampaignsByOrgByCampaignNumber EndpointPattern = EndpointPattern{
861+
Pattern: "/orgs/{org}/campaigns/{campaign_number}",
862+
Method: "GET",
863+
}
864+
865+
var PatchOrgsCampaignsByOrgByCampaignNumber EndpointPattern = EndpointPattern{
866+
Pattern: "/orgs/{org}/campaigns/{campaign_number}",
867+
Method: "PATCH",
868+
}
869+
870+
var DeleteOrgsCampaignsByOrgByCampaignNumber EndpointPattern = EndpointPattern{
871+
Pattern: "/orgs/{org}/campaigns/{campaign_number}",
872+
Method: "DELETE",
873+
}
874+
845875
var GetOrgsCodeScanningAlertsByOrg EndpointPattern = EndpointPattern{
846876
Pattern: "/orgs/{org}/code-scanning/alerts",
847877
Method: "GET",
@@ -997,11 +1027,6 @@ var GetOrgsCopilotMetricsByOrg EndpointPattern = EndpointPattern{
9971027
Method: "GET",
9981028
}
9991029

1000-
var GetOrgsCopilotUsageByOrg EndpointPattern = EndpointPattern{
1001-
Pattern: "/orgs/{org}/copilot/usage",
1002-
Method: "GET",
1003-
}
1004-
10051030
var GetOrgsDependabotAlertsByOrg EndpointPattern = EndpointPattern{
10061031
Pattern: "/orgs/{org}/dependabot/alerts",
10071032
Method: "GET",
@@ -1212,6 +1237,26 @@ var GetOrgsInvitationsTeamsByOrgByInvitationId EndpointPattern = EndpointPattern
12121237
Method: "GET",
12131238
}
12141239

1240+
var GetOrgsIssueTypesByOrg EndpointPattern = EndpointPattern{
1241+
Pattern: "/orgs/{org}/issue-types",
1242+
Method: "GET",
1243+
}
1244+
1245+
var PostOrgsIssueTypesByOrg EndpointPattern = EndpointPattern{
1246+
Pattern: "/orgs/{org}/issue-types",
1247+
Method: "POST",
1248+
}
1249+
1250+
var PutOrgsIssueTypesByOrgByIssueTypeId EndpointPattern = EndpointPattern{
1251+
Pattern: "/orgs/{org}/issue-types/{issue_type_id}",
1252+
Method: "PUT",
1253+
}
1254+
1255+
var DeleteOrgsIssueTypesByOrgByIssueTypeId EndpointPattern = EndpointPattern{
1256+
Pattern: "/orgs/{org}/issue-types/{issue_type_id}",
1257+
Method: "DELETE",
1258+
}
1259+
12151260
var GetOrgsIssuesByOrg EndpointPattern = EndpointPattern{
12161261
Pattern: "/orgs/{org}/issues",
12171262
Method: "GET",
@@ -1672,11 +1717,6 @@ var GetOrgsTeamCopilotMetricsByOrgByTeamSlug EndpointPattern = EndpointPattern{
16721717
Method: "GET",
16731718
}
16741719

1675-
var GetOrgsTeamCopilotUsageByOrgByTeamSlug EndpointPattern = EndpointPattern{
1676-
Pattern: "/orgs/{org}/team/{team_slug}/copilot/usage",
1677-
Method: "GET",
1678-
}
1679-
16801720
var GetOrgsTeamsByOrg EndpointPattern = EndpointPattern{
16811721
Pattern: "/orgs/{org}/teams",
16821722
Method: "GET",
@@ -2908,17 +2948,17 @@ var GetReposCompareByOwnerByRepoByBasehead EndpointPattern = EndpointPattern{
29082948
}
29092949

29102950
var GetReposContentsByOwnerByRepoByPath EndpointPattern = EndpointPattern{
2911-
Pattern: "/repos/{owner}/{repo}/contents/{path:.+}",
2951+
Pattern: "/repos/{owner}/{repo}/contents/{path:.*}",
29122952
Method: "GET",
29132953
}
29142954

29152955
var PutReposContentsByOwnerByRepoByPath EndpointPattern = EndpointPattern{
2916-
Pattern: "/repos/{owner}/{repo}/contents/{path:.+}",
2956+
Pattern: "/repos/{owner}/{repo}/contents/{path:.*}",
29172957
Method: "PUT",
29182958
}
29192959

29202960
var DeleteReposContentsByOwnerByRepoByPath EndpointPattern = EndpointPattern{
2921-
Pattern: "/repos/{owner}/{repo}/contents/{path:.+}",
2961+
Pattern: "/repos/{owner}/{repo}/contents/{path:.*}",
29222962
Method: "DELETE",
29232963
}
29242964

@@ -5422,11 +5462,6 @@ var GetEnterprisesCopilotMetricsByEnterprise EndpointPattern = EndpointPattern{
54225462
Method: "GET",
54235463
}
54245464

5425-
var GetEnterprisesCopilotUsageByEnterprise EndpointPattern = EndpointPattern{
5426-
Pattern: "/enterprises/{enterprise}/copilot/usage",
5427-
Method: "GET",
5428-
}
5429-
54305465
var GetEnterprisesLicenseSyncStatusByEnterprise EndpointPattern = EndpointPattern{
54315466
Pattern: "/enterprises/{enterprise}/license-sync-status",
54325467
Method: "GET",
@@ -5567,11 +5602,6 @@ var GetEnterprisesTeamCopilotMetricsByEnterpriseByTeamSlug EndpointPattern = End
55675602
Method: "GET",
55685603
}
55695604

5570-
var GetEnterprisesTeamCopilotUsageByEnterpriseByTeamSlug EndpointPattern = EndpointPattern{
5571-
Pattern: "/enterprises/{enterprise}/team/{team_slug}/copilot/usage",
5572-
Method: "GET",
5573-
}
5574-
55755605
var PostEnterprisesByEnterpriseBySecurityProductByEnablement EndpointPattern = EndpointPattern{
55765606
Pattern: "/enterprises/{enterprise}/{security_product}/{enablement}",
55775607
Method: "POST",
@@ -5667,6 +5697,11 @@ var DeleteOrgsCustomRolesByOrgByRoleId EndpointPattern = EndpointPattern{
56675697
Method: "DELETE",
56685698
}
56695699

5700+
var GetOrgsDismissalRequestsSecretScanningByOrg EndpointPattern = EndpointPattern{
5701+
Pattern: "/orgs/{org}/dismissal-requests/secret-scanning",
5702+
Method: "GET",
5703+
}
5704+
56705705
var GetOrgsExternalGroupByOrgByGroupId EndpointPattern = EndpointPattern{
56715706
Pattern: "/orgs/{org}/external-group/{group_id}",
56725707
Method: "GET",
@@ -5772,6 +5807,21 @@ var DeleteReposBypassResponsesSecretScanningByOwnerByRepoByBypassResponseId Endp
57725807
Method: "DELETE",
57735808
}
57745809

5810+
var GetReposDismissalRequestsSecretScanningByOwnerByRepo EndpointPattern = EndpointPattern{
5811+
Pattern: "/repos/{owner}/{repo}/dismissal-requests/secret-scanning",
5812+
Method: "GET",
5813+
}
5814+
5815+
var GetReposDismissalRequestsSecretScanningByOwnerByRepoByAlertNumber EndpointPattern = EndpointPattern{
5816+
Pattern: "/repos/{owner}/{repo}/dismissal-requests/secret-scanning/{alert_number}",
5817+
Method: "GET",
5818+
}
5819+
5820+
var PatchReposDismissalRequestsSecretScanningByOwnerByRepoByAlertNumber EndpointPattern = EndpointPattern{
5821+
Pattern: "/repos/{owner}/{repo}/dismissal-requests/secret-scanning/{alert_number}",
5822+
Method: "PATCH",
5823+
}
5824+
57755825
var PutReposLfsByOwnerByRepo EndpointPattern = EndpointPattern{
57765826
Pattern: "/repos/{owner}/{repo}/lfs",
57775827
Method: "PUT",

src/mock/endpointpattern_test.go

+75-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"context"
55
"testing"
66

7-
"github.com/google/go-github/v69/github"
7+
"github.com/google/go-github/v71/github"
88
)
99

1010
func TestRepoGetContents(t *testing.T) {
@@ -71,6 +71,80 @@ func TestRepoGetContents(t *testing.T) {
7171
}
7272
}
7373

74+
func TestRepoGetContentsForDirectory(t *testing.T) {
75+
cases := []struct {
76+
name string
77+
path string
78+
repositoryContent []*github.RepositoryContent
79+
}{
80+
{
81+
name: "rootDirectory",
82+
path: "",
83+
repositoryContent: []*github.RepositoryContent{
84+
{
85+
Name: github.Ptr("a.yaml"),
86+
DownloadURL: github.Ptr("https://raw.githubusercontent.com/foo/bar/a.yaml"),
87+
},
88+
{
89+
Name: github.Ptr("b.json"),
90+
DownloadURL: github.Ptr("https://raw.githubusercontent.com/foo/bar/b.json"),
91+
},
92+
},
93+
},
94+
}
95+
96+
for _, c := range cases {
97+
t.Run(c.name, func(rc []*github.RepositoryContent) func(t *testing.T) {
98+
return func(t *testing.T) {
99+
mockedHTTPClient := NewMockedHTTPClient(
100+
WithRequestMatch(
101+
GetReposContentsByOwnerByRepoByPath,
102+
rc,
103+
),
104+
)
105+
106+
client := github.NewClient(mockedHTTPClient)
107+
108+
ctx := context.Background()
109+
110+
_, dirContent, _, err := client.Repositories.GetContents(
111+
ctx,
112+
"foo",
113+
"bar",
114+
c.path,
115+
&github.RepositoryContentGetOptions{},
116+
)
117+
118+
if len(dirContent) != len(rc) {
119+
t.Errorf(
120+
"dirContent length is %d, want %d",
121+
len(dirContent),
122+
len(rc),
123+
)
124+
}
125+
126+
for i := range rc {
127+
if rc[i] == dirContent[1] {
128+
t.Errorf(
129+
"dirContent element at %d is '%s', want '%s'",
130+
i,
131+
*dirContent[i].Name,
132+
*rc[i].Name,
133+
)
134+
}
135+
}
136+
137+
if err != nil {
138+
t.Errorf(
139+
"err is %s, want nil",
140+
err.Error(),
141+
)
142+
}
143+
}
144+
}(c.repositoryContent))
145+
}
146+
}
147+
74148
func TestPatchGitReference(t *testing.T) {
75149
mockedHTTPClient := NewMockedHTTPClient(
76150
WithRequestMatch(

src/mock/server_options_external_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"testing"
77
"time"
88

9-
"github.com/google/go-github/v69/github"
9+
"github.com/google/go-github/v71/github"
1010
"github.com/migueleliasweb/go-github-mock/src/mock"
1111
)
1212

src/mock/server_options_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package mock
33
import (
44
"testing"
55

6-
"github.com/google/go-github/v69/github"
6+
"github.com/google/go-github/v71/github"
77
"github.com/gorilla/mux"
88
)
99

src/mock/server_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"strings"
88
"testing"
99

10-
"github.com/google/go-github/v69/github"
10+
"github.com/google/go-github/v71/github"
1111
)
1212

1313
func TestNewMockedHTTPClient(t *testing.T) {

0 commit comments

Comments
 (0)