BigW Consortium Gitlab

widget_spec.rb 9.23 KB
Newer Older
1 2
require 'rails_helper'

3
describe 'Merge request', :js do
4
  let(:user) { create(:user) }
5
  let(:project) { create(:project, :repository) }
6
  let(:project_only_mwps) { create(:project, :repository, only_allow_merge_if_pipeline_succeeds: true) }
7
  let(:merge_request) { create(:merge_request, source_project: project) }
8
  let(:merge_request_in_only_mwps_project) { create(:merge_request, source_project: project_only_mwps) }
9 10

  before do
11 12
    project.add_master(user)
    project_only_mwps.add_master(user)
13
    sign_in(user)
14
  end
15

16 17
  context 'new merge request' do
    before do
18
      visit project_new_merge_request_path(
19 20 21 22 23 24
        project,
        merge_request: {
          source_project_id: project.id,
          target_project_id: project.id,
          source_branch: 'feature',
          target_branch: 'master'
25
        })
26 27 28 29 30
    end

    it 'shows widget status after creating new merge request' do
      click_button 'Submit merge request'

31
      wait_for_requests
32

33
      expect(page).to have_selector('.accept-merge-request')
34
      expect(find('.accept-merge-request')['disabled']).not_to be(true)
35
    end
36 37
  end

38 39
  context 'view merge request' do
    let!(:environment) { create(:environment, project: project) }
40 41 42 43 44 45

    let!(:deployment) do
      create(:deployment, environment: environment,
                          ref: 'feature',
                          sha: merge_request.diff_head_sha)
    end
46

47
    before do
48
      visit project_merge_request_path(project, merge_request)
49
    end
50

51
    it 'shows environments link' do
52
      wait_for_requests
53

54 55
      page.within('.mr-widget-heading') do
        expect(page).to have_content("Deployed to #{environment.name}")
56
        expect(find('.js-deploy-url')[:href]).to include(environment.formatted_external_url)
57 58
      end
    end
59 60 61

    it 'shows green accept merge request button' do
      # Wait for the `ci_status` and `merge_check` requests
62
      wait_for_requests
63 64
      expect(page).to have_selector('.accept-merge-request')
      expect(find('.accept-merge-request')['disabled']).not_to be(true)
65 66 67 68 69 70 71 72 73 74
    end
  end

  context 'view merge request with external CI service' do
    before do
      create(:service, project: project,
                       active: true,
                       type: 'CiService',
                       category: 'ci')

75
      visit project_merge_request_path(project, merge_request)
76 77 78 79
    end

    it 'has danger button while waiting for external CI status' do
      # Wait for the `ci_status` and `merge_check` requests
80
      wait_for_requests
81 82 83 84 85 86 87 88 89 90 91
      expect(page).to have_selector('.accept-merge-request.btn-danger')
    end
  end

  context 'view merge request with failed GitLab CI pipelines' do
    before do
      commit_status = create(:commit_status, project: project, status: 'failed')
      pipeline = create(:ci_pipeline, project: project,
                                      sha: merge_request.diff_head_sha,
                                      ref: merge_request.source_branch,
                                      status: 'failed',
92 93
                                      statuses: [commit_status],
                                      head_pipeline_of: merge_request)
94 95
      create(:ci_build, :pending, pipeline: pipeline)

96
      visit project_merge_request_path(project, merge_request)
97 98 99 100
    end

    it 'has danger button when not succeeded' do
      # Wait for the `ci_status` and `merge_check` requests
101
      wait_for_requests
102 103 104 105
      expect(page).to have_selector('.accept-merge-request.btn-danger')
    end
  end

106 107
  context 'when merge request is in the blocked pipeline state' do
    before do
108
      create(
Felipe Artur committed
109 110 111 112
        :ci_pipeline,
        project: project,
        sha: merge_request.diff_head_sha,
        ref: merge_request.source_branch,
113 114
        status: :manual,
        head_pipeline_of: merge_request)
115

116
      visit project_merge_request_path(project, merge_request)
117 118 119 120 121 122 123 124 125 126
    end

    it 'shows information about blocked pipeline' do
      expect(page).to have_content("Pipeline blocked")
      expect(page).to have_content(
        "The pipeline for this merge request requires a manual action")
      expect(page).to have_css('.ci-status-icon-manual')
    end
  end

127 128 129 130 131 132 133
  context 'view merge request with MWBS button' do
    before do
      commit_status = create(:commit_status, project: project, status: 'pending')
      pipeline = create(:ci_pipeline, project: project,
                                      sha: merge_request.diff_head_sha,
                                      ref: merge_request.source_branch,
                                      status: 'pending',
134 135
                                      statuses: [commit_status],
                                      head_pipeline_of: merge_request)
136 137
      create(:ci_build, :pending, pipeline: pipeline)

138
      visit project_merge_request_path(project, merge_request)
139 140 141 142
    end

    it 'has info button when MWBS button' do
      # Wait for the `ci_status` and `merge_check` requests
143
      wait_for_requests
144 145 146 147
      expect(page).to have_selector('.accept-merge-request.btn-info')
    end
  end

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
  context 'view merge request where project has CI setup but no CI status' do
    before do
      pipeline = create(:ci_pipeline, project: project,
                                      sha: merge_request.diff_head_sha,
                                      ref: merge_request.source_branch)
      create(:ci_build, pipeline: pipeline)

      visit project_merge_request_path(project, merge_request)
    end

    it 'has pipeline error text' do
      # Wait for the `ci_status` and `merge_check` requests
      wait_for_requests

      expect(page).to have_text('Could not connect to the CI server. Please check your settings and try again')
    end
  end

166 167 168 169 170 171 172 173 174 175 176 177 178 179
  context 'view merge request in project with only-mwps setting enabled but no CI is setup' do
    before do
      visit project_merge_request_path(project_only_mwps, merge_request_in_only_mwps_project)
    end

    it 'should be allowed to merge' do
      # Wait for the `ci_status` and `merge_check` requests
      wait_for_requests

      expect(page).to have_selector('.accept-merge-request')
      expect(find('.accept-merge-request')['disabled']).not_to be(true)
    end
  end

180 181 182 183 184 185 186 187
  context 'view merge request with MWPS enabled but automatically merge fails' do
    before do
      merge_request.update(
        merge_when_pipeline_succeeds: true,
        merge_user: merge_request.author,
        merge_error: 'Something went wrong'
      )

188
      visit project_merge_request_path(project, merge_request)
189 190 191 192
    end

    it 'shows information about the merge error' do
      # Wait for the `ci_status` and `merge_check` requests
193
      wait_for_requests
194 195 196 197

      page.within('.mr-widget-body') do
        expect(page).to have_content('Something went wrong')
      end
198
    end
199
  end
200

201 202 203 204 205 206 207 208
  context 'view merge request with MWPS enabled but automatically merge fails' do
    before do
      merge_request.update(
        merge_when_pipeline_succeeds: true,
        merge_user: merge_request.author,
        merge_error: 'Something went wrong'
      )

209
      visit project_merge_request_path(project, merge_request)
210 211 212 213
    end

    it 'shows information about the merge error' do
      # Wait for the `ci_status` and `merge_check` requests
214
      wait_for_requests
215 216 217 218 219 220 221

      page.within('.mr-widget-body') do
        expect(page).to have_content('Something went wrong')
      end
    end
  end

222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
  context 'view merge request where fast-forward merge is not possible' do
    before do
      project.update(merge_requests_ff_only_enabled: true)

      merge_request.update(
        merge_user: merge_request.author,
        merge_status: :cannot_be_merged
      )

      visit project_merge_request_path(project, merge_request)
    end

    it 'shows information about the merge error' do
      # Wait for the `ci_status` and `merge_check` requests
      wait_for_requests

      page.within('.mr-widget-body') do
        expect(page).to have_content('Fast-forward merge is not possible')
      end
    end
  end

244 245 246
  context 'merge error' do
    before do
      allow_any_instance_of(Repository).to receive(:merge).and_return(false)
247
      visit project_merge_request_path(project, merge_request)
248 249 250
    end

    it 'updates the MR widget' do
251 252
      click_button 'Merge'

253 254 255 256 257
      page.within('.mr-widget-body') do
        expect(page).to have_content('Conflicts detected during merge')
      end
    end
  end
258

259
  context 'user can merge into source project but cannot push to fork', :js do
260
    let(:fork_project) { create(:project, :public, :repository) }
261 262 263 264
    let(:user2) { create(:user) }

    before do
      project.team << [user2, :master]
265 266
      sign_out(:user)
      sign_in(user2)
267
      merge_request.update(target_project: fork_project)
268
      visit project_merge_request_path(project, merge_request)
269 270 271 272 273 274 275 276 277 278
    end

    it 'user can merge into the source project' do
      expect(page).to have_button('Merge', disabled: false)
    end

    it 'user cannot remove source branch' do
      expect(page).to have_field('remove-source-branch-input', disabled: true)
    end
  end
279 280 281 282 283 284 285 286 287 288 289 290 291

  context 'ongoing merge process' do
    it 'shows Merging state' do
      allow_any_instance_of(MergeRequest).to receive(:merge_ongoing?).and_return(true)

      visit project_merge_request_path(project, merge_request)

      wait_for_requests

      expect(page).not_to have_button('Merge')
      expect(page).to have_content('This merge request is in the process of being merged')
    end
  end
292
end