summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/analytics/cycle_analytics
diff options
context:
space:
mode:
Diffstat (limited to 'spec/lib/gitlab/analytics/cycle_analytics')
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb62
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb131
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb22
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_created_spec.rb7
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit_spec.rb7
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end_spec.rb7
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created_spec.rb7
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production_spec.rb7
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished_spec.rb7
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started_spec.rb7
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged_spec.rb7
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start_spec.rb24
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb7
13 files changed, 300 insertions, 2 deletions
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb
new file mode 100644
index 00000000000..0fc9d3c1e9e
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/base_query_builder_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::BaseQueryBuilder do
+ let_it_be(:project) { create(:project, :empty_repo) }
+ let_it_be(:mr1) { create(:merge_request, target_project: project, source_project: project, allow_broken: true, created_at: 3.months.ago) }
+ let_it_be(:mr2) { create(:merge_request, target_project: project, source_project: project, allow_broken: true, created_at: 1.month.ago) }
+ let(:params) { {} }
+ let(:records) do
+ stage = build(:cycle_analytics_project_stage, {
+ start_event_identifier: :merge_request_created,
+ end_event_identifier: :merge_request_merged,
+ project: project
+ })
+ described_class.new(stage: stage, params: params).build.to_a
+ end
+
+ before do
+ mr1.metrics.update!(merged_at: 1.month.ago)
+ mr2.metrics.update!(merged_at: Time.now)
+ end
+
+ around do |example|
+ Timecop.freeze { example.run }
+ end
+
+ describe 'date range parameters' do
+ context 'when filters by only the `from` parameter' do
+ before do
+ params[:from] = 4.months.ago
+ end
+
+ it { expect(records.size).to eq(2) }
+ end
+
+ context 'when filters by both `from` and `to` parameters' do
+ before do
+ params.merge!(from: 4.months.ago, to: 2.months.ago)
+ end
+
+ it { expect(records.size).to eq(1) }
+ end
+
+ context 'invalid date range is provided' do
+ before do
+ params.merge!(from: 1.month.ago, to: 10.months.ago)
+ end
+
+ it { expect(records.size).to eq(0) }
+ end
+ end
+
+ it 'scopes query within the target project' do
+ other_mr = create(:merge_request, source_project: create(:project), allow_broken: true, created_at: 2.months.ago)
+ other_mr.metrics.update!(merged_at: 1.month.ago)
+
+ params[:from] = 1.year.ago
+
+ expect(records.size).to eq(2)
+ end
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb
new file mode 100644
index 00000000000..334cab0b799
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb
@@ -0,0 +1,131 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::RecordsFetcher do
+ around do |example|
+ Timecop.freeze { example.run }
+ end
+
+ let_it_be(:project) { create(:project, :empty_repo) }
+ let_it_be(:user) { create(:user) }
+
+ subject do
+ Gitlab::Analytics::CycleAnalytics::DataCollector.new(
+ stage: stage,
+ params: {
+ from: 1.year.ago,
+ current_user: user
+ }
+ ).records_fetcher.serialized_records
+ end
+
+ describe '#serialized_records' do
+ shared_context 'when records are loaded by maintainer' do
+ before do
+ project.add_user(user, Gitlab::Access::MAINTAINER)
+ end
+
+ it 'returns all records' do
+ expect(subject.size).to eq(2)
+ end
+ end
+
+ describe 'for issue based stage' do
+ let_it_be(:issue1) { create(:issue, project: project) }
+ let_it_be(:issue2) { create(:issue, project: project, confidential: true) }
+ let(:stage) do
+ build(:cycle_analytics_project_stage, {
+ start_event_identifier: :plan_stage_start,
+ end_event_identifier: :issue_first_mentioned_in_commit,
+ project: project
+ })
+ end
+
+ before do
+ issue1.metrics.update(first_added_to_board_at: 3.days.ago, first_mentioned_in_commit_at: 2.days.ago)
+ issue2.metrics.update(first_added_to_board_at: 3.days.ago, first_mentioned_in_commit_at: 2.days.ago)
+ end
+
+ context 'when records are loaded by guest' do
+ before do
+ project.add_user(user, Gitlab::Access::GUEST)
+ end
+
+ it 'filters out confidential issues' do
+ expect(subject.size).to eq(1)
+ expect(subject.first[:iid].to_s).to eq(issue1.iid.to_s)
+ end
+ end
+
+ include_context 'when records are loaded by maintainer'
+ end
+
+ describe 'for merge request based stage' do
+ let(:mr1) { create(:merge_request, created_at: 5.days.ago, source_project: project, allow_broken: true) }
+ let(:mr2) { create(:merge_request, created_at: 4.days.ago, source_project: project, allow_broken: true) }
+ let(:stage) do
+ build(:cycle_analytics_project_stage, {
+ start_event_identifier: :merge_request_created,
+ end_event_identifier: :merge_request_merged,
+ project: project
+ })
+ end
+
+ before do
+ mr1.metrics.update(merged_at: 3.days.ago)
+ mr2.metrics.update(merged_at: 3.days.ago)
+ end
+
+ include_context 'when records are loaded by maintainer'
+ end
+
+ describe 'special case' do
+ let(:mr1) { create(:merge_request, source_project: project, allow_broken: true, created_at: 20.days.ago) }
+ let(:mr2) { create(:merge_request, source_project: project, allow_broken: true, created_at: 19.days.ago) }
+ let(:ci_build1) { create(:ci_build) }
+ let(:ci_build2) { create(:ci_build) }
+ let(:default_stages) { Gitlab::Analytics::CycleAnalytics::DefaultStages }
+ let(:stage) { build(:cycle_analytics_project_stage, default_stages.params_for_test_stage.merge(project: project)) }
+
+ before do
+ mr1.metrics.update!({
+ merged_at: 5.days.ago,
+ first_deployed_to_production_at: 1.day.ago,
+ latest_build_started_at: 5.days.ago,
+ latest_build_finished_at: 1.day.ago,
+ pipeline: ci_build1.pipeline
+ })
+ mr2.metrics.update!({
+ merged_at: 10.days.ago,
+ first_deployed_to_production_at: 5.days.ago,
+ latest_build_started_at: 9.days.ago,
+ latest_build_finished_at: 7.days.ago,
+ pipeline: ci_build2.pipeline
+ })
+ end
+
+ context 'returns build records' do
+ shared_examples 'orders build records by `latest_build_finished_at`' do
+ it 'orders by `latest_build_finished_at`' do
+ build_ids = subject.map { |item| item[:id] }
+
+ expect(build_ids).to eq([ci_build1.id, ci_build2.id])
+ end
+ end
+
+ context 'when requesting records for default test stage' do
+ include_examples 'orders build records by `latest_build_finished_at`'
+ end
+
+ context 'when requesting records for default staging stage' do
+ before do
+ stage.assign_attributes(default_stages.params_for_staging_stage)
+ end
+
+ include_examples 'orders build records by `latest_build_finished_at`'
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb
new file mode 100644
index 00000000000..29c8d548754
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/code_stage_start_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::CodeStageStart do
+ let(:subject) { described_class.new({}) }
+ let(:project) { create(:project) }
+
+ it_behaves_like 'cycle analytics event'
+
+ it 'needs connection with an issue via merge_requests_closing_issues table' do
+ issue = create(:issue, project: project)
+ merge_request = create(:merge_request, source_project: project)
+ create(:merge_requests_closing_issues, issue: issue, merge_request: merge_request)
+
+ other_merge_request = create(:merge_request, source_project: project, source_branch: 'a', target_branch: 'master')
+
+ records = subject.apply_query_customization(MergeRequest.all)
+ expect(records).to eq([merge_request])
+ expect(records).not_to include(other_merge_request)
+ end
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_created_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_created_spec.rb
new file mode 100644
index 00000000000..efdef91c5a2
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_created_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::IssueCreated do
+ it_behaves_like 'cycle analytics event'
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit_spec.rb
new file mode 100644
index 00000000000..50883e1c1e2
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_first_mentioned_in_commit_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::IssueFirstMentionedInCommit do
+ it_behaves_like 'cycle analytics event'
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end_spec.rb
new file mode 100644
index 00000000000..85062db370a
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/issue_stage_end_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::IssueStageEnd do
+ it_behaves_like 'cycle analytics event'
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created_spec.rb
new file mode 100644
index 00000000000..7858b810661
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_created_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestCreated do
+ it_behaves_like 'cycle analytics event'
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production_spec.rb
new file mode 100644
index 00000000000..ba9d8be5a2c
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_first_deployed_to_production_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestFirstDeployedToProduction do
+ it_behaves_like 'cycle analytics event'
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished_spec.rb
new file mode 100644
index 00000000000..8e83e10ef96
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_finished_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestLastBuildFinished do
+ it_behaves_like 'cycle analytics event'
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started_spec.rb
new file mode 100644
index 00000000000..9f6b430a320
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_last_build_started_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestLastBuildStarted do
+ it_behaves_like 'cycle analytics event'
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged_spec.rb
new file mode 100644
index 00000000000..ce2aa0a60db
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/merge_request_merged_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::MergeRequestMerged do
+ it_behaves_like 'cycle analytics event'
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start_spec.rb
new file mode 100644
index 00000000000..cb63139f0a8
--- /dev/null
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/plan_stage_start_spec.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Analytics::CycleAnalytics::StageEvents::PlanStageStart do
+ let(:subject) { described_class.new({}) }
+ let(:project) { create(:project) }
+
+ it_behaves_like 'cycle analytics event'
+
+ it 'filters issues where first_associated_with_milestone_at or first_added_to_board_at is filled' do
+ issue1 = create(:issue, project: project)
+ issue1.metrics.update!(first_added_to_board_at: 1.month.ago, first_mentioned_in_commit_at: 2.months.ago)
+
+ issue2 = create(:issue, project: project)
+ issue2.metrics.update!(first_associated_with_milestone_at: 1.month.ago, first_mentioned_in_commit_at: 2.months.ago)
+
+ issue_without_metrics = create(:issue, project: project)
+
+ records = subject.apply_query_customization(Issue.all)
+ expect(records).to match_array([issue1, issue2])
+ expect(records).not_to include(issue_without_metrics)
+ end
+end
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb
index 29f4be76a65..b05faf5d813 100644
--- a/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb
+++ b/spec/lib/gitlab/analytics/cycle_analytics/stage_events/stage_event_spec.rb
@@ -3,8 +3,11 @@
require 'spec_helper'
describe Gitlab::Analytics::CycleAnalytics::StageEvents::StageEvent do
+ let(:instance) { described_class.new({}) }
+
it { expect(described_class).to respond_to(:name) }
it { expect(described_class).to respond_to(:identifier) }
-
- it { expect(described_class.new({})).to respond_to(:object_type) }
+ it { expect(instance).to respond_to(:object_type) }
+ it { expect(instance).to respond_to(:timestamp_projection) }
+ it { expect(instance).to respond_to(:apply_query_customization) }
end