debian-mirror-gitlab/spec/services/event_create_service_spec.rb

542 lines
17 KiB
Ruby
Raw Normal View History

2019-07-31 22:56:46 +05:30
# frozen_string_literal: true
2014-09-02 18:07:02 +05:30
require 'spec_helper'
2021-09-30 23:02:18 +05:30
RSpec.describe EventCreateService, :clean_gitlab_redis_cache, :clean_gitlab_redis_shared_state do
2022-06-21 17:19:12 +05:30
include SnowplowHelpers
2017-09-10 17:25:29 +05:30
let(:service) { described_class.new }
2014-09-02 18:07:02 +05:30
2020-06-23 00:09:42 +05:30
let_it_be(:user, reload: true) { create :user }
let_it_be(:project) { create(:project) }
2020-11-24 15:15:51 +05:30
shared_examples 'it records the event in the event counter' do
specify do
tracking_params = { event_action: event_action, date_from: Date.yesterday, date_to: Date.today }
expect { subject }
2021-02-22 17:27:13 +05:30
.to change { Gitlab::UsageDataCounters::TrackUniqueEvents.count_unique_events(**tracking_params) }
2020-11-24 15:15:51 +05:30
.by(1)
end
end
2014-09-02 18:07:02 +05:30
describe 'Issues' do
2016-08-24 12:49:21 +05:30
describe '#open_issue' do
2014-09-02 18:07:02 +05:30
let(:issue) { create(:issue) }
2015-04-26 12:48:37 +05:30
it { expect(service.open_issue(issue, issue.author)).to be_truthy }
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
it "creates new event" do
2014-09-02 18:07:02 +05:30
expect { service.open_issue(issue, issue.author) }.to change { Event.count }
end
end
2016-08-24 12:49:21 +05:30
describe '#close_issue' do
2014-09-02 18:07:02 +05:30
let(:issue) { create(:issue) }
2015-04-26 12:48:37 +05:30
it { expect(service.close_issue(issue, issue.author)).to be_truthy }
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
it "creates new event" do
2014-09-02 18:07:02 +05:30
expect { service.close_issue(issue, issue.author) }.to change { Event.count }
end
end
2016-08-24 12:49:21 +05:30
describe '#reopen_issue' do
2014-09-02 18:07:02 +05:30
let(:issue) { create(:issue) }
2015-04-26 12:48:37 +05:30
it { expect(service.reopen_issue(issue, issue.author)).to be_truthy }
2014-09-02 18:07:02 +05:30
2017-08-17 22:00:37 +05:30
it "creates new event" do
2014-09-02 18:07:02 +05:30
expect { service.reopen_issue(issue, issue.author) }.to change { Event.count }
end
end
end
2022-07-23 23:45:48 +05:30
describe 'Merge Requests', :snowplow do
2016-08-24 12:49:21 +05:30
describe '#open_mr' do
2020-11-24 15:15:51 +05:30
subject(:open_mr) { service.open_mr(merge_request, merge_request.author) }
2014-09-02 18:07:02 +05:30
let(:merge_request) { create(:merge_request) }
2020-11-24 15:15:51 +05:30
it { expect(open_mr).to be_truthy }
2014-09-02 18:07:02 +05:30
2016-09-13 17:45:13 +05:30
it "creates new event" do
2020-11-24 15:15:51 +05:30
expect { open_mr }.to change { Event.count }
end
it_behaves_like "it records the event in the event counter" do
let(:event_action) { Gitlab::UsageDataCounters::TrackUniqueEvents::MERGE_REQUEST_ACTION }
2014-09-02 18:07:02 +05:30
end
2022-07-23 23:45:48 +05:30
2023-01-13 00:05:48 +05:30
it_behaves_like 'Snowplow event tracking with RedisHLL context' do
let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
let(:category) { described_class.name }
let(:action) { 'created' }
let(:label) { 'usage_activity_by_stage_monthly.create.merge_requests_users' }
2022-07-23 23:45:48 +05:30
let(:namespace) { project.namespace }
let(:project) { merge_request.project }
let(:user) { merge_request.author }
2023-01-13 00:05:48 +05:30
let(:context) do
[Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: 'merge_requests_users').to_context]
end
2022-07-23 23:45:48 +05:30
end
2014-09-02 18:07:02 +05:30
end
2016-08-24 12:49:21 +05:30
describe '#close_mr' do
2020-11-24 15:15:51 +05:30
subject(:close_mr) { service.close_mr(merge_request, merge_request.author) }
2014-09-02 18:07:02 +05:30
let(:merge_request) { create(:merge_request) }
2020-11-24 15:15:51 +05:30
it { expect(close_mr).to be_truthy }
2014-09-02 18:07:02 +05:30
2016-09-13 17:45:13 +05:30
it "creates new event" do
2020-11-24 15:15:51 +05:30
expect { close_mr }.to change { Event.count }
end
it_behaves_like "it records the event in the event counter" do
let(:event_action) { Gitlab::UsageDataCounters::TrackUniqueEvents::MERGE_REQUEST_ACTION }
2014-09-02 18:07:02 +05:30
end
2022-07-23 23:45:48 +05:30
2023-01-13 00:05:48 +05:30
it_behaves_like 'Snowplow event tracking with RedisHLL context' do
let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
let(:category) { described_class.name }
let(:action) { 'closed' }
let(:label) { 'usage_activity_by_stage_monthly.create.merge_requests_users' }
2022-07-23 23:45:48 +05:30
let(:namespace) { project.namespace }
let(:project) { merge_request.project }
let(:user) { merge_request.author }
2023-01-13 00:05:48 +05:30
let(:context) do
[Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: 'merge_requests_users').to_context]
end
2022-07-23 23:45:48 +05:30
end
2014-09-02 18:07:02 +05:30
end
2016-08-24 12:49:21 +05:30
describe '#merge_mr' do
2020-11-24 15:15:51 +05:30
subject(:merge_mr) { service.merge_mr(merge_request, merge_request.author) }
2014-09-02 18:07:02 +05:30
let(:merge_request) { create(:merge_request) }
2020-11-24 15:15:51 +05:30
it { expect(merge_mr).to be_truthy }
2014-09-02 18:07:02 +05:30
2016-09-13 17:45:13 +05:30
it "creates new event" do
2020-11-24 15:15:51 +05:30
expect { merge_mr }.to change { Event.count }
end
it_behaves_like "it records the event in the event counter" do
let(:event_action) { Gitlab::UsageDataCounters::TrackUniqueEvents::MERGE_REQUEST_ACTION }
2014-09-02 18:07:02 +05:30
end
2022-07-23 23:45:48 +05:30
2023-01-13 00:05:48 +05:30
it_behaves_like 'Snowplow event tracking with RedisHLL context' do
let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
let(:category) { described_class.name }
let(:action) { 'merged' }
let(:label) { 'usage_activity_by_stage_monthly.create.merge_requests_users' }
2022-07-23 23:45:48 +05:30
let(:namespace) { project.namespace }
let(:project) { merge_request.project }
let(:user) { merge_request.author }
2023-01-13 00:05:48 +05:30
let(:context) do
[Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: 'merge_requests_users').to_context]
end
2022-07-23 23:45:48 +05:30
end
2014-09-02 18:07:02 +05:30
end
2016-08-24 12:49:21 +05:30
describe '#reopen_mr' do
2014-09-02 18:07:02 +05:30
let(:merge_request) { create(:merge_request) }
2015-04-26 12:48:37 +05:30
it { expect(service.reopen_mr(merge_request, merge_request.author)).to be_truthy }
2014-09-02 18:07:02 +05:30
2016-09-13 17:45:13 +05:30
it "creates new event" do
2014-09-02 18:07:02 +05:30
expect { service.reopen_mr(merge_request, merge_request.author) }.to change { Event.count }
2020-07-28 23:09:34 +05:30
end
end
describe '#approve_mr' do
let(:merge_request) { create(:merge_request) }
it { expect(service.approve_mr(merge_request, user)).to be_truthy }
it 'creates new event' do
service.approve_mr(merge_request, user)
change { Event.approved_action.where(target: merge_request).count }.by(1)
2014-09-02 18:07:02 +05:30
end
end
end
describe 'Milestone' do
2016-08-24 12:49:21 +05:30
describe '#open_milestone' do
2014-09-02 18:07:02 +05:30
let(:milestone) { create(:milestone) }
2015-04-26 12:48:37 +05:30
it { expect(service.open_milestone(milestone, user)).to be_truthy }
2014-09-02 18:07:02 +05:30
2016-09-13 17:45:13 +05:30
it "creates new event" do
2014-09-02 18:07:02 +05:30
expect { service.open_milestone(milestone, user) }.to change { Event.count }
end
end
2016-08-24 12:49:21 +05:30
describe '#close_mr' do
2014-09-02 18:07:02 +05:30
let(:milestone) { create(:milestone) }
2015-04-26 12:48:37 +05:30
it { expect(service.close_milestone(milestone, user)).to be_truthy }
2014-09-02 18:07:02 +05:30
2016-09-13 17:45:13 +05:30
it "creates new event" do
2014-09-02 18:07:02 +05:30
expect { service.close_milestone(milestone, user) }.to change { Event.count }
end
end
2015-09-25 12:07:36 +05:30
2016-08-24 12:49:21 +05:30
describe '#destroy_mr' do
2015-09-25 12:07:36 +05:30
let(:milestone) { create(:milestone) }
it { expect(service.destroy_milestone(milestone, user)).to be_truthy }
2016-09-13 17:45:13 +05:30
it "creates new event" do
2015-09-25 12:07:36 +05:30
expect { service.destroy_milestone(milestone, user) }.to change { Event.count }
end
end
2014-09-02 18:07:02 +05:30
end
2017-08-17 22:00:37 +05:30
2019-12-21 20:55:43 +05:30
shared_examples_for 'service for creating a push event' do |service_class|
2017-08-17 22:00:37 +05:30
it 'creates a new event' do
2019-12-21 20:55:43 +05:30
expect { subject }.to change { Event.count }
2017-09-10 17:25:29 +05:30
end
it 'creates the push event payload' do
2019-12-21 20:55:43 +05:30
expect(service_class).to receive(:new)
2017-09-10 17:25:29 +05:30
.with(an_instance_of(PushEvent), push_data)
.and_call_original
2019-12-21 20:55:43 +05:30
subject
2017-08-17 22:00:37 +05:30
end
it 'updates user last activity' do
2019-12-21 20:55:43 +05:30
expect { subject }.to change { user.last_activity_on }.to(Date.today)
2017-09-10 17:25:29 +05:30
end
2018-03-17 18:26:18 +05:30
it 'caches the last push event for the user' do
2020-01-01 13:55:28 +05:30
expect_next_instance_of(Users::LastPushEventService) do |instance|
expect(instance).to receive(:cache_last_push_event).with(an_instance_of(PushEvent))
end
2018-03-17 18:26:18 +05:30
2019-12-21 20:55:43 +05:30
subject
2018-03-17 18:26:18 +05:30
end
2017-09-10 17:25:29 +05:30
it 'does not create any event data when an error is raised' do
payload_service = double(:service)
allow(payload_service).to receive(:execute)
.and_raise(RuntimeError)
2019-12-21 20:55:43 +05:30
allow(service_class).to receive(:new)
2017-09-10 17:25:29 +05:30
.and_return(payload_service)
2019-12-21 20:55:43 +05:30
expect { subject }.to raise_error(RuntimeError)
2017-09-10 17:25:29 +05:30
expect(Event.count).to eq(0)
expect(PushEventPayload.count).to eq(0)
2017-08-17 22:00:37 +05:30
end
end
2021-09-30 23:02:18 +05:30
describe '#wiki_event' do
2020-04-22 19:07:51 +05:30
let_it_be(:user) { create(:user) }
let_it_be(:wiki_page) { create(:wiki_page) }
let_it_be(:meta) { create(:wiki_page_meta, :for_wiki_page, wiki_page: wiki_page) }
2020-10-24 23:57:45 +05:30
let(:fingerprint) { generate(:sha) }
2020-04-22 19:07:51 +05:30
2020-10-24 23:57:45 +05:30
def create_event
service.wiki_event(meta, user, action, fingerprint)
end
2020-07-28 23:09:34 +05:30
2020-10-24 23:57:45 +05:30
where(:action) { Event::WIKI_ACTIONS.map { |action| [action] } }
with_them do
2020-11-24 15:15:51 +05:30
subject { create_event }
2020-10-24 23:57:45 +05:30
it 'creates the event' do
expect(create_event).to have_attributes(
wiki_page?: true,
valid?: true,
persisted?: true,
action: action.to_s,
wiki_page: wiki_page,
author: user,
fingerprint: fingerprint
)
end
2020-07-28 23:09:34 +05:30
2020-10-24 23:57:45 +05:30
it 'is idempotent', :aggregate_failures do
event = nil
expect { event = create_event }.to change(Event, :count).by(1)
duplicate = nil
expect { duplicate = create_event }.not_to change(Event, :count)
2020-05-24 23:13:21 +05:30
2020-10-24 23:57:45 +05:30
expect(duplicate).to eq(event)
end
2020-11-24 15:15:51 +05:30
it_behaves_like "it records the event in the event counter" do
let(:event_action) { Gitlab::UsageDataCounters::TrackUniqueEvents::WIKI_ACTION }
2020-04-22 19:07:51 +05:30
end
end
2020-06-23 00:09:42 +05:30
(Event.actions.keys - Event::WIKI_ACTIONS).each do |bad_action|
2020-04-22 19:07:51 +05:30
context "The action is #{bad_action}" do
2020-10-24 23:57:45 +05:30
let(:action) { bad_action }
2020-04-22 19:07:51 +05:30
it 'raises an error' do
2020-10-24 23:57:45 +05:30
expect { create_event }.to raise_error(described_class::IllegalActionError)
2020-04-22 19:07:51 +05:30
end
end
end
end
2022-06-21 17:19:12 +05:30
describe '#push', :snowplow do
2019-12-21 20:55:43 +05:30
let(:push_data) do
{
commits: [
{
id: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2',
message: 'This is a commit'
}
],
before: '0000000000000000000000000000000000000000',
after: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2',
total_commits_count: 1,
ref: 'refs/heads/my-branch'
}
end
subject { service.push(project, user, push_data) }
it_behaves_like 'service for creating a push event', PushEventPayloadService
2020-07-28 23:09:34 +05:30
2020-11-24 15:15:51 +05:30
it_behaves_like "it records the event in the event counter" do
let(:event_action) { Gitlab::UsageDataCounters::TrackUniqueEvents::PUSH_ACTION }
2020-07-28 23:09:34 +05:30
end
2022-06-21 17:19:12 +05:30
2023-01-13 00:05:48 +05:30
it_behaves_like 'Snowplow event tracking with RedisHLL context' do
2022-07-23 23:45:48 +05:30
let(:category) { described_class.to_s }
2023-01-13 00:05:48 +05:30
let(:action) { :push }
2022-07-23 23:45:48 +05:30
let(:namespace) { project.namespace }
let(:feature_flag_name) { :route_hll_to_snowplow }
2023-01-13 00:05:48 +05:30
let(:label) { 'usage_activity_by_stage_monthly.create.action_monthly_active_users_project_repo' }
let(:context) do
[Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll,
event: 'action_active_users_project_repo').to_context]
end
2022-07-23 23:45:48 +05:30
end
2019-12-21 20:55:43 +05:30
end
2022-06-21 17:19:12 +05:30
describe '#bulk_push', :snowplow do
2019-12-21 20:55:43 +05:30
let(:push_data) do
{
action: :created,
ref_count: 4,
ref_type: :branch
}
end
subject { service.bulk_push(project, user, push_data) }
it_behaves_like 'service for creating a push event', BulkPushEventPayloadService
2020-07-28 23:09:34 +05:30
2020-11-24 15:15:51 +05:30
it_behaves_like "it records the event in the event counter" do
let(:event_action) { Gitlab::UsageDataCounters::TrackUniqueEvents::PUSH_ACTION }
2020-07-28 23:09:34 +05:30
end
2022-06-21 17:19:12 +05:30
2023-01-13 00:05:48 +05:30
it_behaves_like 'Snowplow event tracking with RedisHLL context' do
2022-07-23 23:45:48 +05:30
let(:category) { described_class.to_s }
2023-01-13 00:05:48 +05:30
let(:action) { :push }
2022-07-23 23:45:48 +05:30
let(:namespace) { project.namespace }
let(:feature_flag_name) { :route_hll_to_snowplow }
2023-01-13 00:05:48 +05:30
let(:label) { 'usage_activity_by_stage_monthly.create.action_monthly_active_users_project_repo' }
let(:context) do
[Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll,
event: 'action_active_users_project_repo').to_context]
end
2022-07-23 23:45:48 +05:30
end
2019-12-21 20:55:43 +05:30
end
2017-08-17 22:00:37 +05:30
describe 'Project' do
describe '#join_project' do
subject { service.join_project(project, user) }
it { is_expected.to be_truthy }
it { expect { subject }.to change { Event.count }.from(0).to(1) }
end
describe '#expired_leave_project' do
subject { service.expired_leave_project(project, user) }
it { is_expected.to be_truthy }
it { expect { subject }.to change { Event.count }.from(0).to(1) }
end
end
2020-06-23 00:09:42 +05:30
2022-08-13 15:12:31 +05:30
describe 'design events', :snowplow do
2020-06-23 00:09:42 +05:30
let_it_be(:design) { create(:design, project: project) }
let_it_be(:author) { user }
2022-08-13 15:12:31 +05:30
before do
allow(Gitlab::Tracking).to receive(:event) # rubocop:disable RSpec/ExpectGitlabTracking
end
2020-06-23 00:09:42 +05:30
describe '#save_designs' do
let_it_be(:updated) { create_list(:design, 5) }
let_it_be(:created) { create_list(:design, 3) }
2020-11-24 15:15:51 +05:30
subject(:result) { service.save_designs(author, create: created, update: updated) }
2020-06-23 00:09:42 +05:30
specify { expect { result }.to change { Event.count }.by(8) }
2021-09-30 23:02:18 +05:30
# An addditional query due to event tracking
specify { expect { result }.not_to exceed_query_limit(2) }
2020-06-23 00:09:42 +05:30
it 'creates 3 created design events' do
ids = result.pluck('id')
events = Event.created_action.where(id: ids)
expect(events.map(&:design)).to match_array(created)
end
it 'creates 5 created design events' do
ids = result.pluck('id')
events = Event.updated_action.where(id: ids)
expect(events.map(&:design)).to match_array(updated)
end
2020-11-24 15:15:51 +05:30
it_behaves_like "it records the event in the event counter" do
let(:event_action) { Gitlab::UsageDataCounters::TrackUniqueEvents::DESIGN_ACTION }
2020-06-23 00:09:42 +05:30
end
2022-08-13 15:12:31 +05:30
it 'records correct create payload with Snowplow event' do
service.save_designs(author, create: [design])
expect_snowplow_event(
2022-10-11 01:57:18 +05:30
category: Gitlab::UsageDataCounters::TrackUniqueEvents::DESIGN_ACTION.to_s,
2022-08-13 15:12:31 +05:30
action: 'create',
2022-10-11 01:57:18 +05:30
namespace: design.project.namespace,
2022-08-13 15:12:31 +05:30
user: author,
project: design.project,
label: 'design_users'
)
end
it 'records correct update payload with Snowplow event' do
service.save_designs(author, update: [design])
expect_snowplow_event(
2022-10-11 01:57:18 +05:30
category: Gitlab::UsageDataCounters::TrackUniqueEvents::DESIGN_ACTION.to_s,
2022-08-13 15:12:31 +05:30
action: 'update',
2022-10-11 01:57:18 +05:30
namespace: design.project.namespace,
2022-08-13 15:12:31 +05:30
user: author,
project: design.project,
label: 'design_users'
)
end
context 'when FF is disabled' do
before do
stub_feature_flags(route_hll_to_snowplow_phase2: false)
end
it 'doesnt emit snowwplow events', :snowplow do
subject
expect_no_snowplow_event
end
end
2020-06-23 00:09:42 +05:30
end
describe '#destroy_designs' do
let_it_be(:designs) { create_list(:design, 5) }
let_it_be(:author) { create(:user) }
2020-11-24 15:15:51 +05:30
subject(:result) { service.destroy_designs(designs, author) }
2020-06-23 00:09:42 +05:30
specify { expect { result }.to change { Event.count }.by(5) }
2021-09-30 23:02:18 +05:30
# An addditional query due to event tracking
specify { expect { result }.not_to exceed_query_limit(2) }
2020-06-23 00:09:42 +05:30
it 'creates 5 destroyed design events' do
ids = result.pluck('id')
events = Event.destroyed_action.where(id: ids)
expect(events.map(&:design)).to match_array(designs)
end
2020-11-24 15:15:51 +05:30
it_behaves_like "it records the event in the event counter" do
let(:event_action) { Gitlab::UsageDataCounters::TrackUniqueEvents::DESIGN_ACTION }
end
2022-08-13 15:12:31 +05:30
it 'records correct payload with Snowplow event' do
service.destroy_designs([design], author)
expect_snowplow_event(
2022-10-11 01:57:18 +05:30
category: Gitlab::UsageDataCounters::TrackUniqueEvents::DESIGN_ACTION.to_s,
2022-08-13 15:12:31 +05:30
action: 'destroy',
2022-10-11 01:57:18 +05:30
namespace: design.project.namespace,
2022-08-13 15:12:31 +05:30
user: author,
project: design.project,
label: 'design_users'
)
end
context 'when FF is disabled' do
before do
stub_feature_flags(route_hll_to_snowplow_phase2: false)
end
2023-01-13 00:05:48 +05:30
it 'doesnt emit snowplow events', :snowplow do
2022-08-13 15:12:31 +05:30
subject
expect_no_snowplow_event
end
end
2020-11-24 15:15:51 +05:30
end
end
2022-07-23 23:45:48 +05:30
describe '#leave_note', :snowplow do
2020-11-24 15:15:51 +05:30
subject(:leave_note) { service.leave_note(note, author) }
let(:note) { create(:note) }
let(:author) { create(:user) }
let(:event_action) { Gitlab::UsageDataCounters::TrackUniqueEvents::MERGE_REQUEST_ACTION }
it { expect(leave_note).to be_truthy }
it "creates new event" do
expect { leave_note }.to change { Event.count }.by(1)
end
context 'when it is a diff note' do
2023-01-13 00:05:48 +05:30
let(:note) { create(:diff_note_on_merge_request) }
2022-07-23 23:45:48 +05:30
2023-01-13 00:05:48 +05:30
it_behaves_like "it records the event in the event counter"
it_behaves_like 'Snowplow event tracking with RedisHLL context' do
let(:feature_flag_name) { :route_hll_to_snowplow_phase2 }
2022-07-23 23:45:48 +05:30
let(:note) { create(:diff_note_on_merge_request) }
2023-01-13 00:05:48 +05:30
let(:category) { described_class.name }
let(:action) { 'commented' }
let(:label) { 'usage_activity_by_stage_monthly.create.merge_requests_users' }
2022-07-23 23:45:48 +05:30
let(:namespace) { project.namespace }
2023-01-13 00:05:48 +05:30
let(:project) { note.project }
2022-07-23 23:45:48 +05:30
let(:user) { author }
2023-01-13 00:05:48 +05:30
let(:context) do
[Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: 'merge_requests_users').to_context]
end
2022-07-23 23:45:48 +05:30
end
2020-11-24 15:15:51 +05:30
end
context 'when it is not a diff note' do
it 'does not change the unique action counter' do
counter_class = Gitlab::UsageDataCounters::TrackUniqueEvents
tracking_params = { event_action: event_action, date_from: Date.yesterday, date_to: Date.today }
2020-07-28 23:09:34 +05:30
2021-02-22 17:27:13 +05:30
expect { subject }.not_to change { counter_class.count_unique_events(**tracking_params) }
2020-06-23 00:09:42 +05:30
end
end
end
2014-09-02 18:07:02 +05:30
end