Commit e71ac60c authored by Sean Arnold's avatar Sean Arnold Committed by Mayra Cabrera

Add incident management analytics events

- Update yaml and add class for events
parent 8e4df1a6
...@@ -20,6 +20,8 @@ module Mutations ...@@ -20,6 +20,8 @@ module Mutations
alert = authorized_find!(project_path: args[:project_path], iid: args[:iid]) alert = authorized_find!(project_path: args[:project_path], iid: args[:iid])
result = set_assignees(alert, args[:assignee_usernames], args[:operation_mode]) result = set_assignees(alert, args[:assignee_usernames], args[:operation_mode])
track_usage_event(:incident_management_alert_assigned, current_user)
prepare_response(result) prepare_response(result)
end end
......
...@@ -11,6 +11,8 @@ module Mutations ...@@ -11,6 +11,8 @@ module Mutations
alert = authorized_find!(project_path: args[:project_path], iid: args[:iid]) alert = authorized_find!(project_path: args[:project_path], iid: args[:iid])
result = ::AlertManagement::Alerts::Todo::CreateService.new(alert, current_user).execute result = ::AlertManagement::Alerts::Todo::CreateService.new(alert, current_user).execute
track_usage_event(:incident_management_alert_todo, current_user)
prepare_response(result) prepare_response(result)
end end
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
module Mutations module Mutations
module AlertManagement module AlertManagement
class Base < BaseMutation class Base < BaseMutation
include Gitlab::Utils::UsageData
include ResolvesProject include ResolvesProject
argument :project_path, GraphQL::ID_TYPE, argument :project_path, GraphQL::ID_TYPE,
......
...@@ -9,6 +9,8 @@ module Mutations ...@@ -9,6 +9,8 @@ module Mutations
alert = authorized_find!(project_path: args[:project_path], iid: args[:iid]) alert = authorized_find!(project_path: args[:project_path], iid: args[:iid])
result = create_alert_issue(alert, current_user) result = create_alert_issue(alert, current_user)
track_usage_event(:incident_management_incident_created, current_user)
prepare_response(alert, result) prepare_response(alert, result)
end end
......
...@@ -13,6 +13,8 @@ module Mutations ...@@ -13,6 +13,8 @@ module Mutations
alert = authorized_find!(project_path: args[:project_path], iid: args[:iid]) alert = authorized_find!(project_path: args[:project_path], iid: args[:iid])
result = update_status(alert, args[:status]) result = update_status(alert, args[:status])
track_usage_event(:incident_management_alert_status_changed, current_user)
prepare_response(result) prepare_response(result)
end end
......
# frozen_string_literal: true
module IncidentManagement
module UsageData
include Gitlab::Utils::UsageData
def track_incident_action(current_user, target, action)
return unless target.incident?
track_usage_event(:"incident_management_#{action}", current_user)
end
# No-op as optionally overridden in implementing classes.
# For use to provide checks before calling #track_incident_action.
def track_event
end
end
end
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
module IssuableLinks module IssuableLinks
class CreateService < BaseService class CreateService < BaseService
include IncidentManagement::UsageData
attr_reader :issuable, :current_user, :params attr_reader :issuable, :current_user, :params
def initialize(issuable, user, params) def initialize(issuable, user, params)
...@@ -27,6 +29,8 @@ module IssuableLinks ...@@ -27,6 +29,8 @@ module IssuableLinks
return error(@errors.join('. '), 422) return error(@errors.join('. '), 422)
end end
track_event
success success
end end
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
module IssuableLinks module IssuableLinks
class DestroyService < BaseService class DestroyService < BaseService
include IncidentManagement::UsageData
attr_reader :link, :current_user attr_reader :link, :current_user
def initialize(link, user) def initialize(link, user)
...@@ -14,6 +16,7 @@ module IssuableLinks ...@@ -14,6 +16,7 @@ module IssuableLinks
remove_relation remove_relation
create_notes create_notes
track_event
success(message: 'Relation was removed') success(message: 'Relation was removed')
end end
......
...@@ -36,6 +36,10 @@ module IssueLinks ...@@ -36,6 +36,10 @@ module IssueLinks
def set_link_type(_link) def set_link_type(_link)
# EE only # EE only
end end
def track_event
track_incident_action(current_user, issuable, :incident_relate)
end
end end
end end
......
...@@ -20,5 +20,9 @@ module IssueLinks ...@@ -20,5 +20,9 @@ module IssueLinks
SystemNoteService.unrelate_issue(source, target, current_user) SystemNoteService.unrelate_issue(source, target, current_user)
SystemNoteService.unrelate_issue(target, source, current_user) SystemNoteService.unrelate_issue(target, source, current_user)
end end
def track_event
track_incident_action(current_user, target, :incident_unrelate)
end
end end
end end
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
module Issues module Issues
class BaseService < ::IssuableBaseService class BaseService < ::IssuableBaseService
include IncidentManagement::UsageData
def hook_data(issue, action, old_associations: {}) def hook_data(issue, action, old_associations: {})
hook_data = issue.to_hook_data(current_user, old_associations: old_associations) hook_data = issue.to_hook_data(current_user, old_associations: old_associations)
hook_data[:object_attributes][:action] = action hook_data[:object_attributes][:action] = action
......
...@@ -37,6 +37,7 @@ module Issues ...@@ -37,6 +37,7 @@ module Issues
execute_hooks(issue, 'close') execute_hooks(issue, 'close')
invalidate_cache_counts(issue, users: issue.assignees) invalidate_cache_counts(issue, users: issue.assignees)
issue.update_project_counter_caches issue.update_project_counter_caches
track_incident_action(current_user, issue, :incident_closed)
store_first_mentioned_in_commit_at(issue, closed_via) if closed_via.is_a?(MergeRequest) store_first_mentioned_in_commit_at(issue, closed_via) if closed_via.is_a?(MergeRequest)
......
...@@ -30,6 +30,7 @@ module Issues ...@@ -30,6 +30,7 @@ module Issues
user_agent_detail_service.create user_agent_detail_service.create
resolve_discussions_with_issue(issuable) resolve_discussions_with_issue(issuable)
delete_milestone_total_issue_counter_cache(issuable.milestone) delete_milestone_total_issue_counter_cache(issuable.milestone)
track_incident_action(current_user, issuable, :incident_created)
super super
end end
......
...@@ -13,6 +13,7 @@ module Issues ...@@ -13,6 +13,7 @@ module Issues
invalidate_cache_counts(issue, users: issue.assignees) invalidate_cache_counts(issue, users: issue.assignees)
issue.update_project_counter_caches issue.update_project_counter_caches
delete_milestone_closed_issue_counter_cache(issue.milestone) delete_milestone_closed_issue_counter_cache(issue.milestone)
track_incident_action(current_user, issue, :incident_reopened)
end end
issue issue
......
...@@ -44,12 +44,14 @@ module Issues ...@@ -44,12 +44,14 @@ module Issues
create_assignee_note(issue, old_assignees) create_assignee_note(issue, old_assignees)
notification_service.async.reassigned_issue(issue, current_user, old_assignees) notification_service.async.reassigned_issue(issue, current_user, old_assignees)
todo_service.reassigned_assignable(issue, current_user, old_assignees) todo_service.reassigned_assignable(issue, current_user, old_assignees)
track_incident_action(current_user, issue, :incident_assigned)
end end
if issue.previous_changes.include?('confidential') if issue.previous_changes.include?('confidential')
# don't enqueue immediately to prevent todos removal in case of a mistake # don't enqueue immediately to prevent todos removal in case of a mistake
TodosDestroyer::ConfidentialIssueWorker.perform_in(Todo::WAIT_FOR_DELETE, issue.id) if issue.confidential? TodosDestroyer::ConfidentialIssueWorker.perform_in(Todo::WAIT_FOR_DELETE, issue.id) if issue.confidential?
create_confidentiality_note(issue) create_confidentiality_note(issue)
track_usage_event(:incident_management_incident_change_confidential, current_user)
end end
added_labels = issue.labels - old_labels added_labels = issue.labels - old_labels
......
...@@ -60,6 +60,7 @@ module Issues ...@@ -60,6 +60,7 @@ module Issues
if @issue.persisted? if @issue.persisted?
# Save the meeting directly since we only want to update one meeting, not all # Save the meeting directly since we only want to update one meeting, not all
zoom_meeting.save zoom_meeting.save
track_incident_action(current_user, issue, :incident_zoom_meeting)
success(message: _('Zoom meeting added')) success(message: _('Zoom meeting added'))
else else
success(message: _('Zoom meeting added'), payload: { zoom_meetings: [zoom_meeting] }) success(message: _('Zoom meeting added'), payload: { zoom_meetings: [zoom_meeting] })
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
module Notes module Notes
class CreateService < ::Notes::BaseService class CreateService < ::Notes::BaseService
include IncidentManagement::UsageData
def execute def execute
note = Notes::BuildService.new(project, current_user, params.except(:merge_request_diff_head_sha)).execute note = Notes::BuildService.new(project, current_user, params.except(:merge_request_diff_head_sha)).execute
...@@ -62,6 +64,7 @@ module Notes ...@@ -62,6 +64,7 @@ module Notes
clear_noteable_diffs_cache(note) clear_noteable_diffs_cache(note)
Suggestions::CreateService.new(note).execute Suggestions::CreateService.new(note).execute
increment_usage_counter(note) increment_usage_counter(note)
track_event(note, current_user)
if Feature.enabled?(:notes_create_service_tracking, project) if Feature.enabled?(:notes_create_service_tracking, project)
Gitlab::Tracking.event('Notes::CreateService', 'execute', tracking_data_for(note)) Gitlab::Tracking.event('Notes::CreateService', 'execute', tracking_data_for(note))
...@@ -104,5 +107,11 @@ module Notes ...@@ -104,5 +107,11 @@ module Notes
value: note.id value: note.id
} }
end end
def track_event(note, user)
return unless note.noteable.is_a?(Issue) && note.noteable.incident?
track_usage_event(:incident_management_incident_comment, user)
end
end end
end end
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
# TodoService.new.new_issue(issue, current_user) # TodoService.new.new_issue(issue, current_user)
# #
class TodoService class TodoService
include Gitlab::Utils::UsageData
# When create an issue we should: # When create an issue we should:
# #
# * create a todo for assignee if issue is assigned # * create a todo for assignee if issue is assigned
...@@ -217,6 +218,9 @@ class TodoService ...@@ -217,6 +218,9 @@ class TodoService
Array(users).map do |user| Array(users).map do |user|
next if pending_todos(user, attributes).exists? next if pending_todos(user, attributes).exists?
issue_type = attributes.delete(:issue_type)
track_todo_creation(user, issue_type)
todo = Todo.create(attributes.merge(user_id: user.id)) todo = Todo.create(attributes.merge(user_id: user.id))
user.update_todos_count_cache user.update_todos_count_cache
todo todo
...@@ -299,6 +303,8 @@ class TodoService ...@@ -299,6 +303,8 @@ class TodoService
if target.is_a?(Commit) if target.is_a?(Commit)
attributes.merge!(target_id: nil, commit_id: target.id) attributes.merge!(target_id: nil, commit_id: target.id)
elsif target.is_a?(Issue)
attributes[:issue_type] = target.issue_type
end end
attributes attributes
...@@ -346,6 +352,12 @@ class TodoService ...@@ -346,6 +352,12 @@ class TodoService
def pending_todos(user, criteria = {}) def pending_todos(user, criteria = {})
PendingTodosFinder.new(user, criteria).execute PendingTodosFinder.new(user, criteria).execute
end end
def track_todo_creation(user, issue_type)
return unless issue_type == 'incident'
track_usage_event(:incident_management_incident_todo, user)
end
end end
TodoService.prepend_if_ee('EE::TodoService') TodoService.prepend_if_ee('EE::TodoService')
---
title: Add incident management analytics events
merge_request: 40475
author:
type: added
...@@ -14,6 +14,7 @@ module StatusPage ...@@ -14,6 +14,7 @@ module StatusPage
# * StatusPage::PublishListService # * StatusPage::PublishListService
class PublishService class PublishService
include Gitlab::Utils::StrongMemoize include Gitlab::Utils::StrongMemoize
include Gitlab::Utils::UsageData
def initialize(user:, project:, issue_id:) def initialize(user:, project:, issue_id:)
@user = user @user = user
...@@ -28,6 +29,8 @@ module StatusPage ...@@ -28,6 +29,8 @@ module StatusPage
response = process_details response = process_details
return response if response.error? return response if response.error?
track_event
process_list process_list
end end
...@@ -36,11 +39,13 @@ module StatusPage ...@@ -36,11 +39,13 @@ module StatusPage
attr_reader :user, :project, :issue_id attr_reader :user, :project, :issue_id
def process_details def process_details
unpublish_details? ? unpublish_details : publish_details should_unpublish? ? unpublish_details : publish_details
end end
def unpublish_details? def should_unpublish?
issue.confidential? || !issue.status_page_published_incident strong_memoize(:should_unpublish) do
issue.confidential? || !issue.status_page_published_incident
end
end end
def process_list def process_list
...@@ -90,5 +95,9 @@ module StatusPage ...@@ -90,5 +95,9 @@ module StatusPage
def error(message) def error(message)
ServiceResponse.error(message: message) ServiceResponse.error(message: message)
end end
def track_event
track_usage_event(:incident_management_incident_published, user) unless should_unpublish?
end
end end
end end
...@@ -25,12 +25,18 @@ RSpec.describe StatusPage::PublishService do ...@@ -25,12 +25,18 @@ RSpec.describe StatusPage::PublishService do
describe 'publish details' do describe 'publish details' do
context 'when upload succeeds' do context 'when upload succeeds' do
it 'uploads incident details and list' do before do
expect_to_publish_details(error?: false, success?: true) expect_to_publish_details(error?: false, success?: true)
expect_to_publish_list(error?: false, success?: true) expect_to_publish_list(error?: false, success?: true)
end
it 'uploads incident details and list' do
expect(result).to be_success expect(result).to be_success
end end
it_behaves_like 'an incident management tracked event', :incident_management_incident_published do
let(:current_user) { user }
end
end end
context 'when upload fails' do context 'when upload fails' do
...@@ -52,6 +58,8 @@ RSpec.describe StatusPage::PublishService do ...@@ -52,6 +58,8 @@ RSpec.describe StatusPage::PublishService do
expect(result).to be_success expect(result).to be_success
end end
it_behaves_like 'does not track incident management event', :incident_management_incident_published
end end
context 'when unpublish service responses with error' do context 'when unpublish service responses with error' do
......
...@@ -116,3 +116,60 @@ ...@@ -116,3 +116,60 @@
- name: merge_request_action - name: merge_request_action
category: source_code category: source_code
aggregation: daily aggregation: daily
# Incident management
- name: incident_management_alert_status_changed
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_alert_assigned
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_alert_todo
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_created
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_reopened
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_closed
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_assigned
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_todo
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_comment
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_zoom_meeting
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_published
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_relate
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_unrelate
redis_slot: incident_management
category: incident_management
aggregation: weekly
- name: incident_management_incident_change_confidential
redis_slot: incident_management
category: incident_management
aggregation: weekly
...@@ -96,6 +96,13 @@ module Gitlab ...@@ -96,6 +96,13 @@ module Gitlab
yield.merge(key => Time.current) yield.merge(key => Time.current)
end end
def track_usage_event(metric_name, target)
return unless Feature.enabled?(:"usage_data_#{metric_name}", default_enabled: true)
return unless Gitlab::CurrentSettings.usage_ping_enabled?
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(target.id, metric_name.to_s)
end
private private
def redis_usage_counter def redis_usage_counter
......
...@@ -55,6 +55,7 @@ RSpec.describe Mutations::AlertManagement::Alerts::SetAssignees do ...@@ -55,6 +55,7 @@ RSpec.describe Mutations::AlertManagement::Alerts::SetAssignees do
context 'when operation mode is not specified' do context 'when operation mode is not specified' do
it_behaves_like 'successful resolution' it_behaves_like 'successful resolution'
it_behaves_like 'an incident management tracked event', :incident_management_alert_assigned
end end
context 'when user does not have permission to update alerts' do context 'when user does not have permission to update alerts' do
......
...@@ -16,6 +16,8 @@ RSpec.describe Mutations::AlertManagement::Alerts::Todo::Create do ...@@ -16,6 +16,8 @@ RSpec.describe Mutations::AlertManagement::Alerts::Todo::Create do
describe '#resolve' do describe '#resolve' do
subject(:resolve) { mutation.resolve(args) } subject(:resolve) { mutation.resolve(args) }
it_behaves_like 'an incident management tracked event', :incident_management_alert_todo
context 'when user does not have permissions' do context 'when user does not have permissions' do
let(:current_user) { nil } let(:current_user) { nil }
......
...@@ -26,6 +26,8 @@ RSpec.describe Mutations::AlertManagement::CreateAlertIssue do ...@@ -26,6 +26,8 @@ RSpec.describe Mutations::AlertManagement::CreateAlertIssue do
errors: [] errors: []
) )
end end
it_behaves_like 'an incident management tracked event', :incident_management_incident_created
end end
context 'when CreateAlertIssue responds with an error' do context 'when CreateAlertIssue responds with an error' do
......
...@@ -30,6 +30,10 @@ RSpec.describe Mutations::AlertManagement::UpdateAlertStatus do ...@@ -30,6 +30,10 @@ RSpec.describe Mutations::AlertManagement::UpdateAlertStatus do
) )
end end
it_behaves_like 'an incident management tracked event', :incident_management_alert_status_changed do
let(:user) { current_user }
end
context 'error occurs when updating' do context 'error occurs when updating' do
it 'returns the alert with errors' do it 'returns the alert with errors' do
# Stub an error on the alert # Stub an error on the alert
......
...@@ -20,7 +20,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s ...@@ -20,7 +20,7 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
describe '.categories' do describe '.categories' do
it 'gets all unique category names' do it 'gets all unique category names' do
expect(described_class.categories).to contain_exactly('analytics', 'compliance', 'ide_edit', 'search', 'source_code') expect(described_class.categories).to contain_exactly('analytics', 'compliance', 'ide_edit', 'search', 'source_code', 'incident_management')
end end
end end
......
...@@ -118,6 +118,14 @@ RSpec.describe IssueLinks::CreateService do ...@@ -118,6 +118,14 @@ RSpec.describe IssueLinks::CreateService do
subject subject
end end
context 'issue is an incident' do
let(:issue) { create(:incident, project: project) }
it_behaves_like 'an incident management tracked event', :incident_management_incident_relate do
let(:current_user) { user }
end
end
end end
context 'when reference of any already related issue is present' do context 'when reference of any already related issue is present' do
......
...@@ -36,6 +36,14 @@ RSpec.describe IssueLinks::DestroyService do ...@@ -36,6 +36,14 @@ RSpec.describe IssueLinks::DestroyService do
it 'returns success message' do it 'returns success message' do
is_expected.to eq(message: 'Relation was removed', status: :success) is_expected.to eq(message: 'Relation was removed', status: :success)
end end
context 'target is an incident' do
let(:issue_b) { create(:incident, project: project) }
it_behaves_like 'an incident management tracked event', :incident_management_incident_unrelate do
let(:current_user) { user }
end
end
end end
context 'when failing to remove an issue link' do context 'when failing to remove an issue link' do
......
...@@ -67,6 +67,15 @@ RSpec.describe Issues::CloseService do ...@@ -67,6 +67,15 @@ RSpec.describe Issues::CloseService do
service.execute(issue) service.execute(issue)
end end
context 'issue is incident type' do
let(:issue) { create(:incident, project: project) }
let(:current_user) { user }
subject { service.execute(issue) }
it_behaves_like 'an incident management tracked event', :incident_management_incident_closed
end
end end
describe '#close_issue' do describe '#close_issue' do
......
...@@ -49,6 +49,18 @@ RSpec.describe Issues::CreateService do ...@@ -49,6 +49,18 @@ RSpec.describe Issues::CreateService do
end end
end end
context 'issue is incident type' do
before do
opts[:issue_type] = 'incident'
end
let(:current_user) { user }
subject { issue }
it_behaves_like 'an incident management tracked event', :incident_management_incident_created
end
it 'refreshes the number of open issues', :use_clean_rails_memory_store_caching do it 'refreshes the number of open issues', :use_clean_rails_memory_store_caching do
expect { issue }.to change { project.open_issues_count }.from(0).to(1) expect { issue }.to change { project.open_issues_count }.from(0).to(1)
end end
......
...@@ -53,6 +53,15 @@ RSpec.describe Issues::ReopenService do ...@@ -53,6 +53,15 @@ RSpec.describe Issues::ReopenService do
described_class.new(project, user).execute(issue) described_class.new(project, user).execute(issue)
end end
context 'issue is incident type' do
let(:issue) { create(:incident, :closed, project: project) }
let(:current_user) { user }
subject { described_class.new(project, user).execute(issue) }
it_behaves_like 'an incident management tracked event', :incident_management_incident_reopened
end
context 'when issue is not confidential' do context 'when issue is not confidential' do
it 'executes issue hooks' do it 'executes issue hooks' do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks) expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks)
......
...@@ -112,6 +112,18 @@ RSpec.describe Issues::UpdateService, :mailer do ...@@ -112,6 +112,18 @@ RSpec.describe Issues::UpdateService, :mailer do
update_issue(confidential: false) update_issue(confidential: false)
end end
context 'issue in incident type' do
before do
opts[:issue_type] = 'incident'
end
let(:current_user) { user }
subject { update_issue(confidential: true) }
it_behaves_like 'an incident management tracked event', :incident_management_incident_change_confidential
end
it 'updates open issue counter for assignees when issue is reassigned' do it 'updates open issue counter for assignees when issue is reassigned' do
update_issue(assignee_ids: [user2.id]) update_issue(assignee_ids: [user2.id])
...@@ -461,6 +473,13 @@ RSpec.describe Issues::UpdateService, :mailer do ...@@ -461,6 +473,13 @@ RSpec.describe Issues::UpdateService, :mailer do
expect(Todo.where(attributes).count).to eq(1) expect(Todo.where(attributes).count).to eq(1)
end end
context 'issue is incident type' do
let(:issue) { create(:incident, project: project) }
let(:current_user) { user }
it_behaves_like 'an incident management tracked event', :incident_management_incident_assigned
end
end end
context 'when the milestone is removed' do context 'when the milestone is removed' do
......
...@@ -82,6 +82,13 @@ RSpec.describe Issues::ZoomLinkService do ...@@ -82,6 +82,13 @@ RSpec.describe Issues::ZoomLinkService do
include_examples 'can add meeting' include_examples 'can add meeting'
context 'issue is incident type' do
let(:issue) { create(:incident) }
let(:current_user) { user }
it_behaves_like 'an incident management tracked event', :incident_management_incident_zoom_meeting
end
context 'with insufficient issue update permissions' do context 'with insufficient issue update permissions' do
include_context 'insufficient issue update permissions' include_context 'insufficient issue update permissions'
include_examples 'cannot add meeting' include_examples 'cannot add meeting'
......
...@@ -57,6 +57,16 @@ RSpec.describe Notes::CreateService do ...@@ -57,6 +57,16 @@ RSpec.describe Notes::CreateService do
described_class.new(project, user, opts).execute described_class.new(project, user, opts).execute
end end
context 'issue is an incident' do
subject { described_class.new(project, user, opts).execute }
let(:issue) { create(:incident, project: project) }
it_behaves_like 'an incident management tracked event', :incident_management_incident_comment do
let(:current_user) { user }
end
end
end end
context 'noteable highlight cache clearing' do context 'noteable highlight cache clearing' do
......
...@@ -194,6 +194,19 @@ RSpec.describe TodoService do ...@@ -194,6 +194,19 @@ RSpec.describe TodoService do
should_create_todo(user: john_doe, target: issue) should_create_todo(user: john_doe, target: issue)
end end
end end
context 'issue is an incident' do
let(:issue) { create(:incident, project: project, assignees: [john_doe], author: author) }
subject do
service.new_issue(issue, author)
should_create_todo(user: john_doe, target: issue, action: Todo::ASSIGNED)
end
it_behaves_like 'an incident management tracked event', :incident_management_incident_todo do
let(:current_user) { john_doe}
end
end
end end
describe '#update_issue' do describe '#update_issue' do
......
# frozen_string_literal: true
RSpec.shared_examples 'an incident management tracked event' do |event|
describe ".track_event", :clean_gitlab_redis_shared_state do
let(:counter) { Gitlab::UsageDataCounters::HLLRedisCounter }
let(:start_time) { 1.minute.ago }
let(:end_time) { 1.minute.from_now }
it "tracks the event using redis" do
# Allow other subsequent calls
allow(Gitlab::UsageDataCounters::HLLRedisCounter)
.to receive(:track_event)
expect(Gitlab::UsageDataCounters::HLLRedisCounter)
.to receive(:track_event)
.with(current_user.id, event.to_s)
.and_call_original
expect { subject }
.to change { counter.unique_events(event_names: event.to_s, start_date: start_time, end_date: end_time) }
.by 1
end
end
end
RSpec.shared_examples 'does not track incident management event' do |event|
it 'does not track the event', :clean_gitlab_redis_shared_state do
expect(Gitlab::UsageDataCounters::HLLRedisCounter)
.not_to receive(:track_event)
.with(anything, event.to_s)
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment