Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 18:40:28 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 18:40:28 +0300
commitb595cb0c1dec83de5bdee18284abe86614bed33b (patch)
tree8c3d4540f193c5ff98019352f554e921b3a41a72 /spec/services/issues
parent2f9104a328fc8a4bddeaa4627b595166d24671d0 (diff)
Add latest changes from gitlab-org/gitlab@15-2-stable-eev15.2.0-rc42
Diffstat (limited to 'spec/services/issues')
-rw-r--r--spec/services/issues/clone_service_spec.rb51
-rw-r--r--spec/services/issues/close_service_spec.rb17
-rw-r--r--spec/services/issues/create_service_spec.rb25
-rw-r--r--spec/services/issues/import_csv_service_spec.rb24
-rw-r--r--spec/services/issues/move_service_spec.rb1
-rw-r--r--spec/services/issues/related_branches_service_spec.rb93
-rw-r--r--spec/services/issues/reopen_service_spec.rb33
-rw-r--r--spec/services/issues/update_service_spec.rb21
8 files changed, 158 insertions, 107 deletions
diff --git a/spec/services/issues/clone_service_spec.rb b/spec/services/issues/clone_service_spec.rb
index abbcb1c1d48..858dfc4ab3a 100644
--- a/spec/services/issues/clone_service_spec.rb
+++ b/spec/services/issues/clone_service_spec.rb
@@ -82,12 +82,14 @@ RSpec.describe Issues::CloneService do
expect(new_issue.iid).to be_present
end
- it 'preserves create time' do
- expect(old_issue.created_at.strftime('%D')).to eq new_issue.created_at.strftime('%D')
- end
+ it 'sets created_at of new issue to the time of clone' do
+ future_time = 5.days.from_now
- it 'does not copy system notes' do
- expect(new_issue.notes.count).to eq(1)
+ travel_to(future_time) do
+ new_issue = clone_service.execute(old_issue, new_project, with_notes: with_notes)
+
+ expect(new_issue.created_at).to be_like_time(future_time)
+ end
end
it 'does not set moved_issue' do
@@ -105,6 +107,24 @@ RSpec.describe Issues::CloneService do
end
end
+ context 'issue with system notes and resource events' do
+ before do
+ create(:note, :system, noteable: old_issue, project: old_project)
+ create(:resource_label_event, label: create(:label, project: old_project), issue: old_issue)
+ create(:resource_state_event, issue: old_issue, state: :reopened)
+ create(:resource_milestone_event, issue: old_issue, action: 'remove', milestone_id: nil)
+ end
+
+ it 'does not copy system notes and resource events' do
+ new_issue = clone_service.execute(old_issue, new_project)
+
+ # 1 here is for the "cloned from" system note
+ expect(new_issue.notes.count).to eq(1)
+ expect(new_issue.resource_state_events).to be_empty
+ expect(new_issue.resource_milestone_events).to be_empty
+ end
+ end
+
context 'issue with award emoji' do
let!(:award_emoji) { create(:award_emoji, awardable: old_issue) }
@@ -124,14 +144,27 @@ RSpec.describe Issues::CloneService do
create(:issue, title: title, description: description, project: old_project, author: author, milestone: milestone)
end
- before do
- create(:resource_milestone_event, issue: old_issue, milestone: milestone, action: :add)
+ it 'copies the milestone and creates a resource_milestone_event' do
+ new_issue = clone_service.execute(old_issue, new_project)
+
+ expect(new_issue.milestone).to eq(milestone)
+ expect(new_issue.resource_milestone_events.count).to eq(1)
+ end
+ end
+
+ context 'issue with label' do
+ let(:label) { create(:group_label, group: sub_group_1) }
+ let(:new_project) { create(:project, namespace: sub_group_1) }
+
+ let(:old_issue) do
+ create(:issue, project: old_project, labels: [label])
end
- it 'does not create extra milestone events' do
+ it 'copies the label and creates a resource_label_event' do
new_issue = clone_service.execute(old_issue, new_project)
- expect(new_issue.resource_milestone_events.count).to eq(old_issue.resource_milestone_events.count)
+ expect(new_issue.labels).to contain_exactly(label)
+ expect(new_issue.resource_label_events.count).to eq(1)
end
end
diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb
index 344da5a6582..e88fe1b42f0 100644
--- a/spec/services/issues/close_service_spec.rb
+++ b/spec/services/issues/close_service_spec.rb
@@ -122,14 +122,29 @@ RSpec.describe Issues::CloseService do
expect(new_note.author).to eq(user)
end
+ it 'adds a timeline event', :aggregate_failures do
+ expect(IncidentManagement::TimelineEvents::CreateService)
+ .to receive(:resolve_incident)
+ .with(issue, user)
+ .and_call_original
+
+ expect { service.execute(issue) }.to change { issue.incident_management_timeline_events.count }.by(1)
+ end
+
context 'when the escalation status did not change to resolved' do
let(:escalation_status) { instance_double('IncidentManagement::IssuableEscalationStatus', resolve: false) }
- it 'does not create a system note' do
+ before do
allow(issue).to receive(:incident_management_issuable_escalation_status).and_return(escalation_status)
+ end
+ it 'does not create a system note' do
expect { service.execute(issue) }.not_to change { issue.notes.count }
end
+
+ it 'does not create a timeline event' do
+ expect { service.execute(issue) }.not_to change { issue.incident_management_timeline_events.count }
+ end
end
end
end
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index 9f006603f29..0bc8511e3e3 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -135,6 +135,14 @@ RSpec.describe Issues::CreateService do
issue
end
+ it 'calls IncidentManagement::TimelineEvents::CreateService.create_incident' do
+ expect(IncidentManagement::TimelineEvents::CreateService)
+ .to receive(:create_incident)
+ .with(a_kind_of(Issue), reporter)
+
+ issue
+ end
+
context 'when invalid' do
before do
opts.merge!(title: '')
@@ -489,6 +497,23 @@ RSpec.describe Issues::CreateService do
end
end
end
+
+ context 'with alert bot author' do
+ let_it_be(:user) { User.alert_bot }
+ let_it_be(:label) { create(:label, project: project) }
+
+ let(:opts) do
+ {
+ title: 'Title',
+ description: %(/label #{label.to_reference(format: :name)}")
+ }
+ end
+
+ it 'can apply labels' do
+ expect(issue).to be_persisted
+ expect(issue.labels).to eq([label])
+ end
+ end
end
context 'resolving discussions' do
diff --git a/spec/services/issues/import_csv_service_spec.rb b/spec/services/issues/import_csv_service_spec.rb
index fa40b75190f..9ad1d7dba9f 100644
--- a/spec/services/issues/import_csv_service_spec.rb
+++ b/spec/services/issues/import_csv_service_spec.rb
@@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe Issues::ImportCsvService do
let(:project) { create(:project) }
let(:user) { create(:user) }
+ let(:assignee) { create(:user, username: 'csv_assignee') }
let(:service) do
uploader = FileUploader.new(project)
uploader.store!(file)
@@ -16,4 +17,27 @@ RSpec.describe Issues::ImportCsvService do
let(:issuables) { project.issues }
let(:email_method) { :import_issues_csv_email }
end
+
+ describe '#execute' do
+ let(:file) { fixture_file_upload('spec/fixtures/csv_complex.csv') }
+
+ subject { service.execute }
+
+ it 'sets all issueable attributes and executes quick actions' do
+ project.add_developer(user)
+ project.add_developer(assignee)
+
+ expect { subject }.to change { issuables.count }.by 3
+
+ expect(issuables.reload).to include(
+ have_attributes(
+ title: 'Title with quote"',
+ description: 'Description',
+ time_estimate: 3600,
+ assignees: include(assignee),
+ due_date: Date.new(2022, 6, 28)
+ )
+ )
+ end
+ end
end
diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb
index 56a3c22cd7f..5a1bb2e8b74 100644
--- a/spec/services/issues/move_service_spec.rb
+++ b/spec/services/issues/move_service_spec.rb
@@ -47,6 +47,7 @@ RSpec.describe Issues::MoveService do
it 'creates a new issue in a new project' do
expect(new_issue.project).to eq new_project
+ expect(new_issue.namespace_id).to eq new_project.project_namespace_id
end
it 'copies issue title' do
diff --git a/spec/services/issues/related_branches_service_spec.rb b/spec/services/issues/related_branches_service_spec.rb
index 7a4bae7f852..95d456c1b05 100644
--- a/spec/services/issues/related_branches_service_spec.rb
+++ b/spec/services/issues/related_branches_service_spec.rb
@@ -3,88 +3,47 @@
require 'spec_helper'
RSpec.describe Issues::RelatedBranchesService do
+ let_it_be(:project) { create(:project, :repository, :public, public_builds: false) }
let_it_be(:developer) { create(:user) }
- let_it_be(:issue) { create(:issue) }
+ let_it_be(:issue) { create(:issue, project: project) }
let(:user) { developer }
- subject { described_class.new(project: issue.project, current_user: user) }
+ subject { described_class.new(project: project, current_user: user) }
- before do
- issue.project.add_developer(developer)
+ before_all do
+ 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
+ let_it_be(:pipeline) { create(:ci_pipeline, :success, project: project, ref: issue.to_branch_name) }
- 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(:latest_pipeline).with(name, sha).and_return(pipeline)
- end
+ before_all do
+ project.repository.create_branch(issue.to_branch_name, pipeline.sha)
+ project.repository.create_branch("#{issue.iid}doesnt-match", project.repository.root_ref)
+ project.repository.create_branch("#{issue.iid}-0-stable", project.repository.root_ref)
- allow(repo).to receive(:find_branch).with(missing_branch).and_return(nil)
+ project.repository.add_tag(developer, issue.to_branch_name, pipeline.sha)
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 }
- )
+ context 'when user has access to pipelines' do
+ it 'selects relevant branches, along with pipeline status' do
+ expect(branch_info).to contain_exactly(
+ { name: issue.to_branch_name, pipeline_status: an_instance_of(Gitlab::Ci::Status::Success) }
+ )
+ end
end
- context 'the user has access to otherwise unreadable pipelines' do
- let(:user) { create(:admin) }
+ context 'when user does not have access to pipelines' do
+ let(:user) { create(:user) }
- context 'when admin mode is enabled', :enable_admin_mode do
- 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
-
- context 'when admin mode is disabled' do
- it 'does not return info a developer could not see' do
- expect(branch_info.pluck(:pipeline_status)).not_to include(an_instance_of(Gitlab::Ci::Status::Running))
- end
+ it 'returns branches without pipeline status' do
+ expect(branch_info).to contain_exactly(
+ { name: issue.to_branch_name, pipeline_status: nil }
+ )
end
end
@@ -103,10 +62,10 @@ RSpec.describe Issues::RelatedBranchesService do
end
end
- context 'one of the branches is stable' do
- let(:branch_names) { ["#{issue.iid}-0-stable"] }
+ context 'no branches are available' do
+ let(:project) { create(:project, :empty_repo) }
- it 'is excluded' do
+ it 'returns an empty array' do
expect(branch_info).to be_empty
end
end
diff --git a/spec/services/issues/reopen_service_spec.rb b/spec/services/issues/reopen_service_spec.rb
index c9469b861ac..477b44f4c2c 100644
--- a/spec/services/issues/reopen_service_spec.rb
+++ b/spec/services/issues/reopen_service_spec.rb
@@ -33,6 +33,8 @@ RSpec.describe Issues::ReopenService do
context 'when user is authorized to reopen issue' do
let(:user) { create(:user) }
+ subject(:execute) { described_class.new(project: project, current_user: user).execute(issue) }
+
before do
project.add_maintainer(user)
end
@@ -41,14 +43,12 @@ RSpec.describe Issues::ReopenService do
issue.assignees << user
expect_any_instance_of(User).to receive(:invalidate_issue_cache_counts)
- described_class.new(project: project, current_user: user).execute(issue)
+ execute
end
it 'refreshes the number of opened issues' do
- service = described_class.new(project: project, current_user: user)
-
expect do
- service.execute(issue)
+ execute
BatchLoader::Executor.clear_current
end.to change { project.open_issues_count }.from(0).to(1)
@@ -61,16 +61,27 @@ RSpec.describe Issues::ReopenService do
expect(service).to receive(:delete_cache).and_call_original
end
- described_class.new(project: project, current_user: user).execute(issue)
+ execute
+ end
+
+ it 'does not create timeline event' do
+ expect { execute }.not_to change { issue.incident_management_timeline_events.count }
end
context 'issue is incident type' do
let(:issue) { create(:incident, :closed, project: project) }
let(:current_user) { user }
- subject { described_class.new(project: project, current_user: user).execute(issue) }
-
it_behaves_like 'an incident management tracked event', :incident_management_incident_reopened
+
+ it 'creates a timeline event' do
+ expect(IncidentManagement::TimelineEvents::CreateService)
+ .to receive(:reopen_incident)
+ .with(issue, current_user)
+ .and_call_original
+
+ expect { execute }.to change { issue.incident_management_timeline_events.count }.by(1)
+ end
end
context 'when issue is not confidential' do
@@ -78,18 +89,18 @@ RSpec.describe Issues::ReopenService do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks)
expect(project).to receive(:execute_integrations).with(an_instance_of(Hash), :issue_hooks)
- described_class.new(project: project, current_user: user).execute(issue)
+ execute
end
end
context 'when issue is confidential' do
- it 'executes confidential issue hooks' do
- issue = create(:issue, :confidential, :closed, project: project)
+ let(:issue) { create(:issue, :confidential, :closed, project: project) }
+ it 'executes confidential issue hooks' do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :confidential_issue_hooks)
expect(project).to receive(:execute_integrations).with(an_instance_of(Hash), :confidential_issue_hooks)
- described_class.new(project: project, current_user: user).execute(issue)
+ execute
end
end
end
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index d11fe772023..e2e8828ae89 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -1146,11 +1146,11 @@ RSpec.describe Issues::UpdateService, :mailer do
let(:opts) { { escalation_status: { status: 'acknowledged' } } }
let(:escalation_update_class) { ::IncidentManagement::IssuableEscalationStatuses::AfterUpdateService }
- shared_examples 'updates the escalation status record' do |expected_status, expected_reason = nil|
+ shared_examples 'updates the escalation status record' do |expected_status|
let(:service_double) { instance_double(escalation_update_class) }
it 'has correct value' do
- expect(escalation_update_class).to receive(:new).with(issue, user, status_change_reason: expected_reason).and_return(service_double)
+ expect(escalation_update_class).to receive(:new).with(issue, user).and_return(service_double)
expect(service_double).to receive(:execute)
update_issue(opts)
@@ -1193,23 +1193,6 @@ RSpec.describe Issues::UpdateService, :mailer do
it_behaves_like 'updates the escalation status record', :acknowledged
- context 'with associated alert' do
- let!(:alert) { create(:alert_management_alert, issue: issue, project: project) }
-
- it 'syncs the update back to the alert' do
- update_issue(opts)
-
- expect(issue.escalation_status.status_name).to eq(:acknowledged)
- expect(alert.reload.status_name).to eq(:acknowledged)
- end
- end
-
- context 'with a status change reason provided' do
- let(:opts) { { escalation_status: { status: 'acknowledged', status_change_reason: ' by changing the alert status' } } }
-
- it_behaves_like 'updates the escalation status record', :acknowledged, ' by changing the alert status'
- end
-
context 'with unsupported status value' do
let(:opts) { { escalation_status: { status: 'unsupported-status' } } }