Skip to content

Commit 785eb29

Browse files
committed
add tests for new functionality
1 parent 25b5901 commit 785eb29

File tree

1 file changed

+247
-69
lines changed

1 file changed

+247
-69
lines changed

pkg/github/repositories_test.go

Lines changed: 247 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/json"
77
"net/http"
88
"net/url"
9+
"strings"
910
"testing"
1011
"time"
1112

@@ -2209,73 +2210,250 @@ func Test_filterPaths(t *testing.T) {
22092210
}
22102211

22112212
func Test_resolveGitReference(t *testing.T) {
2212-
ctx := context.Background()
2213-
owner := "owner"
2214-
repo := "repo"
2215-
mockedClient := mock.NewMockedHTTPClient(
2216-
mock.WithRequestMatchHandler(
2217-
mock.GetReposByOwnerByRepo,
2218-
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
2219-
w.WriteHeader(http.StatusOK)
2220-
_, _ = w.Write([]byte(`{"name": "repo", "default_branch": "main"}`))
2221-
}),
2222-
),
2223-
mock.WithRequestMatchHandler(
2224-
mock.GetReposGitRefByOwnerByRepoByRef,
2225-
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
2226-
w.WriteHeader(http.StatusOK)
2227-
_, _ = w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": "123sha456"}}`))
2228-
}),
2229-
),
2230-
)
2231-
2232-
tests := []struct {
2233-
name string
2234-
ref string
2235-
sha string
2236-
expectedOutput *raw.ContentOpts
2237-
}{
2238-
{
2239-
name: "sha takes precedence over ref",
2240-
ref: "refs/heads/main",
2241-
sha: "123sha456",
2242-
expectedOutput: &raw.ContentOpts{
2243-
SHA: "123sha456",
2244-
},
2245-
},
2246-
{
2247-
name: "use default branch if ref and sha both empty",
2248-
ref: "",
2249-
sha: "",
2250-
expectedOutput: &raw.ContentOpts{
2251-
Ref: "refs/heads/main",
2252-
SHA: "123sha456",
2253-
},
2254-
},
2255-
{
2256-
name: "get SHA from ref",
2257-
ref: "refs/heads/main",
2258-
sha: "",
2259-
expectedOutput: &raw.ContentOpts{
2260-
Ref: "refs/heads/main",
2261-
SHA: "123sha456",
2262-
},
2263-
},
2264-
}
2265-
2266-
for _, tc := range tests {
2267-
t.Run(tc.name, func(t *testing.T) {
2268-
// Setup client with mock
2269-
client := github.NewClient(mockedClient)
2270-
opts, err := resolveGitReference(ctx, client, owner, repo, tc.ref, tc.sha)
2271-
require.NoError(t, err)
2272-
2273-
if tc.expectedOutput.SHA != "" {
2274-
assert.Equal(t, tc.expectedOutput.SHA, opts.SHA)
2275-
}
2276-
if tc.expectedOutput.Ref != "" {
2277-
assert.Equal(t, tc.expectedOutput.Ref, opts.Ref)
2278-
}
2279-
})
2280-
}
2213+
ctx := context.Background()
2214+
owner := "owner"
2215+
repo := "repo"
2216+
2217+
tests := []struct {
2218+
name string
2219+
ref string
2220+
sha string
2221+
mockSetup func() *http.Client
2222+
expectedOutput *raw.ContentOpts
2223+
expectError bool
2224+
errorContains string
2225+
}{
2226+
{
2227+
name: "sha takes precedence over ref",
2228+
ref: "refs/heads/main",
2229+
sha: "123sha456",
2230+
mockSetup: func() *http.Client {
2231+
// No API calls should be made when SHA is provided
2232+
return mock.NewMockedHTTPClient()
2233+
},
2234+
expectedOutput: &raw.ContentOpts{
2235+
SHA: "123sha456",
2236+
},
2237+
expectError: false,
2238+
},
2239+
{
2240+
name: "use default branch if ref and sha both empty",
2241+
ref: "",
2242+
sha: "",
2243+
mockSetup: func() *http.Client {
2244+
return mock.NewMockedHTTPClient(
2245+
mock.WithRequestMatchHandler(
2246+
mock.GetReposByOwnerByRepo,
2247+
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
2248+
w.WriteHeader(http.StatusOK)
2249+
_, _ = w.Write([]byte(`{"name": "repo", "default_branch": "main"}`))
2250+
}),
2251+
),
2252+
mock.WithRequestMatchHandler(
2253+
mock.GetReposGitRefByOwnerByRepoByRef,
2254+
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2255+
assert.Contains(t, r.URL.Path, "/git/ref/heads/main")
2256+
w.WriteHeader(http.StatusOK)
2257+
_, _ = w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": "main-sha"}}`))
2258+
}),
2259+
),
2260+
)
2261+
},
2262+
expectedOutput: &raw.ContentOpts{
2263+
Ref: "refs/heads/main",
2264+
SHA: "main-sha",
2265+
},
2266+
expectError: false,
2267+
},
2268+
{
2269+
name: "fully qualified ref passed through unchanged",
2270+
ref: "refs/heads/feature-branch",
2271+
sha: "",
2272+
mockSetup: func() *http.Client {
2273+
return mock.NewMockedHTTPClient(
2274+
mock.WithRequestMatchHandler(
2275+
mock.GetReposGitRefByOwnerByRepoByRef,
2276+
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2277+
assert.Contains(t, r.URL.Path, "/git/ref/heads/feature-branch")
2278+
w.WriteHeader(http.StatusOK)
2279+
_, _ = w.Write([]byte(`{"ref": "refs/heads/feature-branch", "object": {"sha": "feature-sha"}}`))
2280+
}),
2281+
),
2282+
)
2283+
},
2284+
expectedOutput: &raw.ContentOpts{
2285+
Ref: "refs/heads/feature-branch",
2286+
SHA: "feature-sha",
2287+
},
2288+
expectError: false,
2289+
},
2290+
{
2291+
name: "short branch name resolves to refs/heads/",
2292+
ref: "main",
2293+
sha: "",
2294+
mockSetup: func() *http.Client {
2295+
callCount := 0
2296+
return mock.NewMockedHTTPClient(
2297+
mock.WithRequestMatchHandler(
2298+
mock.GetReposGitRefByOwnerByRepoByRef,
2299+
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2300+
callCount++
2301+
if strings.Contains(r.URL.Path, "/git/ref/heads/main") {
2302+
w.WriteHeader(http.StatusOK)
2303+
_, _ = w.Write([]byte(`{"ref": "refs/heads/main", "object": {"sha": "main-sha"}}`))
2304+
} else {
2305+
t.Errorf("Unexpected path: %s", r.URL.Path)
2306+
w.WriteHeader(http.StatusNotFound)
2307+
}
2308+
}),
2309+
),
2310+
)
2311+
},
2312+
expectedOutput: &raw.ContentOpts{
2313+
Ref: "refs/heads/main",
2314+
SHA: "main-sha",
2315+
},
2316+
expectError: false,
2317+
},
2318+
{
2319+
name: "short tag name falls back to refs/tags/ when branch not found",
2320+
ref: "v1.0.0",
2321+
sha: "",
2322+
mockSetup: func() *http.Client {
2323+
return mock.NewMockedHTTPClient(
2324+
mock.WithRequestMatchHandler(
2325+
mock.GetReposGitRefByOwnerByRepoByRef,
2326+
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2327+
if strings.Contains(r.URL.Path, "/git/ref/heads/v1.0.0") {
2328+
w.WriteHeader(http.StatusNotFound)
2329+
_, _ = w.Write([]byte(`{"message": "Not Found"}`))
2330+
} else if strings.Contains(r.URL.Path, "/git/ref/tags/v1.0.0") {
2331+
w.WriteHeader(http.StatusOK)
2332+
_, _ = w.Write([]byte(`{"ref": "refs/tags/v1.0.0", "object": {"sha": "tag-sha"}}`))
2333+
} else {
2334+
t.Errorf("Unexpected path: %s", r.URL.Path)
2335+
w.WriteHeader(http.StatusNotFound)
2336+
}
2337+
}),
2338+
),
2339+
)
2340+
},
2341+
expectedOutput: &raw.ContentOpts{
2342+
Ref: "refs/tags/v1.0.0",
2343+
SHA: "tag-sha",
2344+
},
2345+
expectError: false,
2346+
},
2347+
{
2348+
name: "heads/ prefix gets refs/ prepended",
2349+
ref: "heads/feature-branch",
2350+
sha: "",
2351+
mockSetup: func() *http.Client {
2352+
return mock.NewMockedHTTPClient(
2353+
mock.WithRequestMatchHandler(
2354+
mock.GetReposGitRefByOwnerByRepoByRef,
2355+
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2356+
assert.Contains(t, r.URL.Path, "/git/ref/heads/feature-branch")
2357+
w.WriteHeader(http.StatusOK)
2358+
_, _ = w.Write([]byte(`{"ref": "refs/heads/feature-branch", "object": {"sha": "feature-sha"}}`))
2359+
}),
2360+
),
2361+
)
2362+
},
2363+
expectedOutput: &raw.ContentOpts{
2364+
Ref: "refs/heads/feature-branch",
2365+
SHA: "feature-sha",
2366+
},
2367+
expectError: false,
2368+
},
2369+
{
2370+
name: "tags/ prefix gets refs/ prepended",
2371+
ref: "tags/v1.0.0",
2372+
sha: "",
2373+
mockSetup: func() *http.Client {
2374+
return mock.NewMockedHTTPClient(
2375+
mock.WithRequestMatchHandler(
2376+
mock.GetReposGitRefByOwnerByRepoByRef,
2377+
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2378+
assert.Contains(t, r.URL.Path, "/git/ref/tags/v1.0.0")
2379+
w.WriteHeader(http.StatusOK)
2380+
_, _ = w.Write([]byte(`{"ref": "refs/tags/v1.0.0", "object": {"sha": "tag-sha"}}`))
2381+
}),
2382+
),
2383+
)
2384+
},
2385+
expectedOutput: &raw.ContentOpts{
2386+
Ref: "refs/tags/v1.0.0",
2387+
SHA: "tag-sha",
2388+
},
2389+
expectError: false,
2390+
},
2391+
{
2392+
name: "invalid short name that doesn't exist as branch or tag",
2393+
ref: "nonexistent",
2394+
sha: "",
2395+
mockSetup: func() *http.Client {
2396+
return mock.NewMockedHTTPClient(
2397+
mock.WithRequestMatchHandler(
2398+
mock.GetReposGitRefByOwnerByRepoByRef,
2399+
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2400+
// Both branch and tag attempts should return 404
2401+
w.WriteHeader(http.StatusNotFound)
2402+
_, _ = w.Write([]byte(`{"message": "Not Found"}`))
2403+
}),
2404+
),
2405+
)
2406+
},
2407+
expectError: true,
2408+
errorContains: "could not resolve ref \"nonexistent\" as a branch or a tag",
2409+
},
2410+
{
2411+
name: "fully qualified pull request ref",
2412+
ref: "refs/pull/123/head",
2413+
sha: "",
2414+
mockSetup: func() *http.Client {
2415+
return mock.NewMockedHTTPClient(
2416+
mock.WithRequestMatchHandler(
2417+
mock.GetReposGitRefByOwnerByRepoByRef,
2418+
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2419+
assert.Contains(t, r.URL.Path, "/git/ref/pull/123/head")
2420+
w.WriteHeader(http.StatusOK)
2421+
_, _ = w.Write([]byte(`{"ref": "refs/pull/123/head", "object": {"sha": "pr-sha"}}`))
2422+
}),
2423+
),
2424+
)
2425+
},
2426+
expectedOutput: &raw.ContentOpts{
2427+
Ref: "refs/pull/123/head",
2428+
SHA: "pr-sha",
2429+
},
2430+
expectError: false,
2431+
},
2432+
}
2433+
2434+
for _, tc := range tests {
2435+
t.Run(tc.name, func(t *testing.T) {
2436+
// Setup client with mock
2437+
client := github.NewClient(tc.mockSetup())
2438+
opts, err := resolveGitReference(ctx, client, owner, repo, tc.ref, tc.sha)
2439+
2440+
if tc.expectError {
2441+
require.Error(t, err)
2442+
if tc.errorContains != "" {
2443+
assert.Contains(t, err.Error(), tc.errorContains)
2444+
}
2445+
return
2446+
}
2447+
2448+
require.NoError(t, err)
2449+
require.NotNil(t, opts)
2450+
2451+
if tc.expectedOutput.SHA != "" {
2452+
assert.Equal(t, tc.expectedOutput.SHA, opts.SHA)
2453+
}
2454+
if tc.expectedOutput.Ref != "" {
2455+
assert.Equal(t, tc.expectedOutput.Ref, opts.Ref)
2456+
}
2457+
})
2458+
}
22812459
}

0 commit comments

Comments
 (0)