diff --git a/app/contexts/search_context.rb b/app/contexts/search_context.rb index 0817d52cd00c265207b8e2d2a833d8e184ea2eaf..48def0784fdba884f21753e954638b18046b8482 100644 --- a/app/contexts/search_context.rb +++ b/app/contexts/search_context.rb @@ -13,7 +13,7 @@ class SearchContext projects = Project.where(id: project_ids) result[:projects] = projects.search(query).limit(20) - # Search inside singe project + # Search inside single project project = projects.first if projects.length == 1 if params[:search_code].present? diff --git a/doc/api/projects.md b/doc/api/projects.md index 9afffcbaa80685f86ac2ae9400a454b12b5e3d0b..5150331e7d7face41f2ca53bd234531f4bc3b536 100644 --- a/doc/api/projects.md +++ b/doc/api/projects.md @@ -484,3 +484,18 @@ DELETE /projects/:id/fork Parameter: + `id` (required) - The ID of the project + + +## Search for projects by name + +Search for projects by name which are public or the calling user has access to + +``` +GET /projects/search/:query +``` + +Parameters: + ++ query (required) - A string contained in the project name ++ per_page (optional) - number of projects to return per page ++ page (optional) - the page to retrieve diff --git a/lib/api/projects.rb b/lib/api/projects.rb index c6ff524cb0603b318fc64a24b0826d91ea2a68fb..cf357b23c406fbbd6074162794d559fe069a79f4 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -73,16 +73,16 @@ module API post do required_attributes! [:name] attrs = attributes_for_keys [:name, - :path, - :description, - :default_branch, - :issues_enabled, - :wall_enabled, - :merge_requests_enabled, - :wiki_enabled, - :snippets_enabled, - :namespace_id, - :public] + :path, + :description, + :default_branch, + :issues_enabled, + :wall_enabled, + :merge_requests_enabled, + :wiki_enabled, + :snippets_enabled, + :namespace_id, + :public] @project = ::Projects::CreateContext.new(current_user, attrs).execute if @project.saved? present @project, with: Entities::Project @@ -113,14 +113,14 @@ module API authenticated_as_admin! user = User.find(params[:user_id]) attrs = attributes_for_keys [:name, - :description, - :default_branch, - :issues_enabled, - :wall_enabled, - :merge_requests_enabled, - :wiki_enabled, - :snippets_enabled, - :public] + :description, + :default_branch, + :issues_enabled, + :wall_enabled, + :merge_requests_enabled, + :wiki_enabled, + :snippets_enabled, + :public] @project = ::Projects::CreateContext.new(user, attrs).execute if @project.saved? present @project, with: Entities::Project @@ -165,7 +165,6 @@ module API end end - # Get a project team members # # Parameters: @@ -262,6 +261,20 @@ module API {message: "Access revoked", id: params[:user_id].to_i} end end + + # search for projects current_user has access to + # + # Parameters: + # query (required) - A string contained in the project name + # per_page (optional) - number of projects to return per page + # page (optional) - the page to retrieve + # Example Request: + # GET /projects/search/:query + get "/search/:query" do + ids = current_user.authorized_projects.map(&:id) + projects = Project.where("(id in (?) OR public = true) AND (name LIKE (?))", ids, "%#{params[:query]}%") + present paginate(projects), with: Entities::Project + end end end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 2de3dc55e4030037d4781f9adbc57d1b3441af8f..b8c0b6f33edf4c3180164fb541b1cc4321f35ea2 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -692,4 +692,42 @@ describe API::API do end end end + + describe "GET /projects/search/:query" do + let!(:query) { 'query'} + let!(:search) { create(:project, name: query, creator_id: user.id, namespace: user.namespace) } + let!(:pre) { create(:project, name: "pre_#{query}", creator_id: user.id, namespace: user.namespace) } + let!(:post) { create(:project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) } + let!(:pre_post) { create(:project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) } + let!(:unfound) { create(:project, name: 'unfound', creator_id: user.id, namespace: user.namespace) } + let!(:public) { create(:project, name: "another #{query}",public: true) } + let!(:unfound_public) { create(:project, name: 'unfound public', public: true) } + + context "when unauthenticated" do + it "should return authentication error" do + get api("/projects/search/#{query}") + response.status.should == 401 + end + end + + context "when authenticated" do + it "should return an array of projects" do + get api("/projects/search/#{query}",user) + response.status.should == 200 + json_response.should be_an Array + json_response.size.should == 5 + json_response.each {|project| project['name'].should =~ /.*query.*/} + end + end + + context "when authenticated as a different user" do + it "should return matching public projects" do + get api("/projects/search/#{query}", user2) + response.status.should == 200 + json_response.should be_an Array + json_response.size.should == 1 + json_response.first['name'].should == "another #{query}" + end + end + end end