Loading search.go +35 −28 Changes for search.go: 35 added lines, 28 removed lines. Original line number Diff line number Diff line Loading @@ -77,13 +77,23 @@ type searchOptions struct { Search string `url:"search" json:"search"` } // newSearchOptions returns the query parameters of a search request. A nil // opt means no options, so only the scope and the search term are sent. func newSearchOptions(opt *SearchOptions, scope, query string) *searchOptions { o := &searchOptions{Scope: scope, Search: query} if opt != nil { o.SearchOptions = *opt } return o } // Projects searches the expression within projects // // GitLab API docs: https://docs.gitlab.com/api/search/#scope-projects func (s *SearchService) Projects(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { return do[[]*Project](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "projects", Search: query}), withAPIOpts(newSearchOptions(opt, "projects", query)), withRequestOpts(options...), ) } Loading @@ -95,7 +105,7 @@ func (s *SearchService) Projects(query string, opt *SearchOptions, options ...Re func (s *SearchService) ProjectsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { return do[[]*Project](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "projects", Search: query}), withAPIOpts(newSearchOptions(opt, "projects", query)), withRequestOpts(options...), ) } Loading @@ -106,7 +116,7 @@ func (s *SearchService) ProjectsByGroup(gid any, query string, opt *SearchOption func (s *SearchService) Issues(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { return do[[]*Issue](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "issues", Search: query}), //nolint:goconst withAPIOpts(newSearchOptions(opt, "issues", query)), withRequestOpts(options...), ) } Loading @@ -118,7 +128,7 @@ func (s *SearchService) Issues(query string, opt *SearchOptions, options ...Requ func (s *SearchService) IssuesByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { return do[[]*Issue](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "issues", Search: query}), withAPIOpts(newSearchOptions(opt, "issues", query)), withRequestOpts(options...), ) } Loading @@ -130,7 +140,7 @@ func (s *SearchService) IssuesByGroup(gid any, query string, opt *SearchOptions, func (s *SearchService) IssuesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { return do[[]*Issue](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "issues", Search: query}), withAPIOpts(newSearchOptions(opt, "issues", query)), withRequestOpts(options...), ) } Loading @@ -142,7 +152,7 @@ func (s *SearchService) IssuesByProject(pid any, query string, opt *SearchOption func (s *SearchService) MergeRequests(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { return do[[]*MergeRequest](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "merge_requests", Search: query}), //nolint:goconst withAPIOpts(newSearchOptions(opt, "merge_requests", query)), withRequestOpts(options...), ) } Loading @@ -155,7 +165,7 @@ func (s *SearchService) MergeRequests(query string, opt *SearchOptions, options func (s *SearchService) MergeRequestsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { return do[[]*MergeRequest](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "merge_requests", Search: query}), withAPIOpts(newSearchOptions(opt, "merge_requests", query)), withRequestOpts(options...), ) } Loading @@ -168,7 +178,7 @@ func (s *SearchService) MergeRequestsByGroup(gid any, query string, opt *SearchO func (s *SearchService) MergeRequestsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { return do[[]*MergeRequest](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "merge_requests", Search: query}), withAPIOpts(newSearchOptions(opt, "merge_requests", query)), withRequestOpts(options...), ) } Loading @@ -179,7 +189,7 @@ func (s *SearchService) MergeRequestsByProject(pid any, query string, opt *Searc func (s *SearchService) Milestones(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { return do[[]*Milestone](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "milestones", Search: query}), withAPIOpts(newSearchOptions(opt, "milestones", query)), withRequestOpts(options...), ) } Loading @@ -191,7 +201,7 @@ func (s *SearchService) Milestones(query string, opt *SearchOptions, options ... func (s *SearchService) MilestonesByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { return do[[]*Milestone](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "milestones", Search: query}), withAPIOpts(newSearchOptions(opt, "milestones", query)), withRequestOpts(options...), ) } Loading @@ -203,7 +213,7 @@ func (s *SearchService) MilestonesByGroup(gid any, query string, opt *SearchOpti func (s *SearchService) MilestonesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { return do[[]*Milestone](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "milestones", Search: query}), withAPIOpts(newSearchOptions(opt, "milestones", query)), withRequestOpts(options...), ) } Loading @@ -215,7 +225,7 @@ func (s *SearchService) MilestonesByProject(pid any, query string, opt *SearchOp func (s *SearchService) SnippetTitles(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { return do[[]*Snippet](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "snippet_titles", Search: query}), withAPIOpts(newSearchOptions(opt, "snippet_titles", query)), withRequestOpts(options...), ) } Loading @@ -227,7 +237,7 @@ func (s *SearchService) SnippetTitles(query string, opt *SearchOptions, options func (s *SearchService) NotesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { return do[[]*Note](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "notes", Search: query}), withAPIOpts(newSearchOptions(opt, "notes", query)), withRequestOpts(options...), ) } Loading @@ -239,7 +249,7 @@ func (s *SearchService) NotesByProject(pid any, query string, opt *SearchOptions func (s *SearchService) WikiBlobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { return do[[]*Wiki](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "wiki_blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "wiki_blobs", query)), withRequestOpts(options...), ) } Loading @@ -252,7 +262,7 @@ func (s *SearchService) WikiBlobs(query string, opt *SearchOptions, options ...R func (s *SearchService) WikiBlobsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { return do[[]*Wiki](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "wiki_blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "wiki_blobs", query)), withRequestOpts(options...), ) } Loading @@ -265,7 +275,7 @@ func (s *SearchService) WikiBlobsByGroup(gid any, query string, opt *SearchOptio func (s *SearchService) WikiBlobsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { return do[[]*Wiki](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "wiki_blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "wiki_blobs", query)), withRequestOpts(options...), ) } Loading @@ -276,7 +286,7 @@ func (s *SearchService) WikiBlobsByProject(pid any, query string, opt *SearchOpt func (s *SearchService) Commits(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { return do[[]*Commit](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "commits", Search: query}), withAPIOpts(newSearchOptions(opt, "commits", query)), withRequestOpts(options...), ) } Loading @@ -288,7 +298,7 @@ func (s *SearchService) Commits(query string, opt *SearchOptions, options ...Req func (s *SearchService) CommitsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { return do[[]*Commit](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "commits", Search: query}), withAPIOpts(newSearchOptions(opt, "commits", query)), withRequestOpts(options...), ) } Loading @@ -300,7 +310,7 @@ func (s *SearchService) CommitsByGroup(gid any, query string, opt *SearchOptions func (s *SearchService) CommitsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { return do[[]*Commit](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "commits", Search: query}), withAPIOpts(newSearchOptions(opt, "commits", query)), withRequestOpts(options...), ) } Loading @@ -323,7 +333,7 @@ type Blob struct { func (s *SearchService) Blobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { return do[[]*Blob](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "blobs", query)), withRequestOpts(options...), ) } Loading @@ -335,7 +345,7 @@ func (s *SearchService) Blobs(query string, opt *SearchOptions, options ...Reque func (s *SearchService) BlobsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { return do[[]*Blob](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "blobs", query)), withRequestOpts(options...), ) } Loading @@ -347,7 +357,7 @@ func (s *SearchService) BlobsByGroup(gid any, query string, opt *SearchOptions, func (s *SearchService) BlobsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { return do[[]*Blob](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "blobs", query)), withRequestOpts(options...), ) } Loading @@ -358,7 +368,7 @@ func (s *SearchService) BlobsByProject(pid any, query string, opt *SearchOptions func (s *SearchService) Users(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { return do[[]*User](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "users", Search: query}), withAPIOpts(newSearchOptions(opt, "users", query)), withRequestOpts(options...), ) } Loading @@ -368,12 +378,9 @@ func (s *SearchService) Users(query string, opt *SearchOptions, options ...Reque // // GitLab API docs: https://docs.gitlab.com/api/search/#scope-users-1 func (s *SearchService) UsersByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { if opt == nil { opt = &SearchOptions{} } return do[[]*User](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "users", Search: query}), withAPIOpts(newSearchOptions(opt, "users", query)), withRequestOpts(options...), ) } Loading @@ -385,7 +392,7 @@ func (s *SearchService) UsersByGroup(gid any, query string, opt *SearchOptions, func (s *SearchService) UsersByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { return do[[]*User](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "users", Search: query}), withAPIOpts(newSearchOptions(opt, "users", query)), withRequestOpts(options...), ) } search_test.go +178 −0 Changes for search_test.go: 178 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -19,9 +19,11 @@ package gitlab import ( "fmt" "net/http" "net/url" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestSearchService_Users(t *testing.T) { Loading Loading @@ -687,3 +689,179 @@ func TestSearchService_BlobsByProject(t *testing.T) { assert.NotNil(t, resp) assert.Len(t, blobs, 1) } func TestSearchService_SearchOptions(t *testing.T) { t.Parallel() const ( searchPath = "/api/v4/search" groupSearchPath = "/api/v4/groups/1/-/search" projectSearchPath = "/api/v4/projects/1/-/search" ) tests := []struct { name string path string scope string call func(s SearchServiceInterface, opt *SearchOptions) (int, error) }{ {"Projects", searchPath, "projects", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Projects("fix", opt) return len(r), err }}, {"ProjectsByGroup", groupSearchPath, "projects", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.ProjectsByGroup(1, "fix", opt) return len(r), err }}, {"Issues", searchPath, "issues", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Issues("fix", opt) return len(r), err }}, {"IssuesByGroup", groupSearchPath, "issues", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.IssuesByGroup(1, "fix", opt) return len(r), err }}, {"IssuesByProject", projectSearchPath, "issues", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.IssuesByProject(1, "fix", opt) return len(r), err }}, {"MergeRequests", searchPath, "merge_requests", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.MergeRequests("fix", opt) return len(r), err }}, {"MergeRequestsByGroup", groupSearchPath, "merge_requests", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.MergeRequestsByGroup(1, "fix", opt) return len(r), err }}, {"MergeRequestsByProject", projectSearchPath, "merge_requests", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.MergeRequestsByProject(1, "fix", opt) return len(r), err }}, {"Milestones", searchPath, "milestones", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Milestones("fix", opt) return len(r), err }}, {"MilestonesByGroup", groupSearchPath, "milestones", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.MilestonesByGroup(1, "fix", opt) return len(r), err }}, {"MilestonesByProject", projectSearchPath, "milestones", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.MilestonesByProject(1, "fix", opt) return len(r), err }}, {"SnippetTitles", searchPath, "snippet_titles", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.SnippetTitles("fix", opt) return len(r), err }}, {"NotesByProject", projectSearchPath, "notes", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.NotesByProject(1, "fix", opt) return len(r), err }}, {"WikiBlobs", searchPath, "wiki_blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.WikiBlobs("fix", opt) return len(r), err }}, {"WikiBlobsByGroup", groupSearchPath, "wiki_blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.WikiBlobsByGroup(1, "fix", opt) return len(r), err }}, {"WikiBlobsByProject", projectSearchPath, "wiki_blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.WikiBlobsByProject(1, "fix", opt) return len(r), err }}, {"Commits", searchPath, "commits", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Commits("fix", opt) return len(r), err }}, {"CommitsByGroup", groupSearchPath, "commits", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.CommitsByGroup(1, "fix", opt) return len(r), err }}, {"CommitsByProject", projectSearchPath, "commits", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.CommitsByProject(1, "fix", opt) return len(r), err }}, {"Blobs", searchPath, "blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Blobs("fix", opt) return len(r), err }}, {"BlobsByGroup", groupSearchPath, "blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.BlobsByGroup(1, "fix", opt) return len(r), err }}, {"BlobsByProject", projectSearchPath, "blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.BlobsByProject(1, "fix", opt) return len(r), err }}, {"Users", searchPath, "users", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Users("fix", opt) return len(r), err }}, {"UsersByGroup", groupSearchPath, "users", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.UsersByGroup(1, "fix", opt) return len(r), err }}, {"UsersByProject", projectSearchPath, "users", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.UsersByProject(1, "fix", opt) return len(r), err }}, } for _, tt := range tests { t.Run(tt.name+"/nil options", func(t *testing.T) { t.Parallel() mux, client := setup(t) mux.HandleFunc(tt.path, func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) assert.Equal(t, url.Values{"scope": {tt.scope}, "search": {"fix"}}, r.URL.Query()) fmt.Fprint(w, `[{}]`) }) // GIVEN nil search options // WHEN the search method is called var ( n int err error ) require.NotPanics(t, func() { n, err = tt.call(client.Search, nil) }) // THEN the request carries only the scope and the search term require.NoError(t, err) assert.Equal(t, 1, n) }) t.Run(tt.name+"/with options", func(t *testing.T) { t.Parallel() mux, client := setup(t) mux.HandleFunc(tt.path, func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) want := url.Values{ "scope": {tt.scope}, "search": {"fix"}, "page": {"2"}, "per_page": {"5"}, "ref": {"main"}, "search_type": {"basic"}, } assert.Equal(t, want, r.URL.Query()) fmt.Fprint(w, `[{}]`) }) // GIVEN search options opt := &SearchOptions{ ListOptions: ListOptions{Page: 2, PerPage: 5}, Ref: new("main"), SearchType: new(BasicSearch), } // WHEN the search method is called n, err := tt.call(client.Search, opt) // THEN the options are sent with the scope and the search term require.NoError(t, err) assert.Equal(t, 1, n) }) } } Loading
search.go +35 −28 Changes for search.go: 35 added lines, 28 removed lines. Original line number Diff line number Diff line Loading @@ -77,13 +77,23 @@ type searchOptions struct { Search string `url:"search" json:"search"` } // newSearchOptions returns the query parameters of a search request. A nil // opt means no options, so only the scope and the search term are sent. func newSearchOptions(opt *SearchOptions, scope, query string) *searchOptions { o := &searchOptions{Scope: scope, Search: query} if opt != nil { o.SearchOptions = *opt } return o } // Projects searches the expression within projects // // GitLab API docs: https://docs.gitlab.com/api/search/#scope-projects func (s *SearchService) Projects(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { return do[[]*Project](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "projects", Search: query}), withAPIOpts(newSearchOptions(opt, "projects", query)), withRequestOpts(options...), ) } Loading @@ -95,7 +105,7 @@ func (s *SearchService) Projects(query string, opt *SearchOptions, options ...Re func (s *SearchService) ProjectsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) { return do[[]*Project](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "projects", Search: query}), withAPIOpts(newSearchOptions(opt, "projects", query)), withRequestOpts(options...), ) } Loading @@ -106,7 +116,7 @@ func (s *SearchService) ProjectsByGroup(gid any, query string, opt *SearchOption func (s *SearchService) Issues(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { return do[[]*Issue](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "issues", Search: query}), //nolint:goconst withAPIOpts(newSearchOptions(opt, "issues", query)), withRequestOpts(options...), ) } Loading @@ -118,7 +128,7 @@ func (s *SearchService) Issues(query string, opt *SearchOptions, options ...Requ func (s *SearchService) IssuesByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { return do[[]*Issue](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "issues", Search: query}), withAPIOpts(newSearchOptions(opt, "issues", query)), withRequestOpts(options...), ) } Loading @@ -130,7 +140,7 @@ func (s *SearchService) IssuesByGroup(gid any, query string, opt *SearchOptions, func (s *SearchService) IssuesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) { return do[[]*Issue](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "issues", Search: query}), withAPIOpts(newSearchOptions(opt, "issues", query)), withRequestOpts(options...), ) } Loading @@ -142,7 +152,7 @@ func (s *SearchService) IssuesByProject(pid any, query string, opt *SearchOption func (s *SearchService) MergeRequests(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { return do[[]*MergeRequest](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "merge_requests", Search: query}), //nolint:goconst withAPIOpts(newSearchOptions(opt, "merge_requests", query)), withRequestOpts(options...), ) } Loading @@ -155,7 +165,7 @@ func (s *SearchService) MergeRequests(query string, opt *SearchOptions, options func (s *SearchService) MergeRequestsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { return do[[]*MergeRequest](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "merge_requests", Search: query}), withAPIOpts(newSearchOptions(opt, "merge_requests", query)), withRequestOpts(options...), ) } Loading @@ -168,7 +178,7 @@ func (s *SearchService) MergeRequestsByGroup(gid any, query string, opt *SearchO func (s *SearchService) MergeRequestsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) { return do[[]*MergeRequest](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "merge_requests", Search: query}), withAPIOpts(newSearchOptions(opt, "merge_requests", query)), withRequestOpts(options...), ) } Loading @@ -179,7 +189,7 @@ func (s *SearchService) MergeRequestsByProject(pid any, query string, opt *Searc func (s *SearchService) Milestones(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { return do[[]*Milestone](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "milestones", Search: query}), withAPIOpts(newSearchOptions(opt, "milestones", query)), withRequestOpts(options...), ) } Loading @@ -191,7 +201,7 @@ func (s *SearchService) Milestones(query string, opt *SearchOptions, options ... func (s *SearchService) MilestonesByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { return do[[]*Milestone](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "milestones", Search: query}), withAPIOpts(newSearchOptions(opt, "milestones", query)), withRequestOpts(options...), ) } Loading @@ -203,7 +213,7 @@ func (s *SearchService) MilestonesByGroup(gid any, query string, opt *SearchOpti func (s *SearchService) MilestonesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Milestone, *Response, error) { return do[[]*Milestone](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "milestones", Search: query}), withAPIOpts(newSearchOptions(opt, "milestones", query)), withRequestOpts(options...), ) } Loading @@ -215,7 +225,7 @@ func (s *SearchService) MilestonesByProject(pid any, query string, opt *SearchOp func (s *SearchService) SnippetTitles(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Snippet, *Response, error) { return do[[]*Snippet](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "snippet_titles", Search: query}), withAPIOpts(newSearchOptions(opt, "snippet_titles", query)), withRequestOpts(options...), ) } Loading @@ -227,7 +237,7 @@ func (s *SearchService) SnippetTitles(query string, opt *SearchOptions, options func (s *SearchService) NotesByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Note, *Response, error) { return do[[]*Note](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "notes", Search: query}), withAPIOpts(newSearchOptions(opt, "notes", query)), withRequestOpts(options...), ) } Loading @@ -239,7 +249,7 @@ func (s *SearchService) NotesByProject(pid any, query string, opt *SearchOptions func (s *SearchService) WikiBlobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { return do[[]*Wiki](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "wiki_blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "wiki_blobs", query)), withRequestOpts(options...), ) } Loading @@ -252,7 +262,7 @@ func (s *SearchService) WikiBlobs(query string, opt *SearchOptions, options ...R func (s *SearchService) WikiBlobsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { return do[[]*Wiki](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "wiki_blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "wiki_blobs", query)), withRequestOpts(options...), ) } Loading @@ -265,7 +275,7 @@ func (s *SearchService) WikiBlobsByGroup(gid any, query string, opt *SearchOptio func (s *SearchService) WikiBlobsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Wiki, *Response, error) { return do[[]*Wiki](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "wiki_blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "wiki_blobs", query)), withRequestOpts(options...), ) } Loading @@ -276,7 +286,7 @@ func (s *SearchService) WikiBlobsByProject(pid any, query string, opt *SearchOpt func (s *SearchService) Commits(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { return do[[]*Commit](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "commits", Search: query}), withAPIOpts(newSearchOptions(opt, "commits", query)), withRequestOpts(options...), ) } Loading @@ -288,7 +298,7 @@ func (s *SearchService) Commits(query string, opt *SearchOptions, options ...Req func (s *SearchService) CommitsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { return do[[]*Commit](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "commits", Search: query}), withAPIOpts(newSearchOptions(opt, "commits", query)), withRequestOpts(options...), ) } Loading @@ -300,7 +310,7 @@ func (s *SearchService) CommitsByGroup(gid any, query string, opt *SearchOptions func (s *SearchService) CommitsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) { return do[[]*Commit](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "commits", Search: query}), withAPIOpts(newSearchOptions(opt, "commits", query)), withRequestOpts(options...), ) } Loading @@ -323,7 +333,7 @@ type Blob struct { func (s *SearchService) Blobs(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { return do[[]*Blob](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "blobs", query)), withRequestOpts(options...), ) } Loading @@ -335,7 +345,7 @@ func (s *SearchService) Blobs(query string, opt *SearchOptions, options ...Reque func (s *SearchService) BlobsByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { return do[[]*Blob](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "blobs", query)), withRequestOpts(options...), ) } Loading @@ -347,7 +357,7 @@ func (s *SearchService) BlobsByGroup(gid any, query string, opt *SearchOptions, func (s *SearchService) BlobsByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*Blob, *Response, error) { return do[[]*Blob](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "blobs", Search: query}), withAPIOpts(newSearchOptions(opt, "blobs", query)), withRequestOpts(options...), ) } Loading @@ -358,7 +368,7 @@ func (s *SearchService) BlobsByProject(pid any, query string, opt *SearchOptions func (s *SearchService) Users(query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { return do[[]*User](s.client, withPath(routeSearch), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "users", Search: query}), withAPIOpts(newSearchOptions(opt, "users", query)), withRequestOpts(options...), ) } Loading @@ -368,12 +378,9 @@ func (s *SearchService) Users(query string, opt *SearchOptions, options ...Reque // // GitLab API docs: https://docs.gitlab.com/api/search/#scope-users-1 func (s *SearchService) UsersByGroup(gid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { if opt == nil { opt = &SearchOptions{} } return do[[]*User](s.client, withPath(routeGroupsIDSearch, GroupID{gid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "users", Search: query}), withAPIOpts(newSearchOptions(opt, "users", query)), withRequestOpts(options...), ) } Loading @@ -385,7 +392,7 @@ func (s *SearchService) UsersByGroup(gid any, query string, opt *SearchOptions, func (s *SearchService) UsersByProject(pid any, query string, opt *SearchOptions, options ...RequestOptionFunc) ([]*User, *Response, error) { return do[[]*User](s.client, withPath(routeProjectsIDSearch, ProjectID{pid}), withAPIOpts(&searchOptions{SearchOptions: *opt, Scope: "users", Search: query}), withAPIOpts(newSearchOptions(opt, "users", query)), withRequestOpts(options...), ) }
search_test.go +178 −0 Changes for search_test.go: 178 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -19,9 +19,11 @@ package gitlab import ( "fmt" "net/http" "net/url" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestSearchService_Users(t *testing.T) { Loading Loading @@ -687,3 +689,179 @@ func TestSearchService_BlobsByProject(t *testing.T) { assert.NotNil(t, resp) assert.Len(t, blobs, 1) } func TestSearchService_SearchOptions(t *testing.T) { t.Parallel() const ( searchPath = "/api/v4/search" groupSearchPath = "/api/v4/groups/1/-/search" projectSearchPath = "/api/v4/projects/1/-/search" ) tests := []struct { name string path string scope string call func(s SearchServiceInterface, opt *SearchOptions) (int, error) }{ {"Projects", searchPath, "projects", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Projects("fix", opt) return len(r), err }}, {"ProjectsByGroup", groupSearchPath, "projects", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.ProjectsByGroup(1, "fix", opt) return len(r), err }}, {"Issues", searchPath, "issues", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Issues("fix", opt) return len(r), err }}, {"IssuesByGroup", groupSearchPath, "issues", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.IssuesByGroup(1, "fix", opt) return len(r), err }}, {"IssuesByProject", projectSearchPath, "issues", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.IssuesByProject(1, "fix", opt) return len(r), err }}, {"MergeRequests", searchPath, "merge_requests", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.MergeRequests("fix", opt) return len(r), err }}, {"MergeRequestsByGroup", groupSearchPath, "merge_requests", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.MergeRequestsByGroup(1, "fix", opt) return len(r), err }}, {"MergeRequestsByProject", projectSearchPath, "merge_requests", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.MergeRequestsByProject(1, "fix", opt) return len(r), err }}, {"Milestones", searchPath, "milestones", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Milestones("fix", opt) return len(r), err }}, {"MilestonesByGroup", groupSearchPath, "milestones", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.MilestonesByGroup(1, "fix", opt) return len(r), err }}, {"MilestonesByProject", projectSearchPath, "milestones", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.MilestonesByProject(1, "fix", opt) return len(r), err }}, {"SnippetTitles", searchPath, "snippet_titles", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.SnippetTitles("fix", opt) return len(r), err }}, {"NotesByProject", projectSearchPath, "notes", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.NotesByProject(1, "fix", opt) return len(r), err }}, {"WikiBlobs", searchPath, "wiki_blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.WikiBlobs("fix", opt) return len(r), err }}, {"WikiBlobsByGroup", groupSearchPath, "wiki_blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.WikiBlobsByGroup(1, "fix", opt) return len(r), err }}, {"WikiBlobsByProject", projectSearchPath, "wiki_blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.WikiBlobsByProject(1, "fix", opt) return len(r), err }}, {"Commits", searchPath, "commits", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Commits("fix", opt) return len(r), err }}, {"CommitsByGroup", groupSearchPath, "commits", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.CommitsByGroup(1, "fix", opt) return len(r), err }}, {"CommitsByProject", projectSearchPath, "commits", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.CommitsByProject(1, "fix", opt) return len(r), err }}, {"Blobs", searchPath, "blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Blobs("fix", opt) return len(r), err }}, {"BlobsByGroup", groupSearchPath, "blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.BlobsByGroup(1, "fix", opt) return len(r), err }}, {"BlobsByProject", projectSearchPath, "blobs", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.BlobsByProject(1, "fix", opt) return len(r), err }}, {"Users", searchPath, "users", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.Users("fix", opt) return len(r), err }}, {"UsersByGroup", groupSearchPath, "users", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.UsersByGroup(1, "fix", opt) return len(r), err }}, {"UsersByProject", projectSearchPath, "users", func(s SearchServiceInterface, opt *SearchOptions) (int, error) { r, _, err := s.UsersByProject(1, "fix", opt) return len(r), err }}, } for _, tt := range tests { t.Run(tt.name+"/nil options", func(t *testing.T) { t.Parallel() mux, client := setup(t) mux.HandleFunc(tt.path, func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) assert.Equal(t, url.Values{"scope": {tt.scope}, "search": {"fix"}}, r.URL.Query()) fmt.Fprint(w, `[{}]`) }) // GIVEN nil search options // WHEN the search method is called var ( n int err error ) require.NotPanics(t, func() { n, err = tt.call(client.Search, nil) }) // THEN the request carries only the scope and the search term require.NoError(t, err) assert.Equal(t, 1, n) }) t.Run(tt.name+"/with options", func(t *testing.T) { t.Parallel() mux, client := setup(t) mux.HandleFunc(tt.path, func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodGet) want := url.Values{ "scope": {tt.scope}, "search": {"fix"}, "page": {"2"}, "per_page": {"5"}, "ref": {"main"}, "search_type": {"basic"}, } assert.Equal(t, want, r.URL.Query()) fmt.Fprint(w, `[{}]`) }) // GIVEN search options opt := &SearchOptions{ ListOptions: ListOptions{Page: 2, PerPage: 5}, Ref: new("main"), SearchType: new(BasicSearch), } // WHEN the search method is called n, err := tt.call(client.Search, opt) // THEN the options are sent with the scope and the search term require.NoError(t, err) assert.Equal(t, 1, n) }) } }