gitlab-org--gitlab-foss/spec/controllers/projects/compare_controller_spec.rb

350 lines
10 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::CompareController do
let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
before do
sign_in(user)
project.add_maintainer(user)
end
describe 'GET index' do
render_views
before do
get :index, params: { namespace_id: project.namespace, project_id: project }
end
it 'returns successfully' do
expect(response).to be_successful
end
end
describe 'GET show' do
render_views
subject(:show_request) { get :show, params: request_params }
let(:request_params) do
{
namespace_id: project.namespace,
project_id: project,
from: source_ref,
to: target_ref,
w: whitespace
}
end
let(:whitespace) { nil }
context 'when the refs exist' do
context 'when we set the white space param' do
let(:source_ref) { "08f22f25" }
let(:target_ref) { "66eceea0" }
let(:whitespace) { 1 }
it 'shows some diffs with ignore whitespace change option' do
show_request
expect(response).to be_successful
diff_file = assigns(:diffs).diff_files.first
expect(diff_file).not_to be_nil
expect(assigns(:commits).length).to be >= 1
# without whitespace option, there are more than 2 diff_splits
diff_splits = diff_file.diff.diff.split("\n")
expect(diff_splits.length).to be <= 2
end
end
context 'when we do not set the white space param' do
let(:source_ref) { "improve%2Fawesome" }
let(:target_ref) { "feature" }
let(:whitespace) { nil }
it 'sets the diffs and commits ivars' do
show_request
expect(response).to be_successful
expect(assigns(:diffs).diff_files.first).not_to be_nil
expect(assigns(:commits).length).to be >= 1
end
end
end
context 'when the source ref does not exist' do
let(:source_ref) { 'non-existent-source-ref' }
let(:target_ref) { "feature" }
it 'sets empty diff and commit ivars' do
show_request
expect(response).to be_successful
expect(assigns(:diffs)).to eq([])
expect(assigns(:commits)).to eq([])
end
end
context 'when the target ref does not exist' do
let(:target_ref) { 'non-existent-target-ref' }
let(:source_ref) { "improve%2Fawesome" }
it 'sets empty diff and commit ivars' do
show_request
expect(response).to be_successful
expect(assigns(:diffs)).to eq([])
expect(assigns(:commits)).to eq([])
end
end
context 'when the target ref is invalid' do
let(:target_ref) { "master%' AND 2554=4423 AND '%'='" }
let(:source_ref) { "improve%2Fawesome" }
it 'shows a flash message and redirects' do
show_request
expect(flash[:alert]).to eq('Invalid branch name')
expect(response).to have_gitlab_http_status(:found)
end
end
context 'when the source ref is invalid' do
let(:source_ref) { "master%' AND 2554=4423 AND '%'='" }
let(:target_ref) { "improve%2Fawesome" }
it 'shows a flash message and redirects' do
show_request
expect(flash[:alert]).to eq('Invalid branch name')
expect(response).to have_gitlab_http_status(:found)
end
end
end
describe 'GET diff_for_path' do
def diff_for_path(extra_params = {})
params = {
namespace_id: project.namespace,
project_id: project
}
get :diff_for_path, params: params.merge(extra_params)
end
let(:existing_path) { 'files/ruby/feature.rb' }
let(:source_ref) { "improve%2Fawesome" }
let(:target_ref) { "feature" }
context 'when the source and target refs exist' do
context 'when the user has access target the project' do
context 'when the path exists in the diff' do
it 'disables diff notes' do
diff_for_path(from: source_ref, to: target_ref, old_path: existing_path, new_path: existing_path)
expect(assigns(:diff_notes_disabled)).to be_truthy
end
it 'only renders the diffs for the path given' do
expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs|
expect(diffs.diff_files.map(&:new_path)).to contain_exactly(existing_path)
meth.call(diffs)
end
diff_for_path(from: source_ref, to: target_ref, old_path: existing_path, new_path: existing_path)
end
end
context 'when the path does not exist in the diff' do
before do
diff_for_path(from: source_ref, to: target_ref, old_path: existing_path.succ, new_path: existing_path.succ)
end
it 'returns a 404' do
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
context 'when the user does not have access target the project' do
before do
project.team.truncate
diff_for_path(from: source_ref, to: target_ref, old_path: existing_path, new_path: existing_path)
end
it 'returns a 404' do
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
context 'when the source ref does not exist' do
before do
diff_for_path(from: source_ref.succ, to: target_ref, old_path: existing_path, new_path: existing_path)
end
it 'returns a 404' do
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when the target ref does not exist' do
before do
diff_for_path(from: source_ref, to: target_ref.succ, old_path: existing_path, new_path: existing_path)
end
it 'returns a 404' do
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
describe 'POST create' do
subject(:create_request) { post :create, params: request_params }
let(:request_params) do
{
namespace_id: project.namespace,
project_id: project,
from: source_ref,
to: target_ref
}
end
context 'when sending valid params' do
let(:source_ref) { "improve%2Fawesome" }
let(:target_ref) { "feature" }
it 'redirects back to show' do
create_request
expect(response).to redirect_to(project_compare_path(project, to: target_ref, from: source_ref))
end
end
context 'when sending invalid params' do
context 'when the source ref is empty and target ref is set' do
let(:source_ref) { '' }
let(:target_ref) { 'master' }
it 'redirects back to index and preserves the target ref' do
create_request
expect(response).to redirect_to(project_compare_index_path(project, to: target_ref))
end
end
context 'when the target ref is empty and source ref is set' do
let(:source_ref) { 'master' }
let(:target_ref) { '' }
it 'redirects back to index and preserves source ref' do
create_request
expect(response).to redirect_to(project_compare_index_path(project, from: source_ref))
end
end
context 'when the target and source ref are empty' do
let(:source_ref) { '' }
let(:target_ref) { '' }
it 'redirects back to index' do
create_request
expect(response).to redirect_to(namespace_project_compare_index_path)
end
end
end
end
describe 'GET signatures' do
subject(:signatures_request) { get :signatures, params: request_params }
let(:request_params) do
{
namespace_id: project.namespace,
project_id: project,
from: source_ref,
to: target_ref,
format: :json
}
end
context 'when the source and target refs exist' do
let(:source_ref) { "improve%2Fawesome" }
let(:target_ref) { "feature" }
context 'when the user has access to the project' do
render_views
let(:signature_commit) { project.commit_by(oid: '0b4bc9a49b562e85de7cc9e834518ea6828729b9') }
let(:non_signature_commit) { build(:commit, project: project, safe_message: "message", sha: 'non_signature_commit') }
before do
escaped_source_ref = Addressable::URI.unescape(source_ref)
escaped_target_ref = Addressable::URI.unescape(target_ref)
compare_service = CompareService.new(project, escaped_target_ref)
compare = compare_service.execute(project, escaped_source_ref)
expect(CompareService).to receive(:new).with(project, escaped_target_ref).and_return(compare_service)
expect(compare_service).to receive(:execute).with(project, escaped_source_ref).and_return(compare)
expect(compare).to receive(:commits).and_return([signature_commit, non_signature_commit])
expect(non_signature_commit).to receive(:has_signature?).and_return(false)
end
it 'returns only the commit with a signature' do
signatures_request
expect(response).to have_gitlab_http_status(:ok)
signatures = json_response['signatures']
expect(signatures.size).to eq(1)
expect(signatures.first['commit_sha']).to eq(signature_commit.sha)
expect(signatures.first['html']).to be_present
end
end
context 'when the user does not have access to the project' do
before do
project.team.truncate
end
it 'returns a 404' do
signatures_request
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
context 'when the source ref does not exist' do
let(:source_ref) { 'non-existent-ref-source' }
let(:target_ref) { "feature" }
it 'returns no signatures' do
signatures_request
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['signatures']).to be_empty
end
end
context 'when the target ref does not exist' do
let(:target_ref) { 'non-existent-ref-target' }
let(:source_ref) { "improve%2Fawesome" }
it 'returns no signatures' do
signatures_request
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['signatures']).to be_empty
end
end
end
end