diff options
Diffstat (limited to 'spec/services/system_notes')
3 files changed, 223 insertions, 63 deletions
diff --git a/spec/services/system_notes/issuables_service_spec.rb b/spec/services/system_notes/issuables_service_spec.rb index 5bc7ea82976..b2ccd9dba52 100644 --- a/spec/services/system_notes/issuables_service_spec.rb +++ b/spec/services/system_notes/issuables_service_spec.rb @@ -247,42 +247,6 @@ RSpec.describe ::SystemNotes::IssuablesService do end end - describe '#request_attention' do - subject { service.request_attention(user) } - - let(:user) { create(:user) } - - it_behaves_like 'a system note' do - let(:action) { 'attention_requested' } - end - - context 'when attention requested' do - it_behaves_like 'a note with overridable created_at' - - it 'sets the note text' do - expect(subject.note).to eq "requested attention from @#{user.username}" - end - end - end - - describe '#remove_attention_request' do - subject { service.remove_attention_request(user) } - - let(:user) { create(:user) } - - it_behaves_like 'a system note' do - let(:action) { 'attention_request_removed' } - end - - context 'when attention request is removed' do - it_behaves_like 'a note with overridable created_at' - - it 'sets the note text' do - expect(subject.note).to eq "removed attention request from @#{user.username}" - end - end - end - describe '#change_title' do let(:noteable) { create(:issue, project: project, title: 'Lorem ipsum') } @@ -559,8 +523,8 @@ RSpec.describe ::SystemNotes::IssuablesService do let(:action) { 'task' } end - it "posts the 'marked the task as complete' system note" do - expect(subject.note).to eq("marked the task **task** as completed") + it "posts the 'marked the checklist item as complete' system note" do + expect(subject.note).to eq("marked the checklist item **task** as completed") end end @@ -625,8 +589,8 @@ RSpec.describe ::SystemNotes::IssuablesService do end describe '#noteable_cloned' do - let(:new_project) { create(:project) } - let(:new_noteable) { create(:issue, project: new_project) } + let_it_be(:new_project) { create(:project) } + let_it_be(:new_noteable) { create(:issue, project: new_project) } subject do service.noteable_cloned(new_noteable, direction) @@ -684,6 +648,22 @@ RSpec.describe ::SystemNotes::IssuablesService do end end + context 'custom created timestamp' do + let(:direction) { :from } + + it 'allows setting of custom created_at value' do + timestamp = 1.day.ago + + note = service.noteable_cloned(new_noteable, direction, created_at: timestamp) + + expect(note.created_at).to be_like_time(timestamp) + end + + it 'defaults to current time when created_at is not given', :freeze_time do + expect(subject.created_at).to be_like_time(Time.current) + end + end + context 'metrics' do context 'cloned from' do let(:direction) { :from } @@ -696,15 +676,20 @@ RSpec.describe ::SystemNotes::IssuablesService do end end - context 'cloned to' do + context 'cloned to', :snowplow do let(:direction) { :to } it 'tracks usage' do expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter) - .to receive(:track_issue_cloned_action).with(author: author) + .to receive(:track_issue_cloned_action).with(author: author, project: project ) subject end + + it_behaves_like 'issue_edit snowplow tracking' do + let(:property) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CLONED } + let(:user) { author } + end end end end @@ -886,4 +871,43 @@ RSpec.describe ::SystemNotes::IssuablesService do it { expect(subject.note).to eq "changed issue type to incident" } end + + describe '#hierarchy_changed' do + let_it_be_with_reload(:work_item) { create(:work_item, project: project) } + let_it_be_with_reload(:task) { create(:work_item, :task, project: project) } + + let(:service) { described_class.new(noteable: work_item, project: project, author: author) } + + subject { service.hierarchy_changed(task, hierarchy_change_action) } + + context 'when task is added as a child' do + let(:hierarchy_change_action) { 'relate' } + + it_behaves_like 'a system note' do + let(:expected_noteable) { task } + let(:action) { 'relate_to_parent' } + end + + it 'sets the correct note text' do + expect { subject }.to change { Note.system.count }.by(2) + expect(work_item.notes.last.note).to eq("added ##{task.iid} as child task") + expect(task.notes.last.note).to eq("added ##{work_item.iid} as parent issue") + end + end + + context 'when child task is removed' do + let(:hierarchy_change_action) { 'unrelate' } + + it_behaves_like 'a system note' do + let(:expected_noteable) { task } + let(:action) { 'unrelate_from_parent' } + end + + it 'sets the correct note text' do + expect { subject }.to change { Note.system.count }.by(2) + expect(work_item.notes.last.note).to eq("removed child task ##{task.iid}") + expect(task.notes.last.note).to eq("removed parent issue ##{work_item.iid}") + end + end + end end diff --git a/spec/services/system_notes/merge_requests_service_spec.rb b/spec/services/system_notes/merge_requests_service_spec.rb index 58d2489f878..3e66ccef106 100644 --- a/spec/services/system_notes/merge_requests_service_spec.rb +++ b/spec/services/system_notes/merge_requests_service_spec.rb @@ -167,8 +167,8 @@ RSpec.describe ::SystemNotes::MergeRequestsService do end describe '.change_branch' do - let(:old_branch) { 'old_branch'} - let(:new_branch) { 'new_branch'} + let(:old_branch) { 'old_branch' } + let(:new_branch) { 'new_branch' } it_behaves_like 'a system note' do let(:action) { 'branch' } diff --git a/spec/services/system_notes/time_tracking_service_spec.rb b/spec/services/system_notes/time_tracking_service_spec.rb index fdf18f4f29a..33608deaa64 100644 --- a/spec/services/system_notes/time_tracking_service_spec.rb +++ b/spec/services/system_notes/time_tracking_service_spec.rb @@ -3,35 +3,112 @@ require 'spec_helper' RSpec.describe ::SystemNotes::TimeTrackingService do - let_it_be(:author) { create(:user) } - let_it_be(:project) { create(:project, :repository) } + let_it_be(:author) { create(:user) } + let_it_be(:project) { create(:project, :repository) } - describe '#change_due_date' do - subject { described_class.new(noteable: noteable, project: project, author: author).change_due_date(due_date) } + describe '#change_start_date_or_due_date' do + let_it_be(:issue) { create(:issue, project: project) } + let_it_be(:work_item) { create(:work_item, project: project) } - let(:due_date) { Date.today } + subject(:note) { described_class.new(noteable: noteable, project: project, author: author).change_start_date_or_due_date(changed_dates) } - context 'when noteable is an issue' do - let_it_be(:noteable) { create(:issue, project: project) } + let(:start_date) { Date.today } + let(:due_date) { 1.week.from_now.to_date } + let(:changed_dates) { { 'due_date' => [nil, due_date], 'start_date' => [nil, start_date] } } + shared_examples 'issuable getting date change notes' do it_behaves_like 'a note with overridable created_at' it_behaves_like 'a system note' do - let(:action) { 'due_date' } + let(:action) { 'start_date_or_due_date' } end - context 'when due date added' do - it 'sets the note text' do - expect(subject.note).to eq "changed due date to #{due_date.to_s(:long)}" + context 'when both dates are added' do + it 'sets the correct note message' do + expect(note.note).to eq("changed start date to #{start_date.to_s(:long)} and changed due date to #{due_date.to_s(:long)}") end end - context 'when due date removed' do - let(:due_date) { nil } + context 'when both dates are removed' do + let(:changed_dates) { { 'due_date' => [due_date, nil], 'start_date' => [start_date, nil] } } - it 'sets the note text' do - expect(subject.note).to eq 'removed due date' + before do + noteable.update!(start_date: start_date, due_date: due_date) + end + + it 'sets the correct note message' do + expect(note.note).to eq('removed start date and removed due date') + end + end + + context 'when due date is added' do + let(:changed_dates) { { 'due_date' => [nil, due_date] } } + + it 'sets the correct note message' do + expect(note.note).to eq("changed due date to #{due_date.to_s(:long)}") + end + + it 'tracks the issue event in usage ping' do + expect(activity_counter_class).to receive(activity_counter_method).with(author: author) + + subject end + + context 'and start date removed' do + let(:changed_dates) { { 'due_date' => [nil, due_date], 'start_date' => [start_date, nil] } } + + it 'sets the correct note message' do + expect(note.note).to eq("removed start date and changed due date to #{due_date.to_s(:long)}") + end + end + end + + context 'when start_date is added' do + let(:changed_dates) { { 'start_date' => [nil, start_date] } } + + it 'does not track the issue event in usage ping' do + expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).not_to receive(:track_issue_due_date_changed_action) + + subject + end + + it 'sets the correct note message' do + expect(note.note).to eq("changed start date to #{start_date.to_s(:long)}") + end + + context 'and due date removed' do + let(:changed_dates) { { 'due_date' => [due_date, nil], 'start_date' => [nil, start_date] } } + + it 'sets the correct note message' do + expect(note.note).to eq("changed start date to #{start_date.to_s(:long)} and removed due date") + end + end + end + + context 'when no dates are changed' do + let(:changed_dates) { {} } + + it 'does not create a note and returns nil' do + expect do + note + end.to not_change(Note, :count) + + expect(note).to be_nil + end + end + end + + context 'when noteable is an issue' do + let(:noteable) { issue } + let(:activity_counter_class) { Gitlab::UsageDataCounters::IssueActivityUniqueCounter } + let(:activity_counter_method) { :track_issue_due_date_changed_action } + + it_behaves_like 'issuable getting date change notes' + + it 'does not track the work item event in usage ping' do + expect(Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter).not_to receive(:track_work_item_date_changed_action) + + subject end it 'tracks the issue event in usage ping' do @@ -39,13 +116,48 @@ RSpec.describe ::SystemNotes::TimeTrackingService do subject end + + context 'when only start_date is added' do + let(:changed_dates) { { 'start_date' => [nil, start_date] } } + + it 'does not track the issue event in usage ping' do + expect(activity_counter_class).not_to receive(activity_counter_method) + + subject + end + end + end + + context 'when noteable is a work item' do + let(:noteable) { work_item } + let(:activity_counter_class) { Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter } + let(:activity_counter_method) { :track_work_item_date_changed_action } + + it_behaves_like 'issuable getting date change notes' + + it 'does not track the issue event in usage ping' do + expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).not_to receive(:track_issue_due_date_changed_action) + + subject + end + + context 'when only start_date is added' do + let(:changed_dates) { { 'start_date' => [nil, start_date] } } + + it 'tracks the issue event in usage ping' do + expect(activity_counter_class).to receive(activity_counter_method).with(author: author) + + subject + end + end end context 'when noteable is a merge request' do - let_it_be(:noteable) { create(:merge_request, source_project: project) } + let(:noteable) { create(:merge_request, source_project: project) } it 'does not track the issue event in usage ping' do - expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).not_to receive(:track_issue_due_date_changed_action).with(author: author) + expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).not_to receive(:track_issue_due_date_changed_action) + expect(Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter).not_to receive(:track_work_item_date_changed_action) subject end @@ -106,13 +218,37 @@ RSpec.describe ::SystemNotes::TimeTrackingService do end end + describe '#create_timelog' do + subject { described_class.new(noteable: noteable, project: project, author: author).created_timelog(timelog) } + + context 'when the timelog has a positive time spent value' do + let_it_be(:noteable, reload: true) { create(:issue, project: project) } + + let(:timelog) { create(:timelog, user: author, issue: noteable, time_spent: 1800, spent_at: '2022-03-30T00:00:00.000Z') } + + it 'sets the note text' do + expect(subject.note).to eq "added 30m of time spent at 2022-03-30" + end + end + + context 'when the timelog has a negative time spent value' do + let_it_be(:noteable, reload: true) { create(:issue, project: project) } + + let(:timelog) { create(:timelog, user: author, issue: noteable, time_spent: -1800, spent_at: '2022-03-30T00:00:00.000Z') } + + it 'sets the note text' do + expect(subject.note).to eq "subtracted 30m of time spent at 2022-03-30" + end + end + end + describe '#remove_timelog' do subject { described_class.new(noteable: noteable, project: project, author: author).remove_timelog(timelog) } context 'when the timelog has a positive time spent value' do let_it_be(:noteable, reload: true) { create(:issue, project: project) } - let(:timelog) { create(:timelog, user: author, issue: noteable, time_spent: 1800, spent_at: '2022-03-30T00:00:00.000Z')} + let(:timelog) { create(:timelog, user: author, issue: noteable, time_spent: 1800, spent_at: '2022-03-30T00:00:00.000Z') } it 'sets the note text' do expect(subject.note).to eq "deleted 30m of spent time from 2022-03-30" @@ -122,7 +258,7 @@ RSpec.describe ::SystemNotes::TimeTrackingService do context 'when the timelog has a negative time spent value' do let_it_be(:noteable, reload: true) { create(:issue, project: project) } - let(:timelog) { create(:timelog, user: author, issue: noteable, time_spent: -1800, spent_at: '2022-03-30T00:00:00.000Z')} + let(:timelog) { create(:timelog, user: author, issue: noteable, time_spent: -1800, spent_at: '2022-03-30T00:00:00.000Z') } it 'sets the note text' do expect(subject.note).to eq "deleted -30m of spent time from 2022-03-30" |