Commit 4cfbfbb845680f2df67110ca15f2479cba8e2441
1 parent
0630be38
Exists in
master
and in
4 other branches
Added search for projects by name to api
GITLAB-1283 (GITLAB-869) Change-Id: I611e7e93f6292de08e1edc8d3ea77cf9087b6ded Conflicts: config/initializers/1_settings.rb
Showing
3 changed files
with
73 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? | ... | ... |
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,22 @@ 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, defaults to 20 | |
270 | + # offset (optional) - the offset in pages to retrieve | |
271 | + # Example Request: | |
272 | + # GET /projects/search/:query | |
273 | + get "/search/:query" do | |
274 | + limit = (params[:per_page] || 20).to_i | |
275 | + offset = (params[:page] || 0).to_i * limit | |
276 | + ids = current_user.authorized_projects.map(&:id) | |
277 | + projects = Project.where("(id in (?) OR public = true) AND (name LIKE (?))", ids, "%#{params[:query]}%").limit(limit).offset(offset) | |
278 | + present projects, with: Entities::Project | |
279 | + end | |
265 | 280 | end |
266 | 281 | end |
267 | 282 | 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 | ... | ... |