2019-07-31 22:56:46 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2016-06-02 11:05:42 +05:30
|
|
|
require 'spec_helper'
|
|
|
|
|
2023-05-27 22:25:52 +05:30
|
|
|
RSpec.describe Projects::AutocompleteService, feature_category: :projects do
|
2016-06-02 11:05:42 +05:30
|
|
|
describe '#issues' do
|
|
|
|
describe 'confidential issues' do
|
|
|
|
let(:author) { create(:user) }
|
|
|
|
let(:assignee) { create(:user) }
|
|
|
|
let(:non_member) { create(:user) }
|
|
|
|
let(:member) { create(:user) }
|
|
|
|
let(:admin) { create(:admin) }
|
2017-09-10 17:25:29 +05:30
|
|
|
let(:project) { create(:project, :public) }
|
2016-06-02 11:05:42 +05:30
|
|
|
let!(:issue) { create(:issue, project: project, title: 'Issue 1') }
|
|
|
|
let!(:security_issue_1) { create(:issue, :confidential, project: project, title: 'Security issue 1', author: author) }
|
2017-08-17 22:00:37 +05:30
|
|
|
let!(:security_issue_2) { create(:issue, :confidential, title: 'Security issue 2', project: project, assignees: [assignee]) }
|
2016-06-02 11:05:42 +05:30
|
|
|
|
2016-09-13 17:45:13 +05:30
|
|
|
it 'does not list project confidential issues for guests' do
|
2016-06-02 11:05:42 +05:30
|
|
|
autocomplete = described_class.new(project, nil)
|
|
|
|
issues = autocomplete.issues.map(&:iid)
|
|
|
|
|
|
|
|
expect(issues).to include issue.iid
|
|
|
|
expect(issues).not_to include security_issue_1.iid
|
|
|
|
expect(issues).not_to include security_issue_2.iid
|
|
|
|
expect(issues.count).to eq 1
|
|
|
|
end
|
|
|
|
|
2016-09-13 17:45:13 +05:30
|
|
|
it 'does not list project confidential issues for non project members' do
|
2016-06-02 11:05:42 +05:30
|
|
|
autocomplete = described_class.new(project, non_member)
|
|
|
|
issues = autocomplete.issues.map(&:iid)
|
|
|
|
|
|
|
|
expect(issues).to include issue.iid
|
|
|
|
expect(issues).not_to include security_issue_1.iid
|
|
|
|
expect(issues).not_to include security_issue_2.iid
|
|
|
|
expect(issues.count).to eq 1
|
|
|
|
end
|
|
|
|
|
2016-09-13 17:45:13 +05:30
|
|
|
it 'does not list project confidential issues for project members with guest role' do
|
2018-03-17 18:26:18 +05:30
|
|
|
project.add_guest(member)
|
2016-06-16 23:09:34 +05:30
|
|
|
|
|
|
|
autocomplete = described_class.new(project, non_member)
|
|
|
|
issues = autocomplete.issues.map(&:iid)
|
|
|
|
|
|
|
|
expect(issues).to include issue.iid
|
|
|
|
expect(issues).not_to include security_issue_1.iid
|
|
|
|
expect(issues).not_to include security_issue_2.iid
|
|
|
|
expect(issues.count).to eq 1
|
|
|
|
end
|
|
|
|
|
2016-09-13 17:45:13 +05:30
|
|
|
it 'lists project confidential issues for author' do
|
2016-06-02 11:05:42 +05:30
|
|
|
autocomplete = described_class.new(project, author)
|
|
|
|
issues = autocomplete.issues.map(&:iid)
|
|
|
|
|
|
|
|
expect(issues).to include issue.iid
|
|
|
|
expect(issues).to include security_issue_1.iid
|
|
|
|
expect(issues).not_to include security_issue_2.iid
|
|
|
|
expect(issues.count).to eq 2
|
|
|
|
end
|
|
|
|
|
2016-09-13 17:45:13 +05:30
|
|
|
it 'lists project confidential issues for assignee' do
|
2016-06-02 11:05:42 +05:30
|
|
|
autocomplete = described_class.new(project, assignee)
|
|
|
|
issues = autocomplete.issues.map(&:iid)
|
|
|
|
|
|
|
|
expect(issues).to include issue.iid
|
|
|
|
expect(issues).not_to include security_issue_1.iid
|
|
|
|
expect(issues).to include security_issue_2.iid
|
|
|
|
expect(issues.count).to eq 2
|
|
|
|
end
|
|
|
|
|
2016-09-13 17:45:13 +05:30
|
|
|
it 'lists project confidential issues for project members' do
|
2018-03-17 18:26:18 +05:30
|
|
|
project.add_developer(member)
|
2016-06-02 11:05:42 +05:30
|
|
|
|
|
|
|
autocomplete = described_class.new(project, member)
|
|
|
|
issues = autocomplete.issues.map(&:iid)
|
|
|
|
|
|
|
|
expect(issues).to include issue.iid
|
|
|
|
expect(issues).to include security_issue_1.iid
|
|
|
|
expect(issues).to include security_issue_2.iid
|
|
|
|
expect(issues.count).to eq 3
|
|
|
|
end
|
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
context 'when admin mode is enabled', :enable_admin_mode do
|
|
|
|
it 'lists all project issues for admin', :enable_admin_mode do
|
|
|
|
autocomplete = described_class.new(project, admin)
|
|
|
|
issues = autocomplete.issues.map(&:iid)
|
|
|
|
|
|
|
|
expect(issues).to include issue.iid
|
|
|
|
expect(issues).to include security_issue_1.iid
|
|
|
|
expect(issues).to include security_issue_2.iid
|
|
|
|
expect(issues.count).to eq 3
|
|
|
|
end
|
|
|
|
end
|
2016-06-02 11:05:42 +05:30
|
|
|
|
2021-01-29 00:20:46 +05:30
|
|
|
context 'when admin mode is disabled' do
|
|
|
|
it 'does not list project confidential issues for admin' do
|
|
|
|
autocomplete = described_class.new(project, admin)
|
|
|
|
issues = autocomplete.issues.map(&:iid)
|
|
|
|
|
|
|
|
expect(issues).to include issue.iid
|
|
|
|
expect(issues).not_to include security_issue_1.iid
|
|
|
|
expect(issues).not_to include security_issue_2.iid
|
|
|
|
expect(issues.count).to eq 1
|
|
|
|
end
|
2016-06-02 11:05:42 +05:30
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-09-10 17:25:29 +05:30
|
|
|
|
|
|
|
describe '#milestones' do
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
let(:group) { create(:group) }
|
|
|
|
let(:project) { create(:project, group: group) }
|
2018-03-17 18:26:18 +05:30
|
|
|
let!(:group_milestone1) { create(:milestone, group: group, due_date: '2017-01-01', title: 'Second Title') }
|
|
|
|
let!(:group_milestone2) { create(:milestone, group: group, due_date: '2017-01-01', title: 'First Title') }
|
|
|
|
let!(:project_milestone) { create(:milestone, project: project, due_date: '2016-01-01') }
|
2017-09-10 17:25:29 +05:30
|
|
|
|
|
|
|
let(:milestone_titles) { described_class.new(project, user).milestones.map(&:title) }
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
it 'includes project and group milestones and sorts them correctly' do
|
|
|
|
expect(milestone_titles).to eq([project_milestone.title, group_milestone2.title, group_milestone1.title])
|
2017-09-10 17:25:29 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not include closed milestones' do
|
2018-03-17 18:26:18 +05:30
|
|
|
group_milestone1.close
|
2017-09-10 17:25:29 +05:30
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
expect(milestone_titles).to eq([project_milestone.title, group_milestone2.title])
|
2017-09-10 17:25:29 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'does not include milestones from other projects in the group' do
|
|
|
|
other_project = create(:project, group: group)
|
|
|
|
project_milestone.update!(project: other_project)
|
|
|
|
|
2018-03-17 18:26:18 +05:30
|
|
|
expect(milestone_titles).to eq([group_milestone2.title, group_milestone1.title])
|
2017-09-10 17:25:29 +05:30
|
|
|
end
|
2018-11-08 19:23:39 +05:30
|
|
|
|
2019-10-12 21:52:04 +05:30
|
|
|
context 'with nested groups' do
|
2018-11-08 19:23:39 +05:30
|
|
|
let(:subgroup) { create(:group, :public, parent: group) }
|
|
|
|
let!(:subgroup_milestone) { create(:milestone, group: subgroup) }
|
|
|
|
|
|
|
|
before do
|
2021-01-03 14:25:43 +05:30
|
|
|
project.update!(namespace: subgroup)
|
2018-11-08 19:23:39 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
it 'includes project milestones and all acestors milestones' do
|
|
|
|
expect(milestone_titles).to match_array(
|
|
|
|
[project_milestone.title, group_milestone2.title, group_milestone1.title, subgroup_milestone.title]
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
describe '#contacts' do
|
|
|
|
let_it_be(:user) { create(:user) }
|
|
|
|
let_it_be(:group) { create(:group, :crm_enabled) }
|
|
|
|
let_it_be(:project) { create(:project, group: group) }
|
|
|
|
let_it_be(:contact_1) { create(:contact, group: group) }
|
|
|
|
let_it_be(:contact_2) { create(:contact, group: group) }
|
2022-11-25 23:54:43 +05:30
|
|
|
let_it_be(:contact_3) { create(:contact, :inactive, group: group) }
|
2022-04-04 11:22:00 +05:30
|
|
|
|
2022-11-25 23:54:43 +05:30
|
|
|
let(:issue) { nil }
|
|
|
|
|
|
|
|
subject { described_class.new(project, user).contacts(issue).as_json }
|
2022-04-04 11:22:00 +05:30
|
|
|
|
|
|
|
before do
|
|
|
|
group.add_developer(user)
|
|
|
|
end
|
|
|
|
|
2022-11-25 23:54:43 +05:30
|
|
|
it 'returns CRM contacts from group' do
|
2022-04-04 11:22:00 +05:30
|
|
|
expected_contacts = [
|
|
|
|
{ 'id' => contact_1.id, 'email' => contact_1.email,
|
2022-11-25 23:54:43 +05:30
|
|
|
'first_name' => contact_1.first_name, 'last_name' => contact_1.last_name, 'state' => contact_1.state },
|
2022-04-04 11:22:00 +05:30
|
|
|
{ 'id' => contact_2.id, 'email' => contact_2.email,
|
2022-11-25 23:54:43 +05:30
|
|
|
'first_name' => contact_2.first_name, 'last_name' => contact_2.last_name, 'state' => contact_2.state },
|
|
|
|
{ 'id' => contact_3.id, 'email' => contact_3.email,
|
|
|
|
'first_name' => contact_3.first_name, 'last_name' => contact_3.last_name, 'state' => contact_3.state }
|
2022-04-04 11:22:00 +05:30
|
|
|
]
|
|
|
|
|
|
|
|
expect(subject).to match_array(expected_contacts)
|
|
|
|
end
|
2022-11-25 23:54:43 +05:30
|
|
|
|
|
|
|
context 'some contacts are already assigned to the issue' do
|
|
|
|
let(:issue) { create(:issue, project: project) }
|
|
|
|
|
|
|
|
before do
|
|
|
|
issue.customer_relations_contacts << [contact_2, contact_3]
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'marks already assigned contacts as set' do
|
|
|
|
expected_contacts = [
|
|
|
|
{ 'id' => contact_1.id, 'email' => contact_1.email,
|
|
|
|
'first_name' => contact_1.first_name, 'last_name' => contact_1.last_name, 'state' => contact_1.state, 'set' => false },
|
|
|
|
{ 'id' => contact_2.id, 'email' => contact_2.email,
|
|
|
|
'first_name' => contact_2.first_name, 'last_name' => contact_2.last_name, 'state' => contact_2.state, 'set' => true },
|
|
|
|
{ 'id' => contact_3.id, 'email' => contact_3.email,
|
|
|
|
'first_name' => contact_3.first_name, 'last_name' => contact_3.last_name, 'state' => contact_3.state, 'set' => true }
|
|
|
|
]
|
|
|
|
|
|
|
|
expect(subject).to match_array(expected_contacts)
|
|
|
|
end
|
|
|
|
end
|
2022-04-04 11:22:00 +05:30
|
|
|
end
|
|
|
|
|
2018-11-08 19:23:39 +05:30
|
|
|
describe '#labels_as_hash' do
|
|
|
|
def expect_labels_to_equal(labels, expected_labels)
|
|
|
|
expect(labels.size).to eq(expected_labels.size)
|
|
|
|
extract_title = lambda { |label| label['title'] }
|
2021-01-03 14:25:43 +05:30
|
|
|
expect(labels.map(&extract_title)).to match_array(expected_labels.map(&extract_title))
|
2018-11-08 19:23:39 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
let(:user) { create(:user) }
|
|
|
|
let(:group) { create(:group, :nested) }
|
|
|
|
let!(:sub_group) { create(:group, parent: group) }
|
|
|
|
let(:project) { create(:project, :public, group: group) }
|
|
|
|
let(:issue) { create(:issue, project: project) }
|
|
|
|
|
|
|
|
let!(:label1) { create(:label, project: project) }
|
|
|
|
let!(:label2) { create(:label, project: project) }
|
|
|
|
let!(:sub_group_label) { create(:group_label, group: sub_group) }
|
2018-12-05 23:21:45 +05:30
|
|
|
let!(:parent_group_label) { create(:group_label, group: group.parent, group_id: group.id) }
|
2018-11-08 19:23:39 +05:30
|
|
|
|
|
|
|
before do
|
|
|
|
create(:group_member, group: group, user: user)
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'returns labels from project and ancestor groups' do
|
|
|
|
service = described_class.new(project, user)
|
2018-12-05 23:21:45 +05:30
|
|
|
results = service.labels_as_hash(nil)
|
2018-11-08 19:23:39 +05:30
|
|
|
expected_labels = [label1, label2, parent_group_label]
|
|
|
|
|
|
|
|
expect_labels_to_equal(results, expected_labels)
|
|
|
|
end
|
|
|
|
|
|
|
|
context 'some labels are already assigned' do
|
|
|
|
before do
|
|
|
|
issue.labels << label1
|
|
|
|
end
|
|
|
|
|
|
|
|
it 'marks already assigned as set' do
|
|
|
|
service = described_class.new(project, user)
|
|
|
|
results = service.labels_as_hash(issue)
|
|
|
|
expected_labels = [label1, label2, parent_group_label]
|
|
|
|
|
|
|
|
expect_labels_to_equal(results, expected_labels)
|
|
|
|
|
|
|
|
assigned_label_titles = issue.labels.map(&:title)
|
|
|
|
results.each do |hash|
|
|
|
|
if assigned_label_titles.include?(hash['title'])
|
|
|
|
expect(hash[:set]).to eq(true)
|
|
|
|
else
|
|
|
|
expect(hash.key?(:set)).to eq(false)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2017-09-10 17:25:29 +05:30
|
|
|
end
|
2016-06-02 11:05:42 +05:30
|
|
|
end
|