diff options
Diffstat (limited to 'spec/requests/api/merge_requests_spec.rb')
-rw-r--r-- | spec/requests/api/merge_requests_spec.rb | 152 |
1 files changed, 110 insertions, 42 deletions
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index d4c05b4b198..2757c56e0fe 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -5,23 +5,19 @@ require "spec_helper" RSpec.describe API::MergeRequests do include ProjectForksHelper - let(:base_time) { Time.now } + let_it_be(:base_time) { Time.now } let_it_be(:user) { create(:user) } let_it_be(:user2) { create(:user) } let_it_be(:admin) { create(:user, :admin) } - let(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace, only_allow_merge_if_pipeline_succeeds: false) } - let(:milestone) { create(:milestone, title: '1.0.0', project: project) } - let(:milestone1) { create(:milestone, title: '0.9', project: project) } - let(:merge_request_context_commit) {create(:merge_request_context_commit, message: 'test')} - let!(:merge_request) { create(:merge_request, :simple, milestone: milestone1, author: user, assignees: [user], merge_request_context_commits: [merge_request_context_commit], source_project: project, target_project: project, source_branch: 'markdown', title: "Test", created_at: base_time) } - let!(:merge_request_closed) { create(:merge_request, state: "closed", milestone: milestone1, author: user, assignees: [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, assignees: [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, assignees: [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_it_be(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace, only_allow_merge_if_pipeline_succeeds: false) } + + let(:milestone1) { create(:milestone, title: '0.9', project: project) } + let(:milestone) { create(:milestone, title: '1.0.0', project: project) } let(:label) { create(:label, title: 'label', color: '#FFAABB', project: project) } let(:label2) { create(:label, title: 'a-test', color: '#FFFFFF', project: project) } + let(:merge_request) { create(:merge_request, :simple, author: user, assignees: [user], source_project: project, target_project: project, source_branch: 'markdown', title: "Test", created_at: base_time) } + before do project.add_reporter(user) project.add_reporter(user2) @@ -29,6 +25,16 @@ RSpec.describe API::MergeRequests do stub_licensed_features(multiple_merge_request_assignees: false) end + shared_context 'with merge requests' do + let_it_be(:milestone1) { create(:milestone, title: '0.9', project: project) } + let_it_be(:merge_request) { create(:merge_request, :simple, milestone: milestone1, author: user, assignees: [user], source_project: project, target_project: project, source_branch: 'markdown', title: "Test", created_at: base_time) } + let_it_be(:merge_request_closed) { create(:merge_request, state: "closed", milestone: milestone1, author: user, assignees: [user], source_project: project, target_project: project, title: "Closed test", created_at: base_time + 1.second) } + let_it_be(:merge_request_merged) { create(:merge_request, state: "merged", author: user, assignees: [user], source_project: project, target_project: project, title: "Merged test", created_at: base_time + 2.seconds, merge_commit_sha: '9999999999999999999999999999999999999999') } + let_it_be(:merge_request_locked) { create(:merge_request, state: "locked", milestone: milestone1, author: user, assignees: [user], source_project: project, target_project: project, title: "Locked test", created_at: base_time + 1.second) } + let_it_be(:note) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") } + let_it_be(:note2) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "another comment on a MR") } + end + shared_context 'with labels' do before do create(:label_link, label: label, target: merge_request) @@ -68,6 +74,7 @@ RSpec.describe API::MergeRequests do context 'when merge request is unchecked' do let(:check_service_class) { MergeRequests::MergeabilityCheckService } let(:mr_entity) { json_response.find { |mr| mr['id'] == merge_request.id } } + let(:merge_request) { create(:merge_request, :simple, author: user, source_project: project, title: "Test") } before do merge_request.mark_as_unchecked! @@ -426,14 +433,13 @@ RSpec.describe API::MergeRequests do end context 'NOT params' do - let(:merge_request2) do + let!(:merge_request2) do create( :merge_request, :simple, milestone: milestone, author: user, assignees: [user], - merge_request_context_commits: [merge_request_context_commit], source_project: project, target_project: project, source_branch: 'what', @@ -442,6 +448,8 @@ RSpec.describe API::MergeRequests do ) end + let!(:merge_request_context_commit) { create(:merge_request_context_commit, merge_request: merge_request2, message: 'test') } + before do create(:label_link, label: label, target: merge_request) create(:label_link, label: label2, target: merge_request2) @@ -527,6 +535,8 @@ RSpec.describe API::MergeRequests do end describe 'GET /merge_requests' do + include_context 'with merge requests' + context 'when unauthenticated' do it 'returns an array of all merge requests' do get api('/merge_requests', user), params: { scope: 'all' } @@ -563,9 +573,9 @@ RSpec.describe API::MergeRequests do end context 'when authenticated' do - let!(:project2) { create(:project, :public, namespace: user.namespace) } - let!(:merge_request2) { create(:merge_request, :simple, author: user, assignees: [user], source_project: project2, target_project: project2) } - let(:user2) { create(:user) } + let_it_be(:project2) { create(:project, :public, :repository, namespace: user.namespace) } + let_it_be(:merge_request2) { create(:merge_request, :simple, author: user, assignees: [user], source_project: project2, target_project: project2) } + let_it_be(:user2) { create(:user) } it 'returns an array of all merge requests except unauthorized ones' do get api('/merge_requests', user), params: { scope: :all } @@ -778,8 +788,8 @@ RSpec.describe API::MergeRequests do end context 'search params' do - before do - merge_request.update(title: 'Search title', description: 'Search description') + let_it_be(:merge_request) do + create(:merge_request, :simple, author: user, source_project: project, target_project: project, title: 'Search title', description: 'Search description') end it 'returns merge requests matching given search string for title' do @@ -818,6 +828,8 @@ RSpec.describe API::MergeRequests do end describe "GET /projects/:id/merge_requests" do + include_context 'with merge requests' + let(:endpoint_path) { "/projects/#{project.id}/merge_requests" } it_behaves_like 'merge requests list' @@ -845,7 +857,9 @@ RSpec.describe API::MergeRequests do end context 'a project which enforces all discussions to be resolved' do - let!(:project) { create(:project, :repository, only_allow_merge_if_all_discussions_are_resolved: true) } + let_it_be(:project) { create(:project, :repository, only_allow_merge_if_all_discussions_are_resolved: true) } + + include_context 'with merge requests' it 'avoids N+1 queries' do control = ActiveRecord::QueryRecorder.new do @@ -864,6 +878,9 @@ RSpec.describe API::MergeRequests do describe "GET /groups/:id/merge_requests" do let_it_be(:group) { create(:group, :public) } let_it_be(:project) { create(:project, :public, :repository, creator: user, namespace: group, only_allow_merge_if_pipeline_succeeds: false) } + + include_context 'with merge requests' + let(:endpoint_path) { "/groups/#{group.id}/merge_requests" } before do @@ -877,6 +894,8 @@ RSpec.describe API::MergeRequests do let_it_be(:subgroup) { create(:group, parent: group) } let_it_be(:project) { create(:project, :public, :repository, creator: user, namespace: subgroup, only_allow_merge_if_pipeline_succeeds: false) } + include_context 'with merge requests' + it_behaves_like 'merge requests list' end @@ -893,7 +912,7 @@ RSpec.describe API::MergeRequests do let(:parent_group) { create(:group) } before do - group.update(parent_id: parent_group.id) + group.update!(parent_id: parent_group.id) merge_request_merged.reload end @@ -936,6 +955,8 @@ RSpec.describe API::MergeRequests do end describe "GET /projects/:id/merge_requests/:merge_request_iid" do + let(:merge_request) { create(:merge_request, :simple, author: user, assignees: [user], milestone: milestone, source_project: project, source_branch: 'markdown', title: "Test") } + it 'matches json schema' do merge_request = create(:merge_request, :with_test_reports, milestone: milestone1, author: user, assignees: [user], source_project: project, target_project: project, title: "Test", created_at: base_time) get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user) @@ -1006,7 +1027,7 @@ RSpec.describe API::MergeRequests do let(:non_member) { create(:user) } before do - merge_request.update(author: non_member) + merge_request.update!(author: non_member) end it 'exposes first_contribution as true' do @@ -1059,9 +1080,12 @@ RSpec.describe API::MergeRequests do end context 'head_pipeline' do + let(:project) { create(:project, :repository) } + let(:merge_request) { create(:merge_request, :simple, author: user, source_project: project, source_branch: 'markdown', title: "Test") } + before do - merge_request.update(head_pipeline: create(:ci_pipeline)) - merge_request.project.project_feature.update(builds_access_level: 10) + merge_request.update!(head_pipeline: create(:ci_pipeline)) + merge_request.project.project_feature.update!(builds_access_level: 10) end context 'when user can read the pipeline' do @@ -1188,11 +1212,13 @@ RSpec.describe API::MergeRequests do describe 'GET /projects/:id/merge_requests/:merge_request_iid/participants' do it_behaves_like 'issuable participants endpoint' do - let(:entity) { merge_request } + let(:entity) { create(:merge_request, :simple, milestone: milestone1, author: user, assignees: [user], source_project: project, target_project: project, source_branch: 'markdown', title: "Test", created_at: base_time) } end end describe 'GET /projects/:id/merge_requests/:merge_request_iid/commits' do + include_context 'with merge requests' + it 'returns a 200 when merge request is valid' do get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/commits", user) commit = merge_request.commits.first @@ -1216,6 +1242,9 @@ RSpec.describe API::MergeRequests do end describe 'GET /projects/:id/merge_requests/:merge_request_iid/:context_commits' do + let_it_be(:merge_request) { create(:merge_request, :simple, author: user, source_project: project, target_project: project, source_branch: 'markdown', title: "Test", created_at: base_time) } + let_it_be(:merge_request_context_commit) { create(:merge_request_context_commit, merge_request: merge_request, message: 'test') } + it 'returns a 200 when merge request is valid' do context_commit = merge_request.context_commits.first @@ -1234,6 +1263,8 @@ RSpec.describe API::MergeRequests do end describe 'GET /projects/:id/merge_requests/:merge_request_iid/changes' do + let_it_be(:merge_request) { create(:merge_request, :simple, author: user, assignees: [user], source_project: project, target_project: project, source_branch: 'markdown', title: "Test", created_at: base_time) } + it 'returns the change information of the merge_request' do get api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/changes", user) @@ -1254,6 +1285,8 @@ RSpec.describe API::MergeRequests do end describe 'GET /projects/:id/merge_requests/:merge_request_iid/pipelines' do + let_it_be(:merge_request) { create(:merge_request, :simple, author: user, assignees: [user], source_project: project, target_project: project, source_branch: 'markdown', title: "Test", created_at: base_time) } + context 'when authorized' do let!(:pipeline) { create(:ci_empty_pipeline, project: project, user: user, ref: merge_request.source_branch, sha: merge_request.diff_head_sha) } let!(:pipeline2) { create(:ci_empty_pipeline, project: project) } @@ -1308,16 +1341,15 @@ RSpec.describe API::MergeRequests do }) end - let(:project) do + let_it_be(:project) do create(:project, :private, :repository, creator: user, namespace: user.namespace, only_allow_merge_if_pipeline_succeeds: false) end - let(:merge_request) do + let_it_be(:merge_request) do create(:merge_request, :with_detached_merge_request_pipeline, - milestone: milestone1, author: user, assignees: [user], source_project: project, @@ -1351,7 +1383,7 @@ RSpec.describe API::MergeRequests do end context 'when the merge request does not exist' do - let(:merge_request_iid) { 777 } + let(:merge_request_iid) { non_existing_record_id } it 'responds with a blank 404' do expect { request }.not_to change(Ci::Pipeline, :count) @@ -1604,7 +1636,7 @@ RSpec.describe API::MergeRequests do end.to change { MergeRequest.count }.by(0) expect(response).to have_gitlab_http_status(:conflict) - expect(json_response['message']).to eq(["Another open merge request already exists for this source branch: !5"]) + expect(json_response['message']).to eq(["Another open merge request already exists for this source branch: !1"]) end end @@ -1659,7 +1691,7 @@ RSpec.describe API::MergeRequests do end it 'returns 403 when target project has disabled merge requests' do - project.project_feature.update(merge_requests_access_level: 0) + project.project_feature.update!(merge_requests_access_level: 0) post api("/projects/#{forked_project.id}/merge_requests", user2), params: { @@ -1778,6 +1810,7 @@ RSpec.describe API::MergeRequests do before do create(:merge_request_context_commit, merge_request: merge_request, sha: commit.id) end + it 'returns 400 when the context commit is already created' do post api("/projects/#{project.id}/merge_requests/#{merge_request_iid}/context_commits", authenticated_user), params: params expect(response).to have_gitlab_http_status(:bad_request) @@ -1937,7 +1970,9 @@ RSpec.describe API::MergeRequests do end describe "PUT /projects/:id/merge_requests/:merge_request_iid/merge", :clean_gitlab_redis_cache do - let(:pipeline) { create(:ci_pipeline) } + let(:project) { create(:project, :repository, namespace: user.namespace) } + let(:merge_request) { create(:merge_request, :simple, author: user, source_project: project, source_branch: 'markdown', title: 'Test') } + let(:pipeline) { create(:ci_pipeline, project: project) } it "returns merge_request in case of success" do put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user) @@ -2111,7 +2146,7 @@ RSpec.describe API::MergeRequests do let(:source_branch) { merge_request.source_branch } before do - merge_request.update(merge_params: { 'force_remove_source_branch' => true }) + merge_request.update!(merge_params: { 'force_remove_source_branch' => true }) end it 'removes the source branch' do @@ -2138,7 +2173,7 @@ RSpec.describe API::MergeRequests do let(:merge_request) { create(:merge_request, :rebased, source_project: project, squash: true) } before do - project.update(merge_requests_ff_only_enabled: true) + project.update!(merge_requests_ff_only_enabled: true) end it "records the squash commit SHA and returns it in the response" do @@ -2169,9 +2204,7 @@ RSpec.describe API::MergeRequests do end context 'when merge-ref is not synced with merge status' do - before do - merge_request.update!(merge_status: 'cannot_be_merged') - end + let(:merge_request) { create(:merge_request, :simple, author: user, source_project: project, source_branch: 'markdown', merge_status: 'cannot_be_merged') } it 'returns 200 if MR can be merged' do get api(url, user) @@ -2230,7 +2263,7 @@ RSpec.describe API::MergeRequests do describe "PUT /projects/:id/merge_requests/:merge_request_iid" do context 'updates force_remove_source_branch properly' do it 'sets to false' do - merge_request.update(merge_params: { 'force_remove_source_branch' => true } ) + merge_request.update!(merge_params: { 'force_remove_source_branch' => true } ) expect(merge_request.force_remove_source_branch?).to be_truthy @@ -2242,7 +2275,7 @@ RSpec.describe API::MergeRequests do end it 'sets to true' do - merge_request.update(merge_params: { 'force_remove_source_branch' => false } ) + merge_request.update!(merge_params: { 'force_remove_source_branch' => false } ) expect(merge_request.force_remove_source_branch?).to be_falsey @@ -2254,6 +2287,7 @@ RSpec.describe API::MergeRequests do end context 'with a merge request across forks' do + let(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace, only_allow_merge_if_pipeline_succeeds: false) } let(:fork_owner) { create(:user) } let(:source_project) { fork_project(project, fork_owner) } let(:target_project) { project } @@ -2320,12 +2354,46 @@ RSpec.describe API::MergeRequests do expect(json_response['squash']).to be_truthy end - it "returns merge_request with renamed target_branch" do + it "updates target_branch and returns merge_request" do put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { target_branch: "wiki" } expect(response).to have_gitlab_http_status(:ok) expect(json_response['target_branch']).to eq('wiki') end + context "forked projects" do + let_it_be(:user2) { create(:user) } + let(:project) { create(:project, :public, :repository) } + let!(:forked_project) { fork_project(project, user2, repository: true) } + let(:merge_request) do + create(:merge_request, + source_project: forked_project, + target_project: project, + source_branch: "fixes") + end + + shared_examples "update of allow_collaboration and allow_maintainer_to_push" do |request_value, expected_value| + %w[allow_collaboration allow_maintainer_to_push].each do |attr| + it "attempts to update #{attr} to #{request_value} and returns #{expected_value} for `allow_collaboration`" do + put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user2), params: { attr => request_value } + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response["allow_collaboration"]).to eq(expected_value) + expect(json_response["allow_maintainer_to_push"]).to eq(expected_value) + end + end + end + + context "when source project is public (i.e. MergeRequest#collaborative_push_possible? == true)" do + it_behaves_like "update of allow_collaboration and allow_maintainer_to_push", true, true + end + + context "when source project is private (i.e. MergeRequest#collaborative_push_possible? == false)" do + let(:project) { create(:project, :private, :repository) } + + it_behaves_like "update of allow_collaboration and allow_maintainer_to_push", true, false + end + end + it "returns merge_request that removes the source branch" do put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}", user), params: { remove_source_branch: true } @@ -2717,7 +2785,7 @@ RSpec.describe API::MergeRequests do end describe 'Time tracking' do - let(:issuable) { merge_request } + let!(:issuable) { create(:merge_request, :simple, author: user, assignees: [user], source_project: project, target_project: project, source_branch: 'markdown', title: "Test", created_at: base_time) } include_examples 'time tracking endpoints', 'merge_request' end @@ -2726,7 +2794,7 @@ RSpec.describe API::MergeRequests do merge_request merge_request.created_at += 1.hour merge_request.updated_at += 30.minutes - merge_request.save + merge_request.save! merge_request end @@ -2734,7 +2802,7 @@ RSpec.describe API::MergeRequests do merge_request_closed merge_request_closed.created_at -= 1.hour merge_request_closed.updated_at -= 30.minutes - merge_request_closed.save + merge_request_closed.save! merge_request_closed end end |