Commit 18a63c6b authored by Sean McGivern's avatar Sean McGivern

Merge branch 'id-move-post-receive-tests-to-service-spec' into 'master'

Convert request specs into units for PostReceiveService

See merge request gitlab-org/gitlab!25377
parents 9afd7128 c995fafd
...@@ -811,6 +811,8 @@ describe API::Internal::Base do ...@@ -811,6 +811,8 @@ describe API::Internal::Base do
describe 'POST /internal/post_receive', :clean_gitlab_redis_shared_state do describe 'POST /internal/post_receive', :clean_gitlab_redis_shared_state do
let(:identifier) { 'key-123' } let(:identifier) { 'key-123' }
let(:branch_name) { 'feature' }
let(:push_options) { ['ci.skip', 'another push option'] }
let(:valid_params) do let(:valid_params) do
{ {
...@@ -822,192 +824,33 @@ describe API::Internal::Base do ...@@ -822,192 +824,33 @@ describe API::Internal::Base do
} }
end end
let(:branch_name) { 'feature' }
let(:changes) do let(:changes) do
"#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/#{branch_name}" "#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/#{branch_name}"
end end
let(:push_options) do subject { post api('/internal/post_receive'), params: valid_params }
['ci.skip',
'another push option']
end
before do before do
project.add_developer(user) project.add_developer(user)
allow_any_instance_of(Gitlab::Identifier).to receive(:identify).and_return(user) allow_any_instance_of(Gitlab::Identifier).to receive(:identify).and_return(user)
end end
it 'enqueues a PostReceive worker job' do it 'executes PostReceiveService' do
expect(PostReceive).to receive(:perform_async)
.with(gl_repository, identifier, changes, { ci: { skip: true } })
post api('/internal/post_receive'), params: valid_params
end
it 'decreases the reference counter and returns the result' do
expect(Gitlab::ReferenceCounter).to receive(:new).with(gl_repository)
.and_return(reference_counter)
expect(reference_counter).to receive(:decrease).and_return(true)
post api('/internal/post_receive'), params: valid_params
expect(json_response['reference_counter_decreased']).to be(true)
end
it 'returns link to create new merge request' do
post api('/internal/post_receive'), params: valid_params
message = <<~MESSAGE.strip message = <<~MESSAGE.strip
To create a merge request for #{branch_name}, visit: To create a merge request for #{branch_name}, visit:
http://#{Gitlab.config.gitlab.host}/#{project.full_path}/-/merge_requests/new?merge_request%5Bsource_branch%5D=#{branch_name} http://#{Gitlab.config.gitlab.host}/#{project.full_path}/-/merge_requests/new?merge_request%5Bsource_branch%5D=#{branch_name}
MESSAGE MESSAGE
expect(json_response['messages']).to include(build_basic_message(message)) subject
end
it 'returns the link to an existing merge request when it exists' do
merge_request = create(:merge_request, source_project: project, source_branch: branch_name, target_branch: 'master')
post api('/internal/post_receive'), params: valid_params
message = <<~MESSAGE.strip
View merge request for feature:
#{project_merge_request_url(project, merge_request)}
MESSAGE
expect(json_response['messages']).to include(build_basic_message(message))
end
it 'returns no merge request messages if printing_merge_request_link_enabled is false' do expect(json_response).to eq({
project.update!(printing_merge_request_link_enabled: false) 'messages' => [{ 'message' => message, 'type' => 'basic' }],
'reference_counter_decreased' => true
post api('/internal/post_receive'), params: valid_params })
expect(json_response['messages']).to be_blank
end
it 'does not invoke MergeRequests::PushOptionsHandlerService' do
expect(MergeRequests::PushOptionsHandlerService).not_to receive(:new)
post api('/internal/post_receive'), params: valid_params
end end
it_behaves_like 'storing arguments in the application context' do it_behaves_like 'storing arguments in the application context' do
let(:expected_params) { { user: user.username, project: project.full_path } } let(:expected_params) { { user: user.username, project: project.full_path } }
subject { post api('/internal/post_receive'), params: valid_params }
end
context 'when there are merge_request push options' do
before do
valid_params[:push_options] = ['merge_request.create']
end
it 'invokes MergeRequests::PushOptionsHandlerService' do
expect(MergeRequests::PushOptionsHandlerService).to receive(:new)
post api('/internal/post_receive'), params: valid_params
end
it 'creates a new merge request' do
expect do
Sidekiq::Testing.fake! do
post api('/internal/post_receive'), params: valid_params
end
end.to change { MergeRequest.count }.by(1)
end
it 'links to the newly created merge request' do
post api('/internal/post_receive'), params: valid_params
message = <<~MESSAGE.strip
View merge request for #{branch_name}:
http://#{Gitlab.config.gitlab.host}/#{project.full_path}/-/merge_requests/1
MESSAGE
expect(json_response['messages']).to include(build_basic_message(message))
end
it 'adds errors on the service instance to warnings' do
expect_any_instance_of(
MergeRequests::PushOptionsHandlerService
).to receive(:errors).at_least(:once).and_return(['my error'])
post api('/internal/post_receive'), params: valid_params
message = "WARNINGS:\nError encountered with push options 'merge_request.create': my error"
expect(json_response['messages']).to include(build_alert_message(message))
end
it 'adds ActiveRecord errors on invalid MergeRequest records to warnings' do
invalid_merge_request = MergeRequest.new
invalid_merge_request.errors.add(:base, 'my error')
expect_any_instance_of(
MergeRequests::CreateService
).to receive(:execute).and_return(invalid_merge_request)
post api('/internal/post_receive'), params: valid_params
message = "WARNINGS:\nError encountered with push options 'merge_request.create': my error"
expect(json_response['messages']).to include(build_alert_message(message))
end
end
context 'broadcast message exists' do
let!(:broadcast_message) { create(:broadcast_message, starts_at: 1.day.ago, ends_at: 1.day.from_now ) }
it 'outputs a broadcast message' do
post api('/internal/post_receive'), params: valid_params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['messages']).to include(build_alert_message(broadcast_message.message))
end
end
context 'broadcast message does not exist' do
it 'does not output a broadcast message' do
post api('/internal/post_receive'), params: valid_params
expect(response).to have_gitlab_http_status(:ok)
expect(has_alert_messages?(json_response['messages'])).to be_falsey
end
end
context 'nil broadcast message' do
it 'does not output a broadcast message' do
allow(BroadcastMessage).to receive(:current).and_return(nil)
post api('/internal/post_receive'), params: valid_params
expect(response).to have_gitlab_http_status(:ok)
expect(has_alert_messages?(json_response['messages'])).to be_falsey
end
end
context 'with a redirected data' do
it 'returns redirected message on the response' do
project_moved = Gitlab::Checks::ProjectMoved.new(project, user, 'http', 'foo/baz')
project_moved.add_message
post api('/internal/post_receive'), params: valid_params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['messages']).to include(build_basic_message(project_moved.message))
end
end
context 'with new project data' do
it 'returns new project message on the response' do
project_created = Gitlab::Checks::ProjectCreated.new(project, user, 'http')
project_created.add_message
post api('/internal/post_receive'), params: valid_params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['messages']).to include(build_basic_message(project_created.message))
end
end end
context 'with an orphaned write deploy key' do context 'with an orphaned write deploy key' do
...@@ -1016,7 +859,7 @@ describe API::Internal::Base do ...@@ -1016,7 +859,7 @@ describe API::Internal::Base do
expect(Gitlab::Checks::ProjectMoved).not_to receive(:fetch_message) expect(Gitlab::Checks::ProjectMoved).not_to receive(:fetch_message)
post api('/internal/post_receive'), params: valid_params subject
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
end end
...@@ -1030,7 +873,7 @@ describe API::Internal::Base do ...@@ -1030,7 +873,7 @@ describe API::Internal::Base do
expect(Gitlab::Checks::ProjectMoved).not_to receive(:fetch_message) expect(Gitlab::Checks::ProjectMoved).not_to receive(:fetch_message)
post api('/internal/post_receive'), params: valid_params subject
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
end end
...@@ -1142,18 +985,4 @@ describe API::Internal::Base do ...@@ -1142,18 +985,4 @@ describe API::Internal::Base do
} }
) )
end end
def build_alert_message(message)
{ 'type' => 'alert', 'message' => message }
end
def build_basic_message(message)
{ 'type' => 'basic', 'message' => message }
end
def has_alert_messages?(messages)
messages.any? do |message|
message['type'] == 'alert'
end
end
end end
# frozen_string_literal: true
require 'spec_helper'
describe PostReceiveService do
include Gitlab::Routing
let_it_be(:project) { create(:project, :repository, :wiki_repo) }
let_it_be(:user) { create(:user) }
let(:identifier) { 'key-123' }
let(:gl_repository) { "project-#{project.id}" }
let(:branch_name) { 'feature' }
let(:secret_token) { Gitlab::Shell.secret_token }
let(:reference_counter) { double('ReferenceCounter') }
let(:push_options) { ['ci.skip', 'another push option'] }
let(:changes) do
"#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/#{branch_name}"
end
let(:params) do
{
gl_repository: gl_repository,
secret_token: secret_token,
identifier: identifier,
changes: changes,
push_options: push_options
}
end
let(:response) { PostReceiveService.new(user, project, params).execute }
subject { response.messages.as_json }
it 'enqueues a PostReceive worker job' do
expect(PostReceive).to receive(:perform_async)
.with(gl_repository, identifier, changes, { ci: { skip: true } })
subject
end
it 'decreases the reference counter and returns the result' do
expect(Gitlab::ReferenceCounter).to receive(:new).with(gl_repository)
.and_return(reference_counter)
expect(reference_counter).to receive(:decrease).and_return(true)
expect(response.reference_counter_decreased).to be(true)
end
it 'returns link to create new merge request' do
message = <<~MESSAGE.strip
To create a merge request for #{branch_name}, visit:
http://#{Gitlab.config.gitlab.host}/#{project.full_path}/-/merge_requests/new?merge_request%5Bsource_branch%5D=#{branch_name}
MESSAGE
expect(subject).to include(build_basic_message(message))
end
it 'returns the link to an existing merge request when it exists' do
merge_request = create(:merge_request, source_project: project, source_branch: branch_name, target_branch: 'master')
message = <<~MESSAGE.strip
View merge request for feature:
#{project_merge_request_url(project, merge_request)}
MESSAGE
expect(subject).to include(build_basic_message(message))
end
context 'when printing_merge_request_link_enabled is false' do
let(:project) { create(:project, printing_merge_request_link_enabled: false) }
it 'returns no merge request messages' do
expect(subject).to be_blank
end
end
it 'does not invoke MergeRequests::PushOptionsHandlerService' do
expect(MergeRequests::PushOptionsHandlerService).not_to receive(:new)
subject
end
context 'when there are merge_request push options' do
let(:params) { super().merge(push_options: ['merge_request.create']) }
before do
project.add_developer(user)
end
it 'invokes MergeRequests::PushOptionsHandlerService' do
expect(MergeRequests::PushOptionsHandlerService).to receive(:new).and_call_original
subject
end
it 'creates a new merge request' do
expect { Sidekiq::Testing.fake! { subject } }.to change(MergeRequest, :count).by(1)
end
it 'links to the newly created merge request' do
message = <<~MESSAGE.strip
View merge request for #{branch_name}:
http://#{Gitlab.config.gitlab.host}/#{project.full_path}/-/merge_requests/1
MESSAGE
expect(subject).to include(build_basic_message(message))
end
it 'adds errors on the service instance to warnings' do
expect_any_instance_of(
MergeRequests::PushOptionsHandlerService
).to receive(:errors).at_least(:once).and_return(['my error'])
message = "WARNINGS:\nError encountered with push options 'merge_request.create': my error"
expect(subject).to include(build_alert_message(message))
end
it 'adds ActiveRecord errors on invalid MergeRequest records to warnings' do
invalid_merge_request = MergeRequest.new
invalid_merge_request.errors.add(:base, 'my error')
message = "WARNINGS:\nError encountered with push options 'merge_request.create': my error"
expect_any_instance_of(
MergeRequests::CreateService
).to receive(:execute).and_return(invalid_merge_request)
expect(subject).to include(build_alert_message(message))
end
end
context 'broadcast message exists' do
it 'outputs a broadcast message' do
broadcast_message = create(:broadcast_message, starts_at: 1.day.ago, ends_at: 1.day.from_now)
expect(subject).to include(build_alert_message(broadcast_message.message))
end
end
context 'broadcast message does not exist' do
it 'does not output a broadcast message' do
expect(has_alert_messages?(subject)).to be_falsey
end
end
context 'nil broadcast message' do
it 'does not output a broadcast message' do
allow(BroadcastMessage).to receive(:current).and_return(nil)
expect(has_alert_messages?(subject)).to be_falsey
end
end
context 'with a redirected data' do
it 'returns redirected message on the response' do
project_moved = Gitlab::Checks::ProjectMoved.new(project, user, 'http', 'foo/baz')
project_moved.add_message
expect(subject).to include(build_basic_message(project_moved.message))
end
end
context 'with new project data' do
it 'returns new project message on the response' do
project_created = Gitlab::Checks::ProjectCreated.new(project, user, 'http')
project_created.add_message
expect(subject).to include(build_basic_message(project_created.message))
end
end
def build_alert_message(message)
{ 'type' => 'alert', 'message' => message }
end
def build_basic_message(message)
{ 'type' => 'basic', 'message' => message }
end
def has_alert_messages?(messages)
messages.any? do |message|
message['type'] == 'alert'
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