# frozen_string_literal: true shared_examples 'issuable link creation' do describe '#execute' do subject { described_class.new(issuable, user, params).execute } context 'when the reference list is empty' do let(:params) do { issuable_references: [] } end it 'returns error' do is_expected.to eq(message: "No matching #{issuable_type} found. Make sure that you are adding a valid #{issuable_type} URL.", status: :error, http_status: 404) end end context 'when Issuable not found' do let(:params) do { issuable_references: ["##{non_existing_record_iid}"] } end it 'returns error' do is_expected.to eq(message: "No matching #{issuable_type} found. Make sure that you are adding a valid #{issuable_type} URL.", status: :error, http_status: 404) end it 'no relationship is created' do expect { subject }.not_to change(issuable_link_class, :count) end end context 'when user has no permission to target issuable' do let(:params) do { issuable_references: [guest_issuable.to_reference(issuable_parent)] } end it 'returns error' do is_expected.to eq(message: "No matching #{issuable_type} found. Make sure that you are adding a valid #{issuable_type} URL.", status: :error, http_status: 404) end it 'no relationship is created' do expect { subject }.not_to change(issuable_link_class, :count) end end context 'source and target are the same issuable' do let(:params) do { issuable_references: [issuable.to_reference] } end it 'does not create notes' do expect(SystemNoteService).not_to receive(:relate_issuable) subject end it 'no relationship is created' do expect { subject }.not_to change(issuable_link_class, :count) end end context 'when there is an issuable to relate' do let(:params) do { issuable_references: [issuable2.to_reference, issuable3.to_reference(issuable_parent)] } end it 'creates relationships' do expect { subject }.to change(issuable_link_class, :count).by(2) expect(issuable_link_class.find_by!(target: issuable2)).to have_attributes(source: issuable, link_type: 'relates_to') expect(issuable_link_class.find_by!(target: issuable3)).to have_attributes(source: issuable, link_type: 'relates_to') end it 'returns success status' do is_expected.to eq(status: :success) end it 'creates notes' do # First two-way relation notes expect(SystemNoteService).to receive(:relate_issuable) .with(issuable, issuable2, user) expect(SystemNoteService).to receive(:relate_issuable) .with(issuable2, issuable, user) # Second two-way relation notes expect(SystemNoteService).to receive(:relate_issuable) .with(issuable, issuable3, user) expect(SystemNoteService).to receive(:relate_issuable) .with(issuable3, issuable, user) subject end end context 'when reference of any already related issue is present' do let(:params) do { issuable_references: [ issuable_a.to_reference, issuable_b.to_reference ], link_type: IssueLink::TYPE_RELATES_TO } end it 'creates notes only for new relations' do expect(SystemNoteService).to receive(:relate_issuable).with(issuable, issuable_a, anything) expect(SystemNoteService).to receive(:relate_issuable).with(issuable_a, issuable, anything) expect(SystemNoteService).not_to receive(:relate_issuable).with(issuable, issuable_b, anything) expect(SystemNoteService).not_to receive(:relate_issuable).with(issuable_b, issuable, anything) subject end end context 'when there are invalid references' do let(:params) do { issuable_references: [issuable.to_reference, issuable_a.to_reference] } end it 'creates links only for valid references' do expect { subject }.to change { issuable_link_class.count }.by(1) end it 'returns error status' do expect(subject).to eq( status: :error, http_status: 422, message: "#{issuable.to_reference} cannot be added: cannot be related to itself" ) end end end end