summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/background_migration/populate_merge_request_metrics_with_events_data_spec.rb
blob: 4cdb679c97f56bf0b5e247424c96e741dd2eef05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
require 'rails_helper'

describe Gitlab::BackgroundMigration::PopulateMergeRequestMetricsWithEventsData, :migration, schema: 20171128214150 do
  # commits_count attribute is added in a next migration
  before do
    allow_any_instance_of(MergeRequestDiff)
      .to receive(:commits_count=).and_return(nil)
  end

  after do
    [MergeRequest, MergeRequestDiff].each(&:reset_column_information)
  end

  describe '#perform' do
    let(:mr_with_event) { create(:merge_request) }
    let!(:merged_event) { create(:event, :merged, target: mr_with_event) }
    let!(:closed_event) { create(:event, :closed, target: mr_with_event) }

    before do
      # Make sure no metrics are created and kept through after_* callbacks.
      mr_with_event.metrics.destroy!
    end

    it 'inserts metrics and updates closed and merged events' do
      subject.perform(mr_with_event.id, mr_with_event.id)

      mr_with_event.reload

      expect(mr_with_event.metrics).to have_attributes(latest_closed_by_id: closed_event.author_id,
                                                       merged_by_id: merged_event.author_id)
      expect(mr_with_event.metrics.latest_closed_at.to_s).to eq(closed_event.updated_at.to_s)
    end
  end

  describe '#insert_metrics_for_range' do
    let!(:mrs_without_metrics) { create_list(:merge_request, 3) }
    let!(:mrs_with_metrics) { create_list(:merge_request, 2) }

    before do
      # Make sure no metrics are created and kept through after_* callbacks.
      mrs_without_metrics.each { |m| m.metrics.destroy! }
    end

    it 'inserts merge_request_metrics for merge_requests without one' do
      expect { subject.insert_metrics_for_range(MergeRequest.first.id, MergeRequest.last.id) }
        .to change(MergeRequest::Metrics, :count).from(2).to(5)

      mrs_without_metrics.each do |mr_without_metrics|
        expect(mr_without_metrics.reload.metrics).to be_present
      end
    end

    it 'does not inserts merge_request_metrics for MRs out of given range' do
      expect { subject.insert_metrics_for_range(mrs_with_metrics.first.id, mrs_with_metrics.last.id) }
        .not_to change(MergeRequest::Metrics, :count).from(2)
    end
  end

  describe '#update_metrics_with_events_data' do
    context 'closed events data update' do
      let(:users) { create_list(:user, 3) }
      let(:mrs_with_event) { create_list(:merge_request, 3) }

      before do
        create_list(:event, 2, :closed, author: users.first, target: mrs_with_event.first)
        create_list(:event, 3, :closed, author: users.second, target: mrs_with_event.second)
        create(:event, :closed, author: users.third, target: mrs_with_event.third)
      end

      it 'migrates multiple MR metrics with closed event data' do
        mr_without_event = create(:merge_request)
        create(:event, :merged)

        subject.update_metrics_with_events_data(mrs_with_event.first.id, mrs_with_event.last.id)

        mrs_with_event.each do |mr_with_event|
          latest_event = Event.where(action: 3, target: mr_with_event).last

          mr_with_event.metrics.reload

          expect(mr_with_event.metrics.latest_closed_by).to eq(latest_event.author)
          expect(mr_with_event.metrics.latest_closed_at.to_s).to eq(latest_event.updated_at.to_s)
        end

        expect(mr_without_event.metrics.reload).to have_attributes(latest_closed_by_id: nil,
                                                                   latest_closed_at: nil)
      end

      it 'does not updates metrics out of given range' do
        out_of_range_mr = create(:merge_request)
        create(:event, :closed, author: users.last, target: out_of_range_mr)

        expect { subject.perform(mrs_with_event.first.id, mrs_with_event.second.id) }
          .not_to change { out_of_range_mr.metrics.reload.merged_by }
          .from(nil)
      end
    end

    context 'merged events data update' do
      let(:users) { create_list(:user, 3) }
      let(:mrs_with_event) { create_list(:merge_request, 3) }

      before do
        create_list(:event, 2, :merged, author: users.first, target: mrs_with_event.first)
        create_list(:event, 3, :merged, author: users.second, target: mrs_with_event.second)
        create(:event, :merged, author: users.third, target: mrs_with_event.third)
      end

      it 'migrates multiple MR metrics with merged event data' do
        mr_without_event = create(:merge_request)
        create(:event, :merged)

        subject.update_metrics_with_events_data(mrs_with_event.first.id, mrs_with_event.last.id)

        mrs_with_event.each do |mr_with_event|
          latest_event = Event.where(action: Event::MERGED, target: mr_with_event).last

          expect(mr_with_event.metrics.reload.merged_by).to eq(latest_event.author)
        end

        expect(mr_without_event.metrics.reload).to have_attributes(merged_by_id: nil)
      end

      it 'does not updates metrics out of given range' do
        out_of_range_mr = create(:merge_request)
        create(:event, :merged, author: users.last, target: out_of_range_mr)

        expect { subject.perform(mrs_with_event.first.id, mrs_with_event.second.id) }
          .not_to change { out_of_range_mr.metrics.reload.merged_by }
          .from(nil)
      end
    end
  end
end