Commit 22bf8448 authored by Valery Sizov's avatar Valery Sizov

fix specs. Stage 3

parent 9a3d0f1d
...@@ -245,6 +245,44 @@ module API ...@@ -245,6 +245,44 @@ module API
error!({ 'message' => message }, status) error!({ 'message' => message }, status)
end end
# Projects helpers
def filter_projects(projects)
# If the archived parameter is passed, limit results accordingly
if params[:archived].present?
projects = projects.where(archived: parse_boolean(params[:archived]))
end
if params[:search].present?
projects = projects.search(params[:search])
end
if params[:ci_enabled_first].present?
projects.includes(:gitlab_ci_service).
reorder("services.active DESC, projects.#{project_order_by} #{project_sort}")
else
projects.reorder(project_order_by => project_sort)
end
end
def project_order_by
order_fields = %w(id name path created_at updated_at last_activity_at)
if order_fields.include?(params['order_by'])
params['order_by']
else
'created_at'
end
end
def project_sort
if params["sort"] == 'asc'
:asc
else
:desc
end
end
private private
def add_pagination_headers(paginated, per_page) def add_pagination_headers(paginated, per_page)
......
...@@ -11,42 +11,6 @@ module API ...@@ -11,42 +11,6 @@ module API
attrs[:visibility_level] = Gitlab::VisibilityLevel::PUBLIC if !attrs[:visibility_level].present? && publik == true attrs[:visibility_level] = Gitlab::VisibilityLevel::PUBLIC if !attrs[:visibility_level].present? && publik == true
attrs attrs
end end
def filter_projects(projects)
# If the archived parameter is passed, limit results accordingly
if params[:archived].present?
projects = projects.where(archived: parse_boolean(params[:archived]))
end
if params[:search].present?
projects = projects.search(params[:search])
end
if params[:ci_enabled_first].present?
projects.includes(:gitlab_ci_service).
reorder("services.active DESC, projects.#{project_order_by} #{project_sort}")
else
projects.reorder(project_order_by => project_sort)
end
end
def project_order_by
order_fields = %w(id name path created_at updated_at last_activity_at)
if order_fields.include?(params['order_by'])
params['order_by']
else
'created_at'
end
end
def project_sort
if params["sort"] == 'asc'
:asc
else
:desc
end
end
end end
# Get a projects list for authenticated user # Get a projects list for authenticated user
......
...@@ -34,8 +34,12 @@ module Ci ...@@ -34,8 +34,12 @@ module Ci
end end
class Project < Grape::Entity class Project < Grape::Entity
expose :id, :name, :timeout, :token, :default_ref, :gitlab_url, :path, expose :id, :name, :token, :default_ref, :gitlab_url, :path,
:always_build, :polling_interval, :public, :ssh_url_to_repo, :gitlab_id :always_build, :polling_interval, :public, :ssh_url_to_repo, :gitlab_id
expose :timeout do |model|
model.timeout
end
end end
class RunnerProject < Grape::Entity class RunnerProject < Grape::Entity
......
...@@ -17,7 +17,7 @@ module Ci ...@@ -17,7 +17,7 @@ module Ci
project = Ci::Project.find(params[:project_id]) project = Ci::Project.find(params[:project_id])
unauthorized! unless current_user.can_manage_project?(project.gitlab_id) unauthorized! unless can?(current_user, :manage_project, project.gl_project)
web_hook = project.web_hooks.new({ url: params[:web_hook] }) web_hook = project.web_hooks.new({ url: params[:web_hook] })
...@@ -34,9 +34,10 @@ module Ci ...@@ -34,9 +34,10 @@ module Ci
# Example Request: # Example Request:
# GET /projects # GET /projects
get do get do
gitlab_projects = Ci::Project.from_gitlab( gitlab_projects = current_user.authorized_projects
current_user, :authorized, { page: params[:page], per_page: params[:per_page], ci_enabled_first: true } gitlab_projects = filter_projects(gitlab_projects)
) gitlab_projects = paginate gitlab_projects
ids = gitlab_projects.map { |project| project.id } ids = gitlab_projects.map { |project| project.id }
projects = Ci::Project.where("gitlab_id IN (?)", ids).load projects = Ci::Project.where("gitlab_id IN (?)", ids).load
...@@ -48,9 +49,10 @@ module Ci ...@@ -48,9 +49,10 @@ module Ci
# Example Request: # Example Request:
# GET /projects/owned # GET /projects/owned
get "owned" do get "owned" do
gitlab_projects = Ci::Project.from_gitlab( gitlab_projects = current_user.owned_projects
current_user, :owned, { page: params[:page], per_page: params[:per_page], ci_enabled_first: true } gitlab_projects = filter_projects(gitlab_projects)
) gitlab_projects = paginate gitlab_projects
ids = gitlab_projects.map { |project| project.id } ids = gitlab_projects.map { |project| project.id }
projects = Ci::Project.where("gitlab_id IN (?)", ids).load projects = Ci::Project.where("gitlab_id IN (?)", ids).load
...@@ -65,8 +67,7 @@ module Ci ...@@ -65,8 +67,7 @@ module Ci
# GET /projects/:id # GET /projects/:id
get ":id" do get ":id" do
project = Ci::Project.find(params[:id]) project = Ci::Project.find(params[:id])
unauthorized! unless can?(current_user, :read_project, project.gl_project)
unauthorized! unless can?(current_user, :read_project, gl_project)
present project, with: Entities::Project present project, with: Entities::Project
end end
...@@ -118,7 +119,7 @@ module Ci ...@@ -118,7 +119,7 @@ module Ci
put ":id" do put ":id" do
project = Ci::Project.find(params[:id]) project = Ci::Project.find(params[:id])
unauthorized! unless can?(current_user, :manage_project, gl_project) unauthorized! unless can?(current_user, :manage_project, project.gl_project)
attrs = attributes_for_keys [:name, :gitlab_id, :path, :gitlab_url, :default_ref, :ssh_url_to_repo] attrs = attributes_for_keys [:name, :gitlab_id, :path, :gitlab_url, :default_ref, :ssh_url_to_repo]
...@@ -144,7 +145,7 @@ module Ci ...@@ -144,7 +145,7 @@ module Ci
delete ":id" do delete ":id" do
project = Ci::Project.find(params[:id]) project = Ci::Project.find(params[:id])
unauthorized! unless can?(current_user, :manage_project, gl_project) unauthorized! unless can?(current_user, :manage_project, project.gl_project)
project.destroy project.destroy
end end
...@@ -160,7 +161,7 @@ module Ci ...@@ -160,7 +161,7 @@ module Ci
project = Ci::Project.find(params[:id]) project = Ci::Project.find(params[:id])
runner = Ci::Runner.find(params[:runner_id]) runner = Ci::Runner.find(params[:runner_id])
unauthorized! unless can?(current_user, :manage_project, gl_project) unauthorized! unless can?(current_user, :manage_project, project.gl_project)
options = { options = {
project_id: project.id, project_id: project.id,
...@@ -188,7 +189,7 @@ module Ci ...@@ -188,7 +189,7 @@ module Ci
project = Ci::Project.find(params[:id]) project = Ci::Project.find(params[:id])
runner = Ci::Runner.find(params[:runner_id]) runner = Ci::Runner.find(params[:runner_id])
unauthorized! unless can?(current_user, :manage_project, gl_project) unauthorized! unless can?(current_user, :manage_project, project.gl_project)
options = { options = {
project_id: project.id, project_id: project.id,
......
...@@ -3,8 +3,9 @@ require 'spec_helper' ...@@ -3,8 +3,9 @@ require 'spec_helper'
describe Ci::API::API do describe Ci::API::API do
include ApiHelpers include ApiHelpers
let(:gitlab_url) { GitlabCi.config.gitlab_server.url } let(:gitlab_url) { GitlabCi.config.gitlab_ci.url }
let(:private_token) { Network.new.authenticate(access_token: "some_token")["private_token"] } let(:user) { create(:user) }
let(:private_token) { user.private_token }
let(:options) do let(:options) do
{ {
...@@ -20,11 +21,16 @@ describe Ci::API::API do ...@@ -20,11 +21,16 @@ describe Ci::API::API do
context "requests for scoped projects" do context "requests for scoped projects" do
# NOTE: These ids are tied to the actual projects on demo.gitlab.com # NOTE: These ids are tied to the actual projects on demo.gitlab.com
describe "GET /projects" do describe "GET /projects" do
let!(:project1) { FactoryGirl.create(:ci_project, name: "gitlabhq", gitlab_id: 3) } let!(:project1) { FactoryGirl.create(:ci_project) }
let!(:project2) { FactoryGirl.create(:ci_project, name: "gitlab-ci", gitlab_id: 4) } let!(:project2) { FactoryGirl.create(:ci_project) }
before do
project1.gl_project.team << [user, :developer]
project2.gl_project.team << [user, :developer]
end
it "should return all projects on the CI instance" do it "should return all projects on the CI instance" do
get api("/projects"), options get ci_api("/projects"), options
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response.count).to eq(2) expect(json_response.count).to eq(2)
expect(json_response.first["id"]).to eq(project1.id) expect(json_response.first["id"]).to eq(project1.id)
...@@ -33,15 +39,21 @@ describe Ci::API::API do ...@@ -33,15 +39,21 @@ describe Ci::API::API do
end end
describe "GET /projects/owned" do describe "GET /projects/owned" do
# NOTE: This user doesn't own any of these projects on demo.gitlab.com let!(:gl_project1) {FactoryGirl.create(:empty_project, namespace: user.namespace)}
let!(:project1) { FactoryGirl.create(:ci_project, name: "gitlabhq", gitlab_id: 3) } let!(:gl_project2) {FactoryGirl.create(:empty_project, namespace: user.namespace)}
let!(:project2) { FactoryGirl.create(:ci_project, name: "random-project", gitlab_id: 9898) } let!(:project1) { FactoryGirl.create(:ci_project, gl_project: gl_project1) }
let!(:project2) { FactoryGirl.create(:ci_project, gl_project: gl_project2) }
before do
project1.gl_project.team << [user, :developer]
project2.gl_project.team << [user, :developer]
end
it "should return all projects on the CI instance" do it "should return all projects on the CI instance" do
get api("/projects/owned"), options get ci_api("/projects/owned"), options
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response.count).to eq(0) expect(json_response.count).to eq(2)
end end
end end
end end
...@@ -54,22 +66,23 @@ describe Ci::API::API do ...@@ -54,22 +66,23 @@ describe Ci::API::API do
before do before do
options.merge!(webhook) options.merge!(webhook)
project.gl_project.team << [user, :master]
end end
it "should create webhook for specified project" do it "should create webhook for specified project" do
post api("/projects/#{project.id}/webhooks"), options post ci_api("/projects/#{project.id}/webhooks"), options
expect(response.status).to eq(201) expect(response.status).to eq(201)
expect(json_response["url"]).to eq(webhook[:web_hook]) expect(json_response["url"]).to eq(webhook[:web_hook])
end end
it "fails to create webhook for non existsing project" do it "fails to create webhook for non existsing project" do
post api("/projects/non-existant-id/webhooks"), options post ci_api("/projects/non-existant-id/webhooks"), options
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
it "non-manager is not authorized" do it "non-manager is not authorized" do
allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false) allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false)
post api("/projects/#{project.id}/webhooks"), options post ci_api("/projects/#{project.id}/webhooks"), options
expect(response.status).to eq(401) expect(response.status).to eq(401)
end end
end end
...@@ -82,14 +95,14 @@ describe Ci::API::API do ...@@ -82,14 +95,14 @@ describe Ci::API::API do
end end
it "fails to create webhook for not valid url" do it "fails to create webhook for not valid url" do
post api("/projects/#{project.id}/webhooks"), options post ci_api("/projects/#{project.id}/webhooks"), options
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
end end
context "Missed web_hook parameter" do context "Missed web_hook parameter" do
it "fails to create webhook for not provided url" do it "fails to create webhook for not provided url" do
post api("/projects/#{project.id}/webhooks"), options post ci_api("/projects/#{project.id}/webhooks"), options
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
end end
...@@ -98,9 +111,13 @@ describe Ci::API::API do ...@@ -98,9 +111,13 @@ describe Ci::API::API do
describe "GET /projects/:id" do describe "GET /projects/:id" do
let!(:project) { FactoryGirl.create(:ci_project) } let!(:project) { FactoryGirl.create(:ci_project) }
before do
project.gl_project.team << [user, :developer]
end
context "with an existing project" do context "with an existing project" do
it "should retrieve the project info" do it "should retrieve the project info" do
get api("/projects/#{project.id}"), options get ci_api("/projects/#{project.id}"), options
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response['id']).to eq(project.id) expect(json_response['id']).to eq(project.id)
end end
...@@ -108,7 +125,7 @@ describe Ci::API::API do ...@@ -108,7 +125,7 @@ describe Ci::API::API do
context "with a non-existing project" do context "with a non-existing project" do
it "should return 404 error if project not found" do it "should return 404 error if project not found" do
get api("/projects/non_existent_id"), options get ci_api("/projects/non_existent_id"), options
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
end end
...@@ -123,19 +140,19 @@ describe Ci::API::API do ...@@ -123,19 +140,19 @@ describe Ci::API::API do
end end
it "should update a specific project's information" do it "should update a specific project's information" do
put api("/projects/#{project.id}"), options put ci_api("/projects/#{project.id}"), options
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(json_response["name"]).to eq(project_info[:name]) expect(json_response["name"]).to eq(project_info[:name])
end end
it "fails to update a non-existing project" do it "fails to update a non-existing project" do
put api("/projects/non-existant-id"), options put ci_api("/projects/non-existant-id"), options
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
it "non-manager is not authorized" do it "non-manager is not authorized" do
allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false) allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false)
put api("/projects/#{project.id}"), options put ci_api("/projects/#{project.id}"), options
expect(response.status).to eq(401) expect(response.status).to eq(401)
end end
end end
...@@ -144,7 +161,7 @@ describe Ci::API::API do ...@@ -144,7 +161,7 @@ describe Ci::API::API do
let!(:project) { FactoryGirl.create(:ci_project) } let!(:project) { FactoryGirl.create(:ci_project) }
it "should delete a specific project" do it "should delete a specific project" do
delete api("/projects/#{project.id}"), options delete ci_api("/projects/#{project.id}"), options
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect { project.reload }.to raise_error expect { project.reload }.to raise_error
...@@ -152,12 +169,12 @@ describe Ci::API::API do ...@@ -152,12 +169,12 @@ describe Ci::API::API do
it "non-manager is not authorized" do it "non-manager is not authorized" do
allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false) allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false)
delete api("/projects/#{project.id}"), options delete ci_api("/projects/#{project.id}"), options
expect(response.status).to eq(401) expect(response.status).to eq(401)
end end
it "is getting not found error" do it "is getting not found error" do
delete api("/projects/not-existing_id"), options delete ci_api("/projects/not-existing_id"), options
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
end end
...@@ -180,7 +197,7 @@ describe Ci::API::API do ...@@ -180,7 +197,7 @@ describe Ci::API::API do
end end
it "should create a project with valid data" do it "should create a project with valid data" do
post api("/projects"), options post ci_api("/projects"), options
expect(response.status).to eq(201) expect(response.status).to eq(201)
expect(json_response['name']).to eq(project_info[:name]) expect(json_response['name']).to eq(project_info[:name])
end end
...@@ -192,7 +209,7 @@ describe Ci::API::API do ...@@ -192,7 +209,7 @@ describe Ci::API::API do
end end
it "should error with invalid data" do it "should error with invalid data" do
post api("/projects"), options post ci_api("/projects"), options
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
end end
...@@ -202,7 +219,7 @@ describe Ci::API::API do ...@@ -202,7 +219,7 @@ describe Ci::API::API do
let(:runner) { FactoryGirl.create(:ci_runner) } let(:runner) { FactoryGirl.create(:ci_runner) }
it "should add the project to the runner" do it "should add the project to the runner" do
post api("/projects/#{project.id}/runners/#{runner.id}"), options post ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
expect(response.status).to eq(201) expect(response.status).to eq(201)
project.reload project.reload
...@@ -210,16 +227,16 @@ describe Ci::API::API do ...@@ -210,16 +227,16 @@ describe Ci::API::API do
end end
it "should fail if it tries to link a non-existing project or runner" do it "should fail if it tries to link a non-existing project or runner" do
post api("/projects/#{project.id}/runners/non-existing"), options post ci_api("/projects/#{project.id}/runners/non-existing"), options
expect(response.status).to eq(404) expect(response.status).to eq(404)
post api("/projects/non-existing/runners/#{runner.id}"), options post ci_api("/projects/non-existing/runners/#{runner.id}"), options
expect(response.status).to eq(404) expect(response.status).to eq(404)
end end
it "non-manager is not authorized" do it "non-manager is not authorized" do
allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false) allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false)
post api("/projects/#{project.id}/runners/#{runner.id}"), options post ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
expect(response.status).to eq(401) expect(response.status).to eq(401)
end end
end end
...@@ -229,12 +246,12 @@ describe Ci::API::API do ...@@ -229,12 +246,12 @@ describe Ci::API::API do
let(:runner) { FactoryGirl.create(:ci_runner) } let(:runner) { FactoryGirl.create(:ci_runner) }
before do before do
post api("/projects/#{project.id}/runners/#{runner.id}"), options post ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
end end
it "should remove the project from the runner" do it "should remove the project from the runner" do
expect(project.runners).to be_present expect(project.runners).to be_present
delete api("/projects/#{project.id}/runners/#{runner.id}"), options delete ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
expect(response.status).to eq(200) expect(response.status).to eq(200)
project.reload project.reload
...@@ -243,7 +260,7 @@ describe Ci::API::API do ...@@ -243,7 +260,7 @@ describe Ci::API::API do
it "non-manager is not authorized" do it "non-manager is not authorized" do
allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false) allow_any_instance_of(User).to receive(:can_manage_project?).and_return(false)
post api("/projects/#{project.id}/runners/#{runner.id}"), options post ci_api("/projects/#{project.id}/runners/#{runner.id}"), options
expect(response.status).to eq(401) expect(response.status).to eq(401)
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment