Commit 1165759b14b02ad87dff46716e37e569f678b0b5
Exists in
master
and in
4 other branches
Merge pull request #5146 from karlhungus/feature-api-search-for-projects-by-name
Added search for projects by name to api
Showing
4 changed files
with
86 additions
and
20 deletions
Show diff stats
app/contexts/search_context.rb
... | ... | @@ -13,7 +13,7 @@ class SearchContext |
13 | 13 | projects = Project.where(id: project_ids) |
14 | 14 | result[:projects] = projects.search(query).limit(20) |
15 | 15 | |
16 | - # Search inside singe project | |
16 | + # Search inside single project | |
17 | 17 | project = projects.first if projects.length == 1 |
18 | 18 | |
19 | 19 | if params[:search_code].present? | ... | ... |
doc/api/projects.md
... | ... | @@ -484,3 +484,18 @@ DELETE /projects/:id/fork |
484 | 484 | Parameter: |
485 | 485 | |
486 | 486 | + `id` (required) - The ID of the project |
487 | + | |
488 | + | |
489 | +## Search for projects by name | |
490 | + | |
491 | +Search for projects by name which are public or the calling user has access to | |
492 | + | |
493 | +``` | |
494 | +GET /projects/search/:query | |
495 | +``` | |
496 | + | |
497 | +Parameters: | |
498 | + | |
499 | ++ query (required) - A string contained in the project name | |
500 | ++ per_page (optional) - number of projects to return per page | |
501 | ++ page (optional) - the page to retrieve | ... | ... |
lib/api/projects.rb
... | ... | @@ -73,16 +73,16 @@ module API |
73 | 73 | post do |
74 | 74 | required_attributes! [:name] |
75 | 75 | attrs = attributes_for_keys [:name, |
76 | - :path, | |
77 | - :description, | |
78 | - :default_branch, | |
79 | - :issues_enabled, | |
80 | - :wall_enabled, | |
81 | - :merge_requests_enabled, | |
82 | - :wiki_enabled, | |
83 | - :snippets_enabled, | |
84 | - :namespace_id, | |
85 | - :public] | |
76 | + :path, | |
77 | + :description, | |
78 | + :default_branch, | |
79 | + :issues_enabled, | |
80 | + :wall_enabled, | |
81 | + :merge_requests_enabled, | |
82 | + :wiki_enabled, | |
83 | + :snippets_enabled, | |
84 | + :namespace_id, | |
85 | + :public] | |
86 | 86 | @project = ::Projects::CreateContext.new(current_user, attrs).execute |
87 | 87 | if @project.saved? |
88 | 88 | present @project, with: Entities::Project |
... | ... | @@ -113,14 +113,14 @@ module API |
113 | 113 | authenticated_as_admin! |
114 | 114 | user = User.find(params[:user_id]) |
115 | 115 | attrs = attributes_for_keys [:name, |
116 | - :description, | |
117 | - :default_branch, | |
118 | - :issues_enabled, | |
119 | - :wall_enabled, | |
120 | - :merge_requests_enabled, | |
121 | - :wiki_enabled, | |
122 | - :snippets_enabled, | |
123 | - :public] | |
116 | + :description, | |
117 | + :default_branch, | |
118 | + :issues_enabled, | |
119 | + :wall_enabled, | |
120 | + :merge_requests_enabled, | |
121 | + :wiki_enabled, | |
122 | + :snippets_enabled, | |
123 | + :public] | |
124 | 124 | @project = ::Projects::CreateContext.new(user, attrs).execute |
125 | 125 | if @project.saved? |
126 | 126 | present @project, with: Entities::Project |
... | ... | @@ -165,7 +165,6 @@ module API |
165 | 165 | end |
166 | 166 | end |
167 | 167 | |
168 | - | |
169 | 168 | # Get a project team members |
170 | 169 | # |
171 | 170 | # Parameters: |
... | ... | @@ -262,6 +261,20 @@ module API |
262 | 261 | {message: "Access revoked", id: params[:user_id].to_i} |
263 | 262 | end |
264 | 263 | end |
264 | + | |
265 | + # search for projects current_user has access to | |
266 | + # | |
267 | + # Parameters: | |
268 | + # query (required) - A string contained in the project name | |
269 | + # per_page (optional) - number of projects to return per page | |
270 | + # page (optional) - the page to retrieve | |
271 | + # Example Request: | |
272 | + # GET /projects/search/:query | |
273 | + get "/search/:query" do | |
274 | + ids = current_user.authorized_projects.map(&:id) | |
275 | + projects = Project.where("(id in (?) OR public = true) AND (name LIKE (?))", ids, "%#{params[:query]}%") | |
276 | + present paginate(projects), with: Entities::Project | |
277 | + end | |
265 | 278 | end |
266 | 279 | end |
267 | 280 | end | ... | ... |
spec/requests/api/projects_spec.rb
... | ... | @@ -692,4 +692,42 @@ describe API::API do |
692 | 692 | end |
693 | 693 | end |
694 | 694 | end |
695 | + | |
696 | + describe "GET /projects/search/:query" do | |
697 | + let!(:query) { 'query'} | |
698 | + let!(:search) { create(:project, name: query, creator_id: user.id, namespace: user.namespace) } | |
699 | + let!(:pre) { create(:project, name: "pre_#{query}", creator_id: user.id, namespace: user.namespace) } | |
700 | + let!(:post) { create(:project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) } | |
701 | + let!(:pre_post) { create(:project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) } | |
702 | + let!(:unfound) { create(:project, name: 'unfound', creator_id: user.id, namespace: user.namespace) } | |
703 | + let!(:public) { create(:project, name: "another #{query}",public: true) } | |
704 | + let!(:unfound_public) { create(:project, name: 'unfound public', public: true) } | |
705 | + | |
706 | + context "when unauthenticated" do | |
707 | + it "should return authentication error" do | |
708 | + get api("/projects/search/#{query}") | |
709 | + response.status.should == 401 | |
710 | + end | |
711 | + end | |
712 | + | |
713 | + context "when authenticated" do | |
714 | + it "should return an array of projects" do | |
715 | + get api("/projects/search/#{query}",user) | |
716 | + response.status.should == 200 | |
717 | + json_response.should be_an Array | |
718 | + json_response.size.should == 5 | |
719 | + json_response.each {|project| project['name'].should =~ /.*query.*/} | |
720 | + end | |
721 | + end | |
722 | + | |
723 | + context "when authenticated as a different user" do | |
724 | + it "should return matching public projects" do | |
725 | + get api("/projects/search/#{query}", user2) | |
726 | + response.status.should == 200 | |
727 | + json_response.should be_an Array | |
728 | + json_response.size.should == 1 | |
729 | + json_response.first['name'].should == "another #{query}" | |
730 | + end | |
731 | + end | |
732 | + end | |
695 | 733 | end | ... | ... |