195 lines
6.4 KiB
Ruby
195 lines
6.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe IssueLinks::ListService do
|
|
let(:user) { create :user }
|
|
let(:project) { create(:project_empty_repo, :private) }
|
|
let(:issue) { create :issue, project: project }
|
|
let(:user_role) { :developer }
|
|
|
|
before do
|
|
project.add_role(user, user_role)
|
|
end
|
|
|
|
describe '#execute' do
|
|
subject { described_class.new(issue, user).execute }
|
|
|
|
context 'user can see all issues' do
|
|
let(:issue_b) { create :issue, project: project }
|
|
let(:issue_c) { create :issue, project: project }
|
|
let(:issue_d) { create :issue, project: project }
|
|
|
|
let!(:issue_link_c) do
|
|
create(:issue_link, source: issue_d,
|
|
target: issue)
|
|
end
|
|
|
|
let!(:issue_link_b) do
|
|
create(:issue_link, source: issue,
|
|
target: issue_c)
|
|
end
|
|
|
|
let!(:issue_link_a) do
|
|
create(:issue_link, source: issue,
|
|
target: issue_b)
|
|
end
|
|
|
|
it 'ensures no N+1 queries are made' do
|
|
control_count = ActiveRecord::QueryRecorder.new { subject }.count
|
|
|
|
project = create :project, :public
|
|
milestone = create :milestone, project: project
|
|
issue_x = create :issue, project: project, milestone: milestone
|
|
issue_y = create :issue, project: project, assignees: [user]
|
|
issue_z = create :issue, project: project
|
|
create :issue_link, source: issue_x, target: issue_y
|
|
create :issue_link, source: issue_x, target: issue_z
|
|
create :issue_link, source: issue_y, target: issue_z
|
|
|
|
expect { subject }.not_to exceed_query_limit(control_count)
|
|
end
|
|
|
|
it 'returns related issues JSON' do
|
|
expect(subject.size).to eq(3)
|
|
|
|
expect(subject).to include(include(id: issue_b.id,
|
|
title: issue_b.title,
|
|
state: issue_b.state,
|
|
reference: issue_b.to_reference(project),
|
|
path: "/#{project.full_path}/-/issues/#{issue_b.iid}",
|
|
relation_path: "/#{project.full_path}/-/issues/#{issue.iid}/links/#{issue_link_a.id}"))
|
|
|
|
expect(subject).to include(include(id: issue_c.id,
|
|
title: issue_c.title,
|
|
state: issue_c.state,
|
|
reference: issue_c.to_reference(project),
|
|
path: "/#{project.full_path}/-/issues/#{issue_c.iid}",
|
|
relation_path: "/#{project.full_path}/-/issues/#{issue.iid}/links/#{issue_link_b.id}"))
|
|
|
|
expect(subject).to include(include(id: issue_d.id,
|
|
title: issue_d.title,
|
|
state: issue_d.state,
|
|
reference: issue_d.to_reference(project),
|
|
path: "/#{project.full_path}/-/issues/#{issue_d.iid}",
|
|
relation_path: "/#{project.full_path}/-/issues/#{issue.iid}/links/#{issue_link_c.id}"))
|
|
end
|
|
end
|
|
|
|
context 'referencing a public project issue' do
|
|
let(:public_project) { create :project, :public }
|
|
let(:issue_b) { create :issue, project: public_project }
|
|
|
|
let!(:issue_link) do
|
|
create(:issue_link, source: issue, target: issue_b)
|
|
end
|
|
|
|
it 'presents issue' do
|
|
expect(subject.size).to eq(1)
|
|
end
|
|
end
|
|
|
|
context 'referencing issue with removed relationships' do
|
|
context 'when referenced a deleted issue' do
|
|
let(:issue_b) { create :issue, project: project }
|
|
let!(:issue_link) do
|
|
create(:issue_link, source: issue, target: issue_b)
|
|
end
|
|
|
|
it 'ignores issue' do
|
|
issue_b.destroy!
|
|
|
|
is_expected.to eq([])
|
|
end
|
|
end
|
|
|
|
context 'when referenced an issue with deleted project' do
|
|
let(:issue_b) { create :issue, project: project }
|
|
let!(:issue_link) do
|
|
create(:issue_link, source: issue, target: issue_b)
|
|
end
|
|
|
|
it 'ignores issue' do
|
|
project.destroy!
|
|
|
|
is_expected.to eq([])
|
|
end
|
|
end
|
|
|
|
context 'when referenced an issue with deleted namespace' do
|
|
let(:issue_b) { create :issue, project: project }
|
|
let!(:issue_link) do
|
|
create(:issue_link, source: issue, target: issue_b)
|
|
end
|
|
|
|
it 'ignores issue' do
|
|
project.namespace.destroy!
|
|
|
|
is_expected.to eq([])
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'user cannot see relations' do
|
|
context 'when user cannot see the referenced issue' do
|
|
let!(:issue_link) do
|
|
create(:issue_link, source: issue)
|
|
end
|
|
|
|
it 'returns an empty list' do
|
|
is_expected.to eq([])
|
|
end
|
|
end
|
|
|
|
context 'when user cannot see the issue that referenced' do
|
|
let!(:issue_link) do
|
|
create(:issue_link, target: issue)
|
|
end
|
|
|
|
it 'returns an empty list' do
|
|
is_expected.to eq([])
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'remove relations' do
|
|
let!(:issue_link) do
|
|
create(:issue_link, source: issue, target: referenced_issue)
|
|
end
|
|
|
|
context 'user can admin related issues just on target project' do
|
|
let(:user_role) { :guest }
|
|
let(:target_project) { create :project }
|
|
let(:referenced_issue) { create :issue, project: target_project }
|
|
|
|
it 'returns no destroy relation path' do
|
|
target_project.add_developer(user)
|
|
|
|
expect(subject.first[:relation_path]).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'user can admin related issues just on source project' do
|
|
let(:user_role) { :developer }
|
|
let(:target_project) { create :project }
|
|
let(:referenced_issue) { create :issue, project: target_project }
|
|
|
|
it 'returns no destroy relation path' do
|
|
target_project.add_guest(user)
|
|
|
|
expect(subject.first[:relation_path]).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'when user can admin related issues on both projects' do
|
|
let(:referenced_issue) { create :issue, project: project }
|
|
|
|
it 'returns related issue destroy relation path' do
|
|
expect(subject.first[:relation_path])
|
|
.to eq("/#{project.full_path}/-/issues/#{issue.iid}/links/#{issue_link.id}")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|