# frozen_string_literal: true require 'spec_helper' describe Issues::RelatedBranchesService do let_it_be(:developer) { create(:user) } let_it_be(:issue) { create(:issue) } let(:user) { developer } subject { described_class.new(issue.project, user) } before do issue.project.add_developer(developer) end describe '#execute' do let(:sha) { 'abcdef' } let(:repo) { issue.project.repository } let(:project) { issue.project } let(:branch_info) { subject.execute(issue) } def make_branch double('Branch', dereferenced_target: double('Target', sha: sha)) end before do allow(repo).to receive(:branch_names).and_return(branch_names) end context 'no branches are available' do let(:branch_names) { [] } it 'returns an empty array' do expect(branch_info).to be_empty end end context 'branches are available' do let(:missing_branch) { "#{issue.to_branch_name}-missing" } let(:unreadable_branch_name) { "#{issue.to_branch_name}-unreadable" } let(:pipeline) { build(:ci_pipeline, :success, project: project) } let(:unreadable_pipeline) { build(:ci_pipeline, :running) } let(:branch_names) do [ generate(:branch), "#{issue.iid}doesnt-match", issue.to_branch_name, missing_branch, unreadable_branch_name ] end before do { issue.to_branch_name => pipeline, unreadable_branch_name => unreadable_pipeline }.each do |name, pipeline| allow(repo).to receive(:find_branch).with(name).and_return(make_branch) allow(project).to receive(:pipeline_for).with(name, sha).and_return(pipeline) end allow(repo).to receive(:find_branch).with(missing_branch).and_return(nil) end it 'selects relevant branches, along with pipeline status where available' do expect(branch_info).to contain_exactly( { name: issue.to_branch_name, pipeline_status: an_instance_of(Gitlab::Ci::Status::Success) }, { name: missing_branch, pipeline_status: be_nil }, { name: unreadable_branch_name, pipeline_status: be_nil } ) end context 'the user has access to otherwise unreadable pipelines' do let(:user) { create(:admin) } it 'returns info a developer could not see' do expect(branch_info.pluck(:pipeline_status)).to include(an_instance_of(Gitlab::Ci::Status::Running)) end end it 'excludes branches referenced in merge requests' do merge_request = create(:merge_request, { description: "Closes #{issue.to_reference}", source_project: issue.project, source_branch: issue.to_branch_name }) merge_request.create_cross_references!(user) referenced_merge_requests = Issues::ReferencedMergeRequestsService .new(issue.project, user) .referenced_merge_requests(issue) expect(referenced_merge_requests).not_to be_empty expect(branch_info.pluck(:name)).not_to include(merge_request.source_branch) end end context 'one of the branches is stable' do let(:branch_names) { ["#{issue.iid}-0-stable"] } it 'is excluded' do expect(branch_info).to be_empty end end end end