summaryrefslogtreecommitdiff
path: root/spec/requests
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2016-08-19 17:41:53 +0800
committerLin Jen-Shin <godfat@godfat.org>2016-08-19 17:41:53 +0800
commit9c9259cc6a08d8b2f8f827598aba06baae7b31f6 (patch)
tree65e103ef2126a46e0ed693f91d5e40a371d9c2ca /spec/requests
parent62127dc95a28d6e7018a72c1a643dbf828a806d4 (diff)
parent12fe6a6fd733110acc72aa0f5bdaec2b1fa1f358 (diff)
downloadgitlab-ce-9c9259cc6a08d8b2f8f827598aba06baae7b31f6.tar.gz
Merge remote-tracking branch 'upstream/master' into artifacts-from-ref-and-build-name
* upstream/master: (195 commits) Fix expansion of discussions in diff Improve performance of MR show page Fix jumping between discussions on changes tab Update doorkeeper to 4.2.0 Fix MR note discussion ID Handle legacy sort order values Refactor `find_for_git_client` and its related methods. Remove right margin on Jump button icon Fix bug causing “Jump to discussion” button not to show Small refactor and syntax fixes. Removed unnecessary service for user retrieval and improved API error message. Added documentation and CHANGELOG item Added checks for 2FA to the API `/sessions` endpoint and the Resource Owner Password Credentials flow. Fix behavior around commands with optional arguments Fix behavior of label_ids and add/remove_label_ids Remove unneeded aliases Do not expose projects on deployments Incorporate feedback Docs for API endpoints Expose project for environments ...
Diffstat (limited to 'spec/requests')
-rw-r--r--spec/requests/api/builds_spec.rb23
-rw-r--r--spec/requests/api/deployments_spec.rb60
-rw-r--r--spec/requests/api/environments_spec.rb1
-rw-r--r--spec/requests/api/oauth_tokens_spec.rb33
-rw-r--r--spec/requests/api/pipelines_spec.rb133
-rw-r--r--spec/requests/api/session_spec.rb11
-rw-r--r--spec/requests/git_http_spec.rb39
7 files changed, 300 insertions, 0 deletions
diff --git a/spec/requests/api/builds_spec.rb b/spec/requests/api/builds_spec.rb
index 73f44756b86..ee0b61e2ca4 100644
--- a/spec/requests/api/builds_spec.rb
+++ b/spec/requests/api/builds_spec.rb
@@ -417,4 +417,27 @@ describe API::API, api: true do
end
end
end
+
+ describe 'POST /projects/:id/builds/:build_id/play' do
+ before do
+ post api("/projects/#{project.id}/builds/#{build.id}/play", user)
+ end
+
+ context 'on an playable build' do
+ let(:build) { create(:ci_build, :manual, project: project, pipeline: pipeline) }
+
+ it 'plays the build' do
+ expect(response).to have_http_status 200
+ expect(json_response['user']['id']).to eq(user.id)
+ expect(json_response['id']).to eq(build.id)
+ end
+ end
+
+ context 'on a non-playable build' do
+ it 'returns a status code 400, Bad Request' do
+ expect(response).to have_http_status 400
+ expect(response.body).to match("Unplayable Build")
+ end
+ end
+ end
end
diff --git a/spec/requests/api/deployments_spec.rb b/spec/requests/api/deployments_spec.rb
new file mode 100644
index 00000000000..8fa8c66db6c
--- /dev/null
+++ b/spec/requests/api/deployments_spec.rb
@@ -0,0 +1,60 @@
+require 'spec_helper'
+
+describe API::API, api: true do
+ include ApiHelpers
+
+ let(:user) { create(:user) }
+ let(:non_member) { create(:user) }
+ let(:project) { deployment.environment.project }
+ let!(:deployment) { create(:deployment) }
+
+ before do
+ project.team << [user, :master]
+ end
+
+ describe 'GET /projects/:id/deployments' do
+ context 'as member of the project' do
+ it_behaves_like 'a paginated resources' do
+ let(:request) { get api("/projects/#{project.id}/deployments", user) }
+ end
+
+ it 'returns projects deployments' do
+ get api("/projects/#{project.id}/deployments", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.size).to eq(1)
+ expect(json_response.first['iid']).to eq(deployment.iid)
+ expect(json_response.first['sha']).to match /\A\h{40}\z/
+ end
+ end
+
+ context 'as non member' do
+ it 'returns a 404 status code' do
+ get api("/projects/#{project.id}/deployments", non_member)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ describe 'GET /projects/:id/deployments/:deployment_id' do
+ context 'as a member of the project' do
+ it 'returns the projects deployment' do
+ get api("/projects/#{project.id}/deployments/#{deployment.id}", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['sha']).to match /\A\h{40}\z/
+ expect(json_response['id']).to eq(deployment.id)
+ end
+ end
+
+ context 'as non member' do
+ it 'returns a 404 status code' do
+ get api("/projects/#{project.id}/deployments/#{deployment.id}", non_member)
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb
index 05e57905343..1898b07835d 100644
--- a/spec/requests/api/environments_spec.rb
+++ b/spec/requests/api/environments_spec.rb
@@ -26,6 +26,7 @@ describe API::API, api: true do
expect(json_response.size).to eq(1)
expect(json_response.first['name']).to eq(environment.name)
expect(json_response.first['external_url']).to eq(environment.external_url)
+ expect(json_response.first['project']['id']).to eq(project.id)
end
end
diff --git a/spec/requests/api/oauth_tokens_spec.rb b/spec/requests/api/oauth_tokens_spec.rb
new file mode 100644
index 00000000000..7e2cc50e591
--- /dev/null
+++ b/spec/requests/api/oauth_tokens_spec.rb
@@ -0,0 +1,33 @@
+require 'spec_helper'
+
+describe API::API, api: true do
+ include ApiHelpers
+
+ context 'Resource Owner Password Credentials' do
+ def request_oauth_token(user)
+ post '/oauth/token', username: user.username, password: user.password, grant_type: 'password'
+ end
+
+ context 'when user has 2FA enabled' do
+ it 'does not create an access token' do
+ user = create(:user, :two_factor)
+
+ request_oauth_token(user)
+
+ expect(response).to have_http_status(401)
+ expect(json_response['error']).to eq('invalid_grant')
+ end
+ end
+
+ context 'when user does not have 2FA enabled' do
+ it 'creates an access token' do
+ user = create(:user)
+
+ request_oauth_token(user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['access_token']).not_to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
new file mode 100644
index 00000000000..7011bdc9ec0
--- /dev/null
+++ b/spec/requests/api/pipelines_spec.rb
@@ -0,0 +1,133 @@
+require 'spec_helper'
+
+describe API::API, api: true do
+ include ApiHelpers
+
+ let(:user) { create(:user) }
+ let(:non_member) { create(:user) }
+ let(:project) { create(:project, creator_id: user.id) }
+
+ let!(:pipeline) do
+ create(:ci_empty_pipeline, project: project, sha: project.commit.id,
+ ref: project.default_branch)
+ end
+
+ before { project.team << [user, :master] }
+
+ describe 'GET /projects/:id/pipelines ' do
+ it_behaves_like 'a paginated resources' do
+ let(:request) { get api("/projects/#{project.id}/pipelines", user) }
+ end
+
+ context 'authorized user' do
+ it 'returns project pipelines' do
+ get api("/projects/#{project.id}/pipelines", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to be_an Array
+ expect(json_response.first['sha']).to match /\A\h{40}\z/
+ expect(json_response.first['id']).to eq pipeline.id
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'does not return project pipelines' do
+ get api("/projects/#{project.id}/pipelines", non_member)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq '404 Project Not Found'
+ expect(json_response).not_to be_an Array
+ end
+ end
+ end
+
+ describe 'GET /projects/:id/pipelines/:pipeline_id' do
+ context 'authorized user' do
+ it 'returns project pipelines' do
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['sha']).to match /\A\h{40}\z/
+ end
+
+ it 'returns 404 when it does not exist' do
+ get api("/projects/#{project.id}/pipelines/123456", user)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq '404 Not found'
+ expect(json_response['id']).to be nil
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'should not return a project pipeline' do
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}", non_member)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq '404 Project Not Found'
+ expect(json_response['id']).to be nil
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/pipelines/:pipeline_id/retry' do
+ context 'authorized user' do
+ let!(:pipeline) do
+ create(:ci_pipeline, project: project, sha: project.commit.id,
+ ref: project.default_branch)
+ end
+
+ let!(:build) { create(:ci_build, :failed, pipeline: pipeline) }
+
+ it 'retries failed builds' do
+ expect do
+ post api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", user)
+ end.to change { pipeline.builds.count }.from(1).to(2)
+
+ expect(response).to have_http_status(201)
+ expect(build.reload.retried?).to be true
+ end
+ end
+
+ context 'unauthorized user' do
+ it 'should not return a project pipeline' do
+ post api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", non_member)
+
+ expect(response).to have_http_status(404)
+ expect(json_response['message']).to eq '404 Project Not Found'
+ expect(json_response['id']).to be nil
+ end
+ end
+ end
+
+ describe 'POST /projects/:id/pipelines/:pipeline_id/cancel' do
+ let!(:pipeline) do
+ create(:ci_empty_pipeline, project: project, sha: project.commit.id,
+ ref: project.default_branch)
+ end
+
+ let!(:build) { create(:ci_build, :running, pipeline: pipeline) }
+
+ context 'authorized user' do
+ it 'retries failed builds' do
+ post api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", user)
+
+ expect(response).to have_http_status(200)
+ expect(json_response['status']).to eq('canceled')
+ end
+ end
+
+ context 'user without proper access rights' do
+ let!(:reporter) { create(:user) }
+
+ before { project.team << [reporter, :reporter] }
+
+ it 'rejects the action' do
+ post api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", reporter)
+
+ expect(response).to have_http_status(403)
+ expect(pipeline.reload.status).to eq('pending')
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/session_spec.rb b/spec/requests/api/session_spec.rb
index 519e7ce12ad..acad1365ace 100644
--- a/spec/requests/api/session_spec.rb
+++ b/spec/requests/api/session_spec.rb
@@ -17,6 +17,17 @@ describe API::API, api: true do
expect(json_response['can_create_project']).to eq(user.can_create_project?)
expect(json_response['can_create_group']).to eq(user.can_create_group?)
end
+
+ context 'with 2FA enabled' do
+ it 'rejects sign in attempts' do
+ user = create(:user, :two_factor)
+
+ post api('/session'), email: user.email, password: user.password
+
+ expect(response).to have_http_status(401)
+ expect(response.body).to include('You have 2FA enabled.')
+ end
+ end
end
context 'when email has case-typo and password is valid' do
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index 8537c252b58..afaf4b7cefb 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -198,6 +198,45 @@ describe 'Git HTTP requests', lib: true do
end
end
+ context 'when user has 2FA enabled' do
+ let(:user) { create(:user, :two_factor) }
+ let(:access_token) { create(:personal_access_token, user: user) }
+
+ before do
+ project.team << [user, :master]
+ end
+
+ context 'when username and password are provided' do
+ it 'rejects the clone attempt' do
+ download("#{project.path_with_namespace}.git", user: user.username, password: user.password) do |response|
+ expect(response).to have_http_status(401)
+ expect(response.body).to include('You have 2FA enabled, please use a personal access token for Git over HTTP')
+ end
+ end
+
+ it 'rejects the push attempt' do
+ upload("#{project.path_with_namespace}.git", user: user.username, password: user.password) do |response|
+ expect(response).to have_http_status(401)
+ expect(response.body).to include('You have 2FA enabled, please use a personal access token for Git over HTTP')
+ end
+ end
+ end
+
+ context 'when username and personal access token are provided' do
+ it 'allows clones' do
+ download("#{project.path_with_namespace}.git", user: user.username, password: access_token.token) do |response|
+ expect(response).to have_http_status(200)
+ end
+ end
+
+ it 'allows pushes' do
+ upload("#{project.path_with_namespace}.git", user: user.username, password: access_token.token) do |response|
+ expect(response).to have_http_status(200)
+ end
+ end
+ end
+ end
+
context "when blank password attempts follow a valid login" do
def attempt_login(include_password)
password = include_password ? user.password : ""