summaryrefslogtreecommitdiff
path: root/spec/requests/api
diff options
context:
space:
mode:
Diffstat (limited to 'spec/requests/api')
-rw-r--r--spec/requests/api/avatar_spec.rb106
-rw-r--r--spec/requests/api/boards_spec.rb1
-rw-r--r--spec/requests/api/branches_spec.rb29
-rw-r--r--spec/requests/api/commits_spec.rb43
-rw-r--r--spec/requests/api/events_spec.rb4
-rw-r--r--spec/requests/api/files_spec.rb85
-rw-r--r--spec/requests/api/graphql/project/merge_request_spec.rb70
-rw-r--r--spec/requests/api/graphql/project_query_spec.rb44
-rw-r--r--spec/requests/api/groups_spec.rb49
-rw-r--r--spec/requests/api/internal_spec.rb18
-rw-r--r--spec/requests/api/issues_spec.rb12
-rw-r--r--spec/requests/api/jobs_spec.rb12
-rw-r--r--spec/requests/api/merge_requests_spec.rb27
-rw-r--r--spec/requests/api/pipelines_spec.rb60
-rw-r--r--spec/requests/api/project_import_spec.rb2
-rw-r--r--spec/requests/api/project_snippets_spec.rb2
-rw-r--r--spec/requests/api/projects_spec.rb36
-rw-r--r--spec/requests/api/repositories_spec.rb34
-rw-r--r--spec/requests/api/runner_spec.rb39
-rw-r--r--spec/requests/api/search_spec.rb24
-rw-r--r--spec/requests/api/settings_spec.rb4
-rw-r--r--spec/requests/api/snippets_spec.rb5
-rw-r--r--spec/requests/api/tags_spec.rb5
-rw-r--r--spec/requests/api/users_spec.rb75
24 files changed, 708 insertions, 78 deletions
diff --git a/spec/requests/api/avatar_spec.rb b/spec/requests/api/avatar_spec.rb
new file mode 100644
index 00000000000..26e0435a6d5
--- /dev/null
+++ b/spec/requests/api/avatar_spec.rb
@@ -0,0 +1,106 @@
+require 'spec_helper'
+
+describe API::Avatar do
+ let(:gravatar_service) { double('GravatarService') }
+
+ describe 'GET /avatar' do
+ context 'avatar uploaded to GitLab' do
+ context 'user with matching public email address' do
+ let(:user) { create(:user, :with_avatar, email: 'public@example.com', public_email: 'public@example.com') }
+
+ before do
+ user
+ end
+
+ it 'returns the avatar url' do
+ get api('/avatar'), { email: 'public@example.com' }
+
+ expect(response.status).to eq 200
+ expect(json_response['avatar_url']).to eql("#{::Settings.gitlab.base_url}#{user.avatar.local_url}")
+ end
+ end
+
+ context 'no user with matching public email address' do
+ before do
+ expect(GravatarService).to receive(:new).and_return(gravatar_service)
+ expect(gravatar_service).to(
+ receive(:execute)
+ .with('private@example.com', nil, 2, { username: nil })
+ .and_return('https://gravatar'))
+ end
+
+ it 'returns the avatar url from Gravatar' do
+ get api('/avatar'), { email: 'private@example.com' }
+
+ expect(response.status).to eq 200
+ expect(json_response['avatar_url']).to eq('https://gravatar')
+ end
+ end
+ end
+
+ context 'avatar uploaded to Gravatar' do
+ context 'user with matching public email address' do
+ let(:user) { create(:user, email: 'public@example.com', public_email: 'public@example.com') }
+
+ before do
+ user
+
+ expect(GravatarService).to receive(:new).and_return(gravatar_service)
+ expect(gravatar_service).to(
+ receive(:execute)
+ .with('public@example.com', nil, 2, { username: user.username })
+ .and_return('https://gravatar'))
+ end
+
+ it 'returns the avatar url from Gravatar' do
+ get api('/avatar'), { email: 'public@example.com' }
+
+ expect(response.status).to eq 200
+ expect(json_response['avatar_url']).to eq('https://gravatar')
+ end
+ end
+
+ context 'no user with matching public email address' do
+ before do
+ expect(GravatarService).to receive(:new).and_return(gravatar_service)
+ expect(gravatar_service).to(
+ receive(:execute)
+ .with('private@example.com', nil, 2, { username: nil })
+ .and_return('https://gravatar'))
+ end
+
+ it 'returns the avatar url from Gravatar' do
+ get api('/avatar'), { email: 'private@example.com' }
+
+ expect(response.status).to eq 200
+ expect(json_response['avatar_url']).to eq('https://gravatar')
+ end
+ end
+
+ context 'public visibility level restricted' do
+ let(:user) { create(:user, :with_avatar, email: 'public@example.com', public_email: 'public@example.com') }
+
+ before do
+ user
+
+ stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
+ end
+
+ context 'when authenticated' do
+ it 'returns the avatar url' do
+ get api('/avatar', user), { email: 'public@example.com' }
+
+ expect(response.status).to eq 200
+ expect(json_response['avatar_url']).to eql("#{::Settings.gitlab.base_url}#{user.avatar.local_url}")
+ end
+ end
+
+ context 'when unauthenticated' do
+ it_behaves_like '403 response' do
+ let(:request) { get api('/avatar'), { email: 'public@example.com' } }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/boards_spec.rb b/spec/requests/api/boards_spec.rb
index 92b614b087e..7710f19ce4e 100644
--- a/spec/requests/api/boards_spec.rb
+++ b/spec/requests/api/boards_spec.rb
@@ -2,7 +2,6 @@ require 'spec_helper'
describe API::Boards do
set(:user) { create(:user) }
- set(:user2) { create(:user) }
set(:non_member) { create(:user) }
set(:guest) { create(:user) }
set(:admin) { create(:user, :admin) }
diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb
index 64f51d9843d..9bb6ed62393 100644
--- a/spec/requests/api/branches_spec.rb
+++ b/spec/requests/api/branches_spec.rb
@@ -155,6 +155,12 @@ describe API::Branches do
end
it_behaves_like 'repository branch'
+
+ it 'returns that the current user cannot push' do
+ get api(route, current_user)
+
+ expect(json_response['can_push']).to eq(false)
+ end
end
context 'when unauthenticated', 'and project is private' do
@@ -169,6 +175,12 @@ describe API::Branches do
it_behaves_like 'repository branch'
+ it 'returns that the current user can push' do
+ get api(route, current_user)
+
+ expect(json_response['can_push']).to eq(true)
+ end
+
context 'when branch contains a dot' do
let(:branch_name) { branch_with_dot.name }
@@ -202,6 +214,23 @@ describe API::Branches do
end
end
+ context 'when authenticated', 'as a developer and branch is protected' do
+ let(:current_user) { create(:user) }
+ let!(:protected_branch) { create(:protected_branch, project: project, name: branch_name) }
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ it_behaves_like 'repository branch'
+
+ it 'returns that the current user cannot push' do
+ get api(route, current_user)
+
+ expect(json_response['can_push']).to eq(false)
+ end
+ end
+
context 'when authenticated', 'as a guest' do
it_behaves_like '403 response' do
let(:request) { get api(route, guest) }
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 8ad19e3f0f5..e73d1a252f5 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -18,14 +18,14 @@ describe API::Commits do
describe 'GET /projects/:id/repository/commits' do
let(:route) { "/projects/#{project_id}/repository/commits" }
- shared_examples_for 'project commits' do
+ shared_examples_for 'project commits' do |schema: 'public_api/v4/commits'|
it "returns project commits" do
commit = project.repository.commit
get api(route, current_user)
expect(response).to have_gitlab_http_status(200)
- expect(response).to match_response_schema('public_api/v4/commits')
+ expect(response).to match_response_schema(schema)
expect(json_response.first['id']).to eq(commit.id)
expect(json_response.first['committer_name']).to eq(commit.committer_name)
expect(json_response.first['committer_email']).to eq(commit.committer_email)
@@ -161,6 +161,23 @@ describe API::Commits do
end
end
+ context 'with_stats optional parameter' do
+ let(:project) { create(:project, :public, :repository) }
+
+ it_behaves_like 'project commits', schema: 'public_api/v4/commits_with_stats' do
+ let(:route) { "/projects/#{project_id}/repository/commits?with_stats=true" }
+
+ it 'include commits details' do
+ commit = project.repository.commit
+ get api(route, current_user)
+
+ expect(json_response.first['stats']['additions']).to eq(commit.stats.additions)
+ expect(json_response.first['stats']['deletions']).to eq(commit.stats.deletions)
+ expect(json_response.first['stats']['total']).to eq(commit.stats.total)
+ end
+ end
+ end
+
context 'with pagination params' do
let(:page) { 1 }
let(:per_page) { 5 }
@@ -247,6 +264,19 @@ describe API::Commits do
]
}
end
+ let!(:valid_utf8_c_params) do
+ {
+ branch: 'master',
+ commit_message: message,
+ actions: [
+ {
+ action: 'create',
+ file_path: 'foo/bar/baz.txt',
+ content: 'puts 🦊'
+ }
+ ]
+ }
+ end
it 'a new file in project repo' do
post api(url, user), valid_c_params
@@ -257,6 +287,15 @@ describe API::Commits do
expect(json_response['committer_email']).to eq(user.email)
end
+ it 'a new file with utf8 chars in project repo' do
+ post api(url, user), valid_utf8_c_params
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response['title']).to eq(message)
+ expect(json_response['committer_name']).to eq(user.name)
+ expect(json_response['committer_email']).to eq(user.email)
+ end
+
it 'returns a 400 bad request if file exists' do
post api(url, user), invalid_c_params
diff --git a/spec/requests/api/events_spec.rb b/spec/requests/api/events_spec.rb
index 962c845f36d..e6a61fdcf39 100644
--- a/spec/requests/api/events_spec.rb
+++ b/spec/requests/api/events_spec.rb
@@ -176,7 +176,7 @@ describe API::Events do
end
it 'avoids N+1 queries' do
- control_count = ActiveRecord::QueryRecorder.new do
+ control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
get api("/projects/#{private_project.id}/events", user), target_type: :merge_request
end.count
@@ -184,7 +184,7 @@ describe API::Events do
expect do
get api("/projects/#{private_project.id}/events", user), target_type: :merge_request
- end.not_to exceed_query_limit(control_count)
+ end.not_to exceed_all_query_limit(control_count)
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index d8fdfd6dee1..4bc5d3ee899 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -21,6 +21,89 @@ describe API::Files do
"/projects/#{project.id}/repository/files/#{file_path}"
end
+ describe "HEAD /projects/:id/repository/files/:file_path" do
+ shared_examples_for 'repository files' do
+ it 'returns file attributes in headers' do
+ head api(route(file_path), current_user), params
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response.headers['X-Gitlab-File-Path']).to eq(CGI.unescape(file_path))
+ expect(response.headers['X-Gitlab-File-Name']).to eq('popen.rb')
+ expect(response.headers['X-Gitlab-Last-Commit-Id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
+ expect(response.headers['X-Gitlab-Content-Sha256']).to eq('c440cd09bae50c4632cc58638ad33c6aa375b6109d811e76a9cc3a613c1e8887')
+ end
+
+ it 'returns file by commit sha' do
+ # This file is deleted on HEAD
+ file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee"
+ params[:ref] = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9"
+
+ head api(route(file_path), current_user), params
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response.headers['X-Gitlab-File-Name']).to eq('commit.js.coffee')
+ expect(response.headers['X-Gitlab-Content-Sha256']).to eq('08785f04375b47f81f46e68cc125d5ef368aa20576ddb53f91f4d83f1d04b929')
+ end
+
+ context 'when mandatory params are not given' do
+ it "responds with a 400 status" do
+ head api(route("any%2Ffile"), current_user)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+ end
+
+ context 'when file_path does not exist' do
+ it "responds with a 404 status" do
+ params[:ref] = 'master'
+
+ head api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+
+ context 'when file_path does not exist' do
+ include_context 'disabled repository'
+
+ it "responds with a 403 status" do
+ head api(route(file_path), current_user), params
+
+ expect(response).to have_gitlab_http_status(403)
+ end
+ end
+ end
+
+ context 'when unauthenticated', 'and project is public' do
+ it_behaves_like 'repository files' do
+ let(:project) { create(:project, :public, :repository) }
+ let(:current_user) { nil }
+ end
+ end
+
+ context 'when unauthenticated', 'and project is private' do
+ it "responds with a 404 status" do
+ current_user = nil
+
+ head api(route(file_path), current_user), params
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+ end
+
+ context 'when authenticated', 'as a developer' do
+ it_behaves_like 'repository files' do
+ let(:current_user) { user }
+ end
+ end
+
+ context 'when authenticated', 'as a guest' do
+ it_behaves_like '403 response' do
+ let(:request) { head api(route(file_path), guest), params }
+ end
+ end
+ end
+
describe "GET /projects/:id/repository/files/:file_path" do
shared_examples_for 'repository files' do
it 'returns file attributes as json' do
@@ -30,6 +113,7 @@ describe API::Files do
expect(json_response['file_path']).to eq(CGI.unescape(file_path))
expect(json_response['file_name']).to eq('popen.rb')
expect(json_response['last_commit_id']).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
+ expect(json_response['content_sha256']).to eq('c440cd09bae50c4632cc58638ad33c6aa375b6109d811e76a9cc3a613c1e8887')
expect(Base64.decode64(json_response['content']).lines.first).to eq("require 'fileutils'\n")
end
@@ -51,6 +135,7 @@ describe API::Files do
expect(response).to have_gitlab_http_status(200)
expect(json_response['file_name']).to eq('commit.js.coffee')
+ expect(json_response['content_sha256']).to eq('08785f04375b47f81f46e68cc125d5ef368aa20576ddb53f91f4d83f1d04b929')
expect(Base64.decode64(json_response['content']).lines.first).to eq("class Commit\n")
end
diff --git a/spec/requests/api/graphql/project/merge_request_spec.rb b/spec/requests/api/graphql/project/merge_request_spec.rb
new file mode 100644
index 00000000000..ad57c43bc87
--- /dev/null
+++ b/spec/requests/api/graphql/project/merge_request_spec.rb
@@ -0,0 +1,70 @@
+require 'spec_helper'
+
+describe 'getting merge request information nested in a project' do
+ include GraphqlHelpers
+
+ let(:project) { create(:project, :repository, :public) }
+ let(:current_user) { create(:user) }
+ let(:merge_request_graphql_data) { graphql_data['project']['mergeRequest'] }
+ let!(:merge_request) { create(:merge_request, source_project: project) }
+
+ let(:query) do
+ graphql_query_for(
+ 'project',
+ { 'fullPath' => project.full_path },
+ query_graphql_field('mergeRequest', iid: merge_request.iid)
+ )
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+ end
+
+ it 'contains merge request information' do
+ post_graphql(query, current_user: current_user)
+
+ expect(merge_request_graphql_data).not_to be_nil
+ end
+
+ # This is a field coming from the `MergeRequestPresenter`
+ it 'includes a web_url' do
+ post_graphql(query, current_user: current_user)
+
+ expect(merge_request_graphql_data['webUrl']).to be_present
+ end
+
+ context 'permissions on the merge request' do
+ it 'includes the permissions for the current user on a public project' do
+ expected_permissions = {
+ 'readMergeRequest' => true,
+ 'adminMergeRequest' => false,
+ 'createNote' => true,
+ 'pushToSourceBranch' => false,
+ 'removeSourceBranch' => false,
+ 'cherryPickOnCurrentMergeRequest' => false,
+ 'revertOnCurrentMergeRequest' => false,
+ 'updateMergeRequest' => false
+ }
+ post_graphql(query, current_user: current_user)
+
+ permission_data = merge_request_graphql_data['userPermissions']
+
+ expect(permission_data).to be_present
+ expect(permission_data).to eq(expected_permissions)
+ end
+ end
+
+ context 'when the user does not have access to the merge request' do
+ let(:project) { create(:project, :public, :repository) }
+
+ it 'returns nil' do
+ project.project_feature.update!(merge_requests_access_level: ProjectFeature::PRIVATE)
+
+ post_graphql(query)
+
+ expect(merge_request_graphql_data).to be_nil
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/project_query_spec.rb b/spec/requests/api/graphql/project_query_spec.rb
new file mode 100644
index 00000000000..a2b3dc5d121
--- /dev/null
+++ b/spec/requests/api/graphql/project_query_spec.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+describe 'getting project information' do
+ include GraphqlHelpers
+
+ let(:project) { create(:project, :repository) }
+ let(:current_user) { create(:user) }
+
+ let(:query) do
+ graphql_query_for('project', 'fullPath' => project.full_path)
+ end
+
+ context 'when the user has access to the project' do
+ before do
+ project.add_developer(current_user)
+ end
+
+ it 'includes the project' do
+ post_graphql(query, current_user: current_user)
+
+ expect(graphql_data['project']).not_to be_nil
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+ end
+ end
+
+ context 'when the user does not have access to the project' do
+ it 'returns an empty field' do
+ post_graphql(query, current_user: current_user)
+
+ expect(graphql_data['project']).to be_nil
+ end
+
+ it_behaves_like 'a working graphql query' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index 7d923932309..da23fdd7dca 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -138,10 +138,15 @@ describe API::Groups do
context "when using sorting" do
let(:group3) { create(:group, name: "a#{group1.name}", path: "z#{group1.path}") }
+ let(:group4) { create(:group, name: "same-name", path: "y#{group1.path}") }
+ let(:group5) { create(:group, name: "same-name") }
let(:response_groups) { json_response.map { |group| group['name'] } }
+ let(:response_groups_ids) { json_response.map { |group| group['id'] } }
before do
group3.add_owner(user1)
+ group4.add_owner(user1)
+ group5.add_owner(user1)
end
it "sorts by name ascending by default" do
@@ -150,7 +155,7 @@ describe API::Groups do
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
- expect(response_groups).to eq([group3.name, group1.name])
+ expect(response_groups).to eq(Group.visible_to_user(user1).order(:name).pluck(:name))
end
it "sorts in descending order when passed" do
@@ -159,16 +164,52 @@ describe API::Groups do
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
- expect(response_groups).to eq([group1.name, group3.name])
+ expect(response_groups).to eq(Group.visible_to_user(user1).order(name: :desc).pluck(:name))
end
- it "sorts by the order_by param" do
+ it "sorts by path in order_by param" do
get api("/groups", user1), order_by: "path"
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
- expect(response_groups).to eq([group1.name, group3.name])
+ expect(response_groups).to eq(Group.visible_to_user(user1).order(:path).pluck(:name))
+ end
+
+ it "sorts by id in the order_by param" do
+ get api("/groups", user1), order_by: "id"
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(response_groups).to eq(Group.visible_to_user(user1).order(:id).pluck(:name))
+ end
+
+ it "sorts also by descending id with pagination fix" do
+ get api("/groups", user1), order_by: "id", sort: "desc"
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(response_groups).to eq(Group.visible_to_user(user1).order(id: :desc).pluck(:name))
+ end
+
+ it "sorts identical keys by id for good pagination" do
+ get api("/groups", user1), search: "same-name", order_by: "name"
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(response_groups_ids).to eq(Group.select { |group| group['name'] == 'same-name' }.map { |group| group['id'] }.sort)
+ end
+
+ it "sorts descending identical keys by id for good pagination" do
+ get api("/groups", user1), search: "same-name", order_by: "name", sort: "desc"
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(response_groups_ids).to eq(Group.select { |group| group['name'] == 'same-name' }.map { |group| group['id'] }.sort)
end
end
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb
index 5dc3ddd4b36..a56b913198c 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal_spec.rb
@@ -522,7 +522,6 @@ describe API::Internal do
context 'the project path was changed' do
let(:project) { create(:project, :repository, :legacy_storage) }
- let!(:old_path_to_repo) { project.repository.path_to_repo }
let!(:repository) { project.repository }
before do
@@ -835,8 +834,7 @@ describe API::Internal do
end
def push(key, project, protocol = 'ssh', env: nil)
- post(
- api("/internal/allowed"),
+ params = {
changes: 'd14d6c0abdd253381df51a723d58691b2ee1ab08 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/master',
key_id: key.id,
project: project.full_path,
@@ -845,7 +843,19 @@ describe API::Internal do
secret_token: secret_token,
protocol: protocol,
env: env
- )
+ }
+
+ if Gitlab.rails5?
+ post(
+ api("/internal/allowed"),
+ params: params
+ )
+ else
+ post(
+ api("/internal/allowed"),
+ params
+ )
+ end
end
def archive(key, project)
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index 4181f4ebbbe..95eff029f98 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -630,15 +630,17 @@ describe API::Issues do
end
it 'avoids N+1 queries' do
- control_count = ActiveRecord::QueryRecorder.new do
+ get api("/projects/#{project.id}/issues", user)
+
+ control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
get api("/projects/#{project.id}/issues", user)
end.count
- create(:issue, author: user, project: project)
+ create_list(:issue, 3, project: project)
expect do
get api("/projects/#{project.id}/issues", user)
- end.not_to exceed_query_limit(control_count)
+ end.not_to exceed_all_query_limit(control_count)
end
it 'returns 404 when project does not exist' do
@@ -1677,7 +1679,7 @@ describe API::Issues do
let!(:user_agent_detail) { create(:user_agent_detail, subject: issue) }
context 'when unauthenticated' do
- it "returns unautorized" do
+ it "returns unauthorized" do
get api("/projects/#{project.id}/issues/#{issue.iid}/user_agent_detail")
expect(response).to have_gitlab_http_status(401)
@@ -1693,7 +1695,7 @@ describe API::Issues do
expect(json_response['akismet_submitted']).to eq(user_agent_detail.submitted)
end
- it "returns unautorized for non-admin users" do
+ it "returns unauthorized for non-admin users" do
get api("/projects/#{project.id}/issues/#{issue.iid}/user_agent_detail", user)
expect(response).to have_gitlab_http_status(403)
diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb
index 45082e644ca..50d6f4b4d99 100644
--- a/spec/requests/api/jobs_spec.rb
+++ b/spec/requests/api/jobs_spec.rb
@@ -177,6 +177,18 @@ describe API::Jobs do
json_response.each { |job| expect(job['pipeline']['id']).to eq(pipeline.id) }
end
end
+
+ it 'avoids N+1 queries' do
+ control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), query
+ end.count
+
+ 3.times { create(:ci_build, :artifacts, pipeline: pipeline) }
+
+ expect do
+ get api("/projects/#{project.id}/pipelines/#{pipeline.id}/jobs", api_user), query
+ end.not_to exceed_all_query_limit(control_count)
+ end
end
context 'unauthorized user' do
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 605761867bf..eba39bb6ccc 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -14,6 +14,7 @@ describe API::MergeRequests do
let!(:merge_request) { create(:merge_request, :simple, milestone: milestone1, author: user, assignee: user, source_project: project, target_project: project, title: "Test", created_at: base_time) }
let!(:merge_request_closed) { create(:merge_request, state: "closed", milestone: milestone1, author: user, assignee: user, source_project: project, target_project: project, title: "Closed test", created_at: base_time + 1.second) }
let!(:merge_request_merged) { create(:merge_request, state: "merged", author: user, assignee: user, source_project: project, target_project: project, title: "Merged test", created_at: base_time + 2.seconds, merge_commit_sha: '9999999999999999999999999999999999999999') }
+ let!(:merge_request_locked) { create(:merge_request, state: "locked", milestone: milestone1, author: user, assignee: user, source_project: project, target_project: project, title: "Locked test", created_at: base_time + 1.second) }
let!(:note) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") }
let!(:note2) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "another comment on a MR") }
let!(:label) do
@@ -85,7 +86,7 @@ describe API::MergeRequests do
get api('/merge_requests', user), scope: :all
- expect_response_contain_exactly(merge_request2, merge_request_merged, merge_request_closed, merge_request)
+ expect_response_contain_exactly(merge_request2, merge_request_merged, merge_request_closed, merge_request, merge_request_locked)
expect(json_response.map { |mr| mr['id'] }).not_to include(merge_request3.id)
end
@@ -158,7 +159,7 @@ describe API::MergeRequests do
it 'returns merge requests with the given source branch' do
get api('/merge_requests', user), source_branch: merge_request_closed.source_branch, state: 'all'
- expect_response_contain_exactly(merge_request_closed, merge_request_merged)
+ expect_response_contain_exactly(merge_request_closed, merge_request_merged, merge_request_locked)
end
end
@@ -166,7 +167,7 @@ describe API::MergeRequests do
it 'returns merge requests with the given target branch' do
get api('/merge_requests', user), target_branch: merge_request_closed.target_branch, state: 'all'
- expect_response_contain_exactly(merge_request_closed, merge_request_merged)
+ expect_response_contain_exactly(merge_request_closed, merge_request_merged, merge_request_locked)
end
end
@@ -219,6 +220,14 @@ describe API::MergeRequests do
expect_response_ordered_exactly(merge_request)
end
end
+
+ context 'state param' do
+ it 'returns merge requests with the given state' do
+ get api('/merge_requests', user), state: 'locked'
+
+ expect_response_contain_exactly(merge_request_locked)
+ end
+ end
end
end
@@ -386,12 +395,13 @@ describe API::MergeRequests do
source_project: forked_project,
target_project: project,
source_branch: 'fixes',
- allow_maintainer_to_push: true)
+ allow_collaboration: true)
end
- it 'includes the `allow_maintainer_to_push` field' do
+ it 'includes the `allow_collaboration` field' do
get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user)
+ expect(json_response['allow_collaboration']).to be_truthy
expect(json_response['allow_maintainer_to_push']).to be_truthy
end
end
@@ -654,11 +664,12 @@ describe API::MergeRequests do
expect(response).to have_gitlab_http_status(400)
end
- it 'allows setting `allow_maintainer_to_push`' do
+ it 'allows setting `allow_collaboration`' do
post api("/projects/#{forked_project.id}/merge_requests", user2),
- title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master",
- author: user2, target_project_id: project.id, allow_maintainer_to_push: true
+ title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master",
+ author: user2, target_project_id: project.id, allow_collaboration: true
expect(response).to have_gitlab_http_status(201)
+ expect(json_response['allow_collaboration']).to be_truthy
expect(json_response['allow_maintainer_to_push']).to be_truthy
end
diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/pipelines_spec.rb
index 0736329f9fd..78ea77cb3bb 100644
--- a/spec/requests/api/pipelines_spec.rb
+++ b/spec/requests/api/pipelines_spec.rb
@@ -285,6 +285,15 @@ describe API::Pipelines do
end
describe 'POST /projects/:id/pipeline ' do
+ def expect_variables(variables, expected_variables)
+ variables.each_with_index do |variable, index|
+ expected_variable = expected_variables[index]
+
+ expect(variable.key).to eq(expected_variable['key'])
+ expect(variable.value).to eq(expected_variable['value'])
+ end
+ end
+
context 'authorized user' do
context 'with gitlab-ci.yml' do
before do
@@ -294,13 +303,62 @@ describe API::Pipelines do
it 'creates and returns a new pipeline' do
expect do
post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
- end.to change { Ci::Pipeline.count }.by(1)
+ end.to change { project.pipelines.count }.by(1)
expect(response).to have_gitlab_http_status(201)
expect(json_response).to be_a Hash
expect(json_response['sha']).to eq project.commit.id
end
+ context 'variables given' do
+ let(:variables) { [{ 'key' => 'UPLOAD_TO_S3', 'value' => 'true' }] }
+
+ it 'creates and returns a new pipeline using the given variables' do
+ expect do
+ post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch, variables: variables
+ end.to change { project.pipelines.count }.by(1)
+ expect_variables(project.pipelines.last.variables, variables)
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response).to be_a Hash
+ expect(json_response['sha']).to eq project.commit.id
+ expect(json_response).not_to have_key('variables')
+ end
+ end
+
+ describe 'using variables conditions' do
+ let(:variables) { [{ 'key' => 'STAGING', 'value' => 'true' }] }
+
+ before do
+ config = YAML.dump(test: { script: 'test', only: { variables: ['$STAGING'] } })
+ stub_ci_pipeline_yaml_file(config)
+ end
+
+ it 'creates and returns a new pipeline using the given variables' do
+ expect do
+ post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch, variables: variables
+ end.to change { project.pipelines.count }.by(1)
+ expect_variables(project.pipelines.last.variables, variables)
+
+ expect(response).to have_gitlab_http_status(201)
+ expect(json_response).to be_a Hash
+ expect(json_response['sha']).to eq project.commit.id
+ expect(json_response).not_to have_key('variables')
+ end
+
+ context 'condition unmatch' do
+ let(:variables) { [{ 'key' => 'STAGING', 'value' => 'false' }] }
+
+ it "doesn't create a job" do
+ expect do
+ post api("/projects/#{project.id}/pipeline", user), ref: project.default_branch
+ end.not_to change { project.pipelines.count }
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+ end
+ end
+
it 'fails when using an invalid ref' do
post api("/projects/#{project.id}/pipeline", user), ref: 'invalid_ref'
diff --git a/spec/requests/api/project_import_spec.rb b/spec/requests/api/project_import_spec.rb
index f8c64f063af..97dffdc9233 100644
--- a/spec/requests/api/project_import_spec.rb
+++ b/spec/requests/api/project_import_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
describe API::ProjectImport do
let(:export_path) { "#{Dir.tmpdir}/project_export_spec" }
let(:user) { create(:user) }
- let(:file) { File.join(Rails.root, 'spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') }
+ let(:file) { File.join('spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') }
let(:namespace) { create(:group) }
before do
allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb
index 4a2289ca137..a3b5e8c6223 100644
--- a/spec/requests/api/project_snippets_spec.rb
+++ b/spec/requests/api/project_snippets_spec.rb
@@ -25,7 +25,7 @@ describe API::ProjectSnippets do
expect(response).to have_gitlab_http_status(404)
end
- it "returns unautorized for non-admin users" do
+ it "returns unauthorized for non-admin users" do
get api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/user_agent_detail", user)
expect(response).to have_gitlab_http_status(403)
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 9b7c3205c1f..abf9ad738bd 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -518,7 +518,7 @@ describe API::Projects do
end
it 'uploads avatar for project a project' do
- project = attributes_for(:project, avatar: fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif'))
+ project = attributes_for(:project, avatar: fixture_file_upload('spec/fixtures/banana_sample.gif', 'image/gif'))
post api('/projects', user), project
@@ -777,7 +777,7 @@ describe API::Projects do
end
it "uploads the file and returns its info" do
- post api("/projects/#{project.id}/uploads", user), file: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")
+ post api("/projects/#{project.id}/uploads", user), file: fixture_file_upload("spec/fixtures/dk.png", "image/png")
expect(response).to have_gitlab_http_status(201)
expect(json_response['alt']).to eq("dk")
@@ -1990,6 +1990,38 @@ describe API::Projects do
end
end
+ describe 'PUT /projects/:id/transfer' do
+ context 'when authenticated as owner' do
+ let(:group) { create :group }
+
+ it 'transfers the project to the new namespace' do
+ group.add_owner(user)
+
+ put api("/projects/#{project.id}/transfer", user), namespace: group.id
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'fails when transferring to a non owned namespace' do
+ put api("/projects/#{project.id}/transfer", user), namespace: group.id
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+
+ it 'fails when transferring to an unknown namespace' do
+ put api("/projects/#{project.id}/transfer", user), namespace: 'unknown'
+
+ expect(response).to have_gitlab_http_status(404)
+ end
+
+ it 'fails on missing namespace' do
+ put api("/projects/#{project.id}/transfer", user)
+
+ expect(response).to have_gitlab_http_status(400)
+ end
+ end
+ end
+
it_behaves_like 'custom attributes endpoints', 'projects' do
let(:attributable) { project }
let(:other_attributable) { project2 }
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index 9e6d69e3874..28f8564ae92 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -220,11 +220,10 @@ describe API::Repositories do
expect(response).to have_gitlab_http_status(200)
- repo_name = project.repository.name.gsub("\.git", "")
type, params = workhorse_send_data
expect(type).to eq('git-archive')
- expect(params['ArchivePath']).to match(/#{repo_name}\-[^\.]+\.tar.gz/)
+ expect(params['ArchivePath']).to match(/#{project.path}\-[^\.]+\.tar.gz/)
end
it 'returns the repository archive archive.zip' do
@@ -232,11 +231,10 @@ describe API::Repositories do
expect(response).to have_gitlab_http_status(200)
- repo_name = project.repository.name.gsub("\.git", "")
type, params = workhorse_send_data
expect(type).to eq('git-archive')
- expect(params['ArchivePath']).to match(/#{repo_name}\-[^\.]+\.zip/)
+ expect(params['ArchivePath']).to match(/#{project.path}\-[^\.]+\.zip/)
end
it 'returns the repository archive archive.tar.bz2' do
@@ -244,11 +242,10 @@ describe API::Repositories do
expect(response).to have_gitlab_http_status(200)
- repo_name = project.repository.name.gsub("\.git", "")
type, params = workhorse_send_data
expect(type).to eq('git-archive')
- expect(params['ArchivePath']).to match(/#{repo_name}\-[^\.]+\.tar.bz2/)
+ expect(params['ArchivePath']).to match(/#{project.path}\-[^\.]+\.tar.bz2/)
end
context 'when sha does not exist' do
@@ -291,6 +288,9 @@ describe API::Repositories do
shared_examples_for 'repository compare' do
it "compares branches" do
+ expect(::Gitlab::Git::Compare).to receive(:new).with(anything, anything, anything, {
+ straight: false
+ }).and_call_original
get api(route, current_user), from: 'master', to: 'feature'
expect(response).to have_gitlab_http_status(200)
@@ -298,6 +298,28 @@ describe API::Repositories do
expect(json_response['diffs']).to be_present
end
+ it "compares branches with explicit merge-base mode" do
+ expect(::Gitlab::Git::Compare).to receive(:new).with(anything, anything, anything, {
+ straight: false
+ }).and_call_original
+ get api(route, current_user), from: 'master', to: 'feature', straight: false
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['commits']).to be_present
+ expect(json_response['diffs']).to be_present
+ end
+
+ it "compares branches with explicit straight mode" do
+ expect(::Gitlab::Git::Compare).to receive(:new).with(anything, anything, anything, {
+ straight: true
+ }).and_call_original
+ get api(route, current_user), from: 'master', to: 'feature', straight: true
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response['commits']).to be_present
+ expect(json_response['diffs']).to be_present
+ end
+
it "compares tags" do
get api(route, current_user), from: 'v1.0.0', to: 'v1.1.0'
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index 319ac389083..e7639599874 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -351,11 +351,13 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
context 'when valid token is provided' do
context 'when Runner is not active' do
let(:runner) { create(:ci_runner, :inactive) }
+ let(:update_value) { runner.ensure_runner_queue_value }
it 'returns 204 error' do
request_job
- expect(response).to have_gitlab_http_status 204
+ expect(response).to have_gitlab_http_status(204)
+ expect(response.header['X-GitLab-Last-Update']).to eq(update_value)
end
end
@@ -816,6 +818,18 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
expect(job.reload.trace.raw).to eq 'BUILD TRACE'
end
+
+ context 'when running state is sent' do
+ it 'updates update_at value' do
+ expect { update_job_after_time }.to change { job.reload.updated_at }
+ end
+ end
+
+ context 'when other state is sent' do
+ it "doesn't update update_at value" do
+ expect { update_job_after_time(20.minutes, state: 'success') }.not_to change { job.reload.updated_at }
+ end
+ end
end
context 'when job has been erased' do
@@ -838,6 +852,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
update_job(state: 'success', trace: 'BUILD TRACE UPDATED')
expect(response).to have_gitlab_http_status(403)
+ expect(response.header['Job-Status']).to eq 'failed'
expect(job.trace.raw).to eq 'Job failed'
expect(job).to be_failed
end
@@ -847,6 +862,12 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
new_params = params.merge(token: token)
put api("/jobs/#{job.id}"), new_params
end
+
+ def update_job_after_time(update_interval = 20.minutes, state = 'running')
+ Timecop.travel(job.updated_at + update_interval) do
+ update_job(job.token, state: state)
+ end
+ end
end
describe 'PATCH /api/v4/jobs/:id/trace' do
@@ -979,6 +1000,17 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
end
end
end
+
+ context 'when the job is canceled' do
+ before do
+ job.cancel
+ patch_the_trace
+ end
+
+ it 'receives status in header' do
+ expect(response.header['Job-Status']).to eq 'canceled'
+ end
+ end
end
context 'when Runner makes a force-patch' do
@@ -1055,8 +1087,8 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
let(:jwt_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
let(:headers) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => jwt_token } }
let(:headers_with_token) { headers.merge(API::Helpers::Runner::JOB_TOKEN_HEADER => job.token) }
- let(:file_upload) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
- let(:file_upload2) { fixture_file_upload(Rails.root + 'spec/fixtures/dk.png', 'image/gif') }
+ let(:file_upload) { fixture_file_upload('spec/fixtures/banana_sample.gif', 'image/gif') }
+ let(:file_upload2) { fixture_file_upload('spec/fixtures/dk.png', 'image/gif') }
before do
stub_artifacts_object_storage
@@ -1101,6 +1133,7 @@ describe API::Runner, :clean_gitlab_redis_shared_state do
expect(json_response['RemoteObject']).to have_key('GetURL')
expect(json_response['RemoteObject']).to have_key('StoreURL')
expect(json_response['RemoteObject']).to have_key('DeleteURL')
+ expect(json_response['RemoteObject']).to have_key('MultipartUpload')
end
end
diff --git a/spec/requests/api/search_spec.rb b/spec/requests/api/search_spec.rb
index aca4aa40027..f8e468be170 100644
--- a/spec/requests/api/search_spec.rb
+++ b/spec/requests/api/search_spec.rb
@@ -312,6 +312,30 @@ describe API::Search do
end
it_behaves_like 'response is correct', schema: 'public_api/v4/blobs', size: 2
+
+ context 'filters' do
+ it 'by filename' do
+ get api("/projects/#{repo_project.id}/search", user), scope: 'blobs', search: 'mon filename:PROCESS.md'
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.size).to eq(2)
+ expect(json_response.first['filename']).to eq('PROCESS.md')
+ end
+
+ it 'by path' do
+ get api("/projects/#{repo_project.id}/search", user), scope: 'blobs', search: 'mon path:markdown'
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.size).to eq(8)
+ end
+
+ it 'by extension' do
+ get api("/projects/#{repo_project.id}/search", user), scope: 'blobs', search: 'mon extension:md'
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.size).to eq(11)
+ end
+ end
end
end
end
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index aead8978dd4..57adc3ca7a6 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -35,7 +35,9 @@ describe API::Settings, 'Settings' do
context "custom repository storage type set in the config" do
before do
- storages = { 'custom' => 'tmp/tests/custom_repositories' }
+ # Add a possible storage to the config
+ storages = Gitlab.config.repositories.storages
+ .merge({ 'custom' => 'tmp/tests/custom_repositories' })
allow(Gitlab.config.repositories).to receive(:storages).and_return(storages)
end
diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb
index b3e253befc6..6da769cb3ed 100644
--- a/spec/requests/api/snippets_spec.rb
+++ b/spec/requests/api/snippets_spec.rb
@@ -20,6 +20,7 @@ describe API::Snippets do
private_snippet.id)
expect(json_response.last).to have_key('web_url')
expect(json_response.last).to have_key('raw_url')
+ expect(json_response.last).to have_key('visibility')
end
it 'hides private snippets from regular user' do
@@ -112,6 +113,7 @@ describe API::Snippets do
expect(json_response['title']).to eq(snippet.title)
expect(json_response['description']).to eq(snippet.description)
expect(json_response['file_name']).to eq(snippet.file_name)
+ expect(json_response['visibility']).to eq(snippet.visibility)
end
it 'returns 404 for invalid snippet id' do
@@ -142,6 +144,7 @@ describe API::Snippets do
expect(json_response['title']).to eq(params[:title])
expect(json_response['description']).to eq(params[:description])
expect(json_response['file_name']).to eq(params[:file_name])
+ expect(json_response['visibility']).to eq(params[:visibility])
end
it 'returns 400 for missing parameters' do
@@ -311,7 +314,7 @@ describe API::Snippets do
expect(json_response['akismet_submitted']).to eq(user_agent_detail.submitted)
end
- it "returns unautorized for non-admin users" do
+ it "returns unauthorized for non-admin users" do
get api("/snippets/#{snippet.id}/user_agent_detail", user)
expect(response).to have_gitlab_http_status(403)
diff --git a/spec/requests/api/tags_spec.rb b/spec/requests/api/tags_spec.rb
index e2b19ad59f9..969710d6613 100644
--- a/spec/requests/api/tags_spec.rb
+++ b/spec/requests/api/tags_spec.rb
@@ -287,7 +287,10 @@ describe API::Tags do
context 'annotated tag' do
it 'creates a new annotated tag' do
# Identity must be set in .gitconfig to create annotated tag.
- repo_path = project.repository.path_to_repo
+ repo_path = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
+ project.repository.path_to_repo
+ end
+
system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.name #{user.name}))
system(*%W(#{Gitlab.config.git.bin_path} --git-dir=#{repo_path} config user.email #{user.email}))
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 05637eb0729..a97c3f3461a 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -512,7 +512,7 @@ describe API::Users do
end
it 'updates user with avatar' do
- put api("/users/#{user.id}", admin), { avatar: fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
+ put api("/users/#{user.id}", admin), { avatar: fixture_file_upload('spec/fixtures/banana_sample.gif', 'image/gif') }
user.reload
@@ -1123,58 +1123,63 @@ describe API::Users do
describe "GET /user" do
let(:personal_access_token) { create(:personal_access_token, user: user).token }
- context 'with regular user' do
- context 'with personal access token' do
- it 'returns 403 without private token when sudo is defined' do
- get api("/user?private_token=#{personal_access_token}&sudo=123")
+ shared_examples 'get user info' do |version|
+ context 'with regular user' do
+ context 'with personal access token' do
+ it 'returns 403 without private token when sudo is defined' do
+ get api("/user?private_token=#{personal_access_token}&sudo=123", version: version)
- expect(response).to have_gitlab_http_status(403)
+ expect(response).to have_gitlab_http_status(403)
+ end
end
- end
- it 'returns current user without private token when sudo not defined' do
- get api("/user", user)
+ it 'returns current user without private token when sudo not defined' do
+ get api("/user", user, version: version)
- expect(response).to have_gitlab_http_status(200)
- expect(response).to match_response_schema('public_api/v4/user/public')
- expect(json_response['id']).to eq(user.id)
- end
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/public')
+ expect(json_response['id']).to eq(user.id)
+ end
- context "scopes" do
- let(:path) { "/user" }
- let(:api_call) { method(:api) }
+ context "scopes" do
+ let(:path) { "/user" }
+ let(:api_call) { method(:api) }
- include_examples 'allows the "read_user" scope'
+ include_examples 'allows the "read_user" scope', version
+ end
end
- end
- context 'with admin' do
- let(:admin_personal_access_token) { create(:personal_access_token, user: admin).token }
+ context 'with admin' do
+ let(:admin_personal_access_token) { create(:personal_access_token, user: admin).token }
- context 'with personal access token' do
- it 'returns 403 without private token when sudo defined' do
- get api("/user?private_token=#{admin_personal_access_token}&sudo=#{user.id}")
+ context 'with personal access token' do
+ it 'returns 403 without private token when sudo defined' do
+ get api("/user?private_token=#{admin_personal_access_token}&sudo=#{user.id}", version: version)
- expect(response).to have_gitlab_http_status(403)
- end
+ expect(response).to have_gitlab_http_status(403)
+ end
- it 'returns initial current user without private token but with is_admin when sudo not defined' do
- get api("/user?private_token=#{admin_personal_access_token}")
+ it 'returns initial current user without private token but with is_admin when sudo not defined' do
+ get api("/user?private_token=#{admin_personal_access_token}", version: version)
- expect(response).to have_gitlab_http_status(200)
- expect(response).to match_response_schema('public_api/v4/user/admin')
- expect(json_response['id']).to eq(admin.id)
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to match_response_schema('public_api/v4/user/admin')
+ expect(json_response['id']).to eq(admin.id)
+ end
end
end
- end
- context 'with unauthenticated user' do
- it "returns 401 error if user is unauthenticated" do
- get api("/user")
+ context 'with unauthenticated user' do
+ it "returns 401 error if user is unauthenticated" do
+ get api("/user", version: version)
- expect(response).to have_gitlab_http_status(401)
+ expect(response).to have_gitlab_http_status(401)
+ end
end
end
+
+ it_behaves_like 'get user info', 'v3'
+ it_behaves_like 'get user info', 'v4'
end
describe "GET /user/keys" do