diff --git a/github/search.go b/github/search.go index 344f1bb985..4d16664058 100644 --- a/github/search.go +++ b/github/search.go @@ -9,6 +9,7 @@ import ( "context" "fmt" "strconv" + "strings" qs "github.com/google/go-querystring/query" ) @@ -299,29 +300,32 @@ func (s *SearchService) search(ctx context.Context, searchType string, parameter if err != nil { return nil, err } - + var acceptHeaders []string switch { case searchType == "commits": // Accept header for search commits preview endpoint // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeCommitSearchPreview) + acceptHeaders = append(acceptHeaders, mediaTypeCommitSearchPreview) case searchType == "topics": // Accept header for search repositories based on topics preview endpoint // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTopicsPreview) + acceptHeaders = append(acceptHeaders, mediaTypeTopicsPreview) case searchType == "repositories": // Accept header for search repositories based on topics preview endpoint // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeTopicsPreview) + acceptHeaders = append(acceptHeaders, mediaTypeTopicsPreview) case searchType == "issues": // Accept header for search issues based on reactions preview endpoint // TODO: remove custom Accept header when this API fully launches. - req.Header.Set("Accept", mediaTypeReactionsPreview) - case opts != nil && opts.TextMatch: - // Accept header defaults to "application/vnd.github.v3+json" - // We change it here to fetch back text-match metadata - req.Header.Set("Accept", "application/vnd.github.v3.text-match+json") + acceptHeaders = append(acceptHeaders, mediaTypeReactionsPreview) + } + // https://docs.github.com/en/rest/search#search-repositories + // Accept header defaults to "application/vnd.github.v3+json" + // We change it here to fetch back text-match metadata + if opts != nil && opts.TextMatch { + acceptHeaders = append(acceptHeaders, "application/vnd.github.v3.text-match+json") } + req.Header.Set("Accept", strings.Join(acceptHeaders, ", ")) return s.client.Do(ctx, req, result) } diff --git a/github/search_test.go b/github/search_test.go index 4562fcf51e..0d49b36c19 100644 --- a/github/search_test.go +++ b/github/search_test.go @@ -9,6 +9,7 @@ import ( "context" "fmt" "net/http" + "strings" "testing" "github.com/google/go-cmp/cmp" @@ -61,6 +62,85 @@ func TestSearchService_Repositories_coverage(t *testing.T) { }) } +func TestSearchService_RepositoriesTextMatch(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/search/repositories", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + textMatchResponse := ` + { + "total_count": 1, + "incomplete_results": false, + "items": [ + { + "name":"gopher1" + } + ] + } + ` + list := strings.Split(r.Header.Get("Accept"), ",") + aMap := make(map[string]struct{}) + for _, s := range list { + aMap[strings.TrimSpace(s)] = struct{}{} + } + if _, ok := aMap["application/vnd.github.v3.text-match+json"]; ok { + textMatchResponse = ` + { + "total_count": 1, + "incomplete_results": false, + "items": [ + { + "name":"gopher1", + "text_matches": [ + { + "fragment": "I'm afraid my friend what you have found\nIs a gopher who lives to feed", + "matches": [ + { + "text": "gopher", + "indices": [ + 14, + 21 + ] + } + ] + } + ] + } + ] + } + ` + } + + fmt.Fprint(w, textMatchResponse) + }) + + opts := &SearchOptions{Sort: "forks", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}, TextMatch: true} + ctx := context.Background() + result, _, err := client.Search.Repositories(ctx, "blah", opts) + if err != nil { + t.Errorf("Search.Code returned error: %v", err) + } + + wantedRepoResult := &Repository{ + Name: String("gopher1"), + TextMatches: []*TextMatch{{ + Fragment: String("I'm afraid my friend what you have found\nIs a gopher who lives to feed"), + Matches: []*Match{{Text: String("gopher"), Indices: []int{14, 21}}}, + }, + }, + } + + want := &RepositoriesSearchResult{ + Total: Int(1), + IncompleteResults: Bool(false), + Repositories: []*Repository{wantedRepoResult}, + } + if !cmp.Equal(result, want) { + t.Errorf("Search.Repo returned %+v, want %+v", result, want) + } +} + func TestSearchService_Topics(t *testing.T) { client, mux, _, teardown := setup() defer teardown()