1# frozen_string_literal: true
2
3require 'spec_helper'
4
5RSpec.describe MergeRequestPollWidgetEntity do
6  include ProjectForksHelper
7  using RSpec::Parameterized::TableSyntax
8
9  let_it_be(:project)  { create :project, :repository }
10  let_it_be(:resource) { create(:merge_request, source_project: project, target_project: project) }
11  let_it_be(:user)     { create(:user) }
12
13  let(:request) { double('request', current_user: user, project: project) }
14  let(:options) { {} }
15
16  subject do
17    described_class.new(resource, { request: request }.merge(options)).as_json
18  end
19
20  it 'has default_merge_commit_message_with_description' do
21    expect(subject[:default_merge_commit_message_with_description])
22      .to eq(resource.default_merge_commit_message(include_description: true))
23  end
24
25  describe 'new_blob_path' do
26    context 'when user can push to project' do
27      it 'returns path' do
28        project.add_developer(user)
29
30        expect(subject[:new_blob_path])
31          .to eq("/#{resource.project.full_path}/-/new/#{resource.source_branch}")
32      end
33    end
34
35    context 'when user cannot push to project' do
36      it 'returns nil' do
37        expect(subject[:new_blob_path]).to be_nil
38      end
39    end
40  end
41
42  describe 'auto merge' do
43    before do
44      project.add_maintainer(user)
45    end
46
47    context 'when auto merge is enabled' do
48      let(:resource) { create(:merge_request, :merge_when_pipeline_succeeds) }
49
50      it 'returns auto merge related information' do
51        expect(subject[:auto_merge_strategy]).to eq('merge_when_pipeline_succeeds')
52      end
53    end
54
55    context 'when auto merge is not enabled' do
56      let(:resource) { create(:merge_request) }
57
58      it 'returns auto merge related information' do
59        expect(subject[:auto_merge_strategy]).to be_nil
60      end
61    end
62
63    context 'when head pipeline is running' do
64      before do
65        create(:ci_pipeline, :running, project: project,
66                                       ref: resource.source_branch,
67                                       sha: resource.diff_head_sha)
68        resource.update_head_pipeline
69      end
70
71      it 'returns available auto merge strategies' do
72        expect(subject[:available_auto_merge_strategies]).to eq(%w[merge_when_pipeline_succeeds])
73      end
74    end
75
76    describe 'squash defaults for projects' do
77      where(:squash_option, :value, :default, :readonly) do
78        'always'      | true  | true  | true
79        'never'       | false | false | true
80        'default_on'  | false | true  | false
81        'default_off' | false | false | false
82      end
83
84      with_them do
85        before do
86          project.project_setting.update!(squash_option: squash_option)
87        end
88
89        it 'the key reflects the correct value' do
90          expect(subject[:squash_on_merge]).to eq(value)
91          expect(subject[:squash_enabled_by_default]).to eq(default)
92          expect(subject[:squash_readonly]).to eq(readonly)
93        end
94      end
95    end
96
97    context 'when head pipeline is finished' do
98      before do
99        create(:ci_pipeline, :success, project: project,
100                                       ref: resource.source_branch,
101                                       sha: resource.diff_head_sha)
102        resource.update_head_pipeline
103      end
104
105      it 'returns available auto merge strategies' do
106        expect(subject[:available_auto_merge_strategies]).to be_empty
107      end
108    end
109  end
110
111  describe 'pipeline' do
112    let!(:pipeline) { create(:ci_empty_pipeline, project: project, ref: resource.source_branch, sha: resource.source_branch_sha, head_pipeline_of: resource) }
113
114    before do
115      allow_any_instance_of(MergeRequestPresenter).to receive(:can?).and_call_original
116      allow_any_instance_of(MergeRequestPresenter).to receive(:can?).with(user, :read_pipeline, anything).and_return(result)
117    end
118
119    context 'when user has access to pipelines' do
120      let(:result) { true }
121
122      context 'when is up to date' do
123        let(:req) { double('request', current_user: user, project: project) }
124
125        it 'does not return pipeline' do
126          expect(subject[:pipeline]).to be_nil
127        end
128
129        it 'returns ci_status' do
130          expect(subject[:ci_status]).to eq('pending')
131        end
132      end
133
134      context 'when is not up to date' do
135        it 'returns nil' do
136          pipeline.update!(sha: "not up to date")
137
138          expect(subject[:pipeline]).to eq(nil)
139        end
140      end
141    end
142
143    context 'when user does not have access to pipelines' do
144      let(:result) { false }
145      let(:req) { double('request', current_user: user, project: project) }
146
147      it 'does not return ci_status' do
148        expect(subject[:ci_status]).to eq(nil)
149      end
150    end
151  end
152
153  describe '#builds_with_coverage' do
154    it 'serializes the builds with coverage' do
155      allow(resource).to receive(:head_pipeline_builds_with_coverage).and_return([
156        double(name: 'rspec', coverage: 91.5),
157        double(name: 'jest', coverage: 94.1)
158      ])
159
160      result = subject[:builds_with_coverage]
161
162      expect(result).to eq([
163        { name: 'rspec', coverage: 91.5 },
164        { name: 'jest', coverage: 94.1 }
165      ])
166    end
167  end
168
169  describe '#mergeable' do
170    it 'shows whether a merge request is mergeable' do
171      expect(subject[:mergeable]).to eq(true)
172    end
173
174    context 'when merge request is in checking state' do
175      before do
176        resource.mark_as_unchecked!
177        resource.mark_as_checking!
178      end
179
180      it 'calculates mergeability and returns true' do
181        expect(subject[:mergeable]).to eq(true)
182      end
183
184      context 'when check_mergeability_async_in_widget is disabled' do
185        before do
186          stub_feature_flags(check_mergeability_async_in_widget: false)
187        end
188
189        it 'calculates mergeability and returns true' do
190          expect(subject[:mergeable]).to eq(true)
191        end
192      end
193    end
194  end
195end
196