user_resolves_conflicts_spec.rb 7.5 KB
Newer Older
1 2
# frozen_string_literal: true

3
require 'spec_helper'
S
Sean McGivern 已提交
4

5
describe 'Merge request > User resolves conflicts', :js do
6
  let(:project) { create(:project, :repository) }
7
  let(:user) { project.creator }
S
Sean McGivern 已提交
8

9 10 11
  before do
    # In order to have the diffs collapsed, we need to disable the increase feature
    stub_feature_flags(gitlab_git_diff_size_limit_increase: false)
12
    stub_feature_flags(single_mr_diff_view: false)
13
  end
S
Sean McGivern 已提交
14 15

  def create_merge_request(source_branch)
16
    create(:merge_request, source_branch: source_branch, target_branch: 'conflict-start', source_project: project, merge_status: :unchecked) do |mr|
S
Sean McGivern 已提交
17 18 19 20
      mr.mark_as_unmergeable
    end
  end

21 22 23
  it_behaves_like 'rendering a single diff version'

  shared_examples 'conflicts are resolved in Interactive mode' do
24 25 26 27
    it 'conflicts are resolved in Interactive mode' do
      within find('.files-wrapper .diff-file', text: 'files/ruby/popen.rb') do
        click_button 'Use ours'
      end
S
Sean McGivern 已提交
28

29 30
      within find('.files-wrapper .diff-file', text: 'files/ruby/regex.rb') do
        all('button', text: 'Use ours').each do |button|
31
          button.send_keys(:return)
32 33
        end
      end
S
Sean McGivern 已提交
34

35
      find_button('Commit to source branch').send_keys(:return)
S
Sean McGivern 已提交
36

37 38
      expect(page).to have_content('All merge conflicts were resolved')
      merge_request.reload_diff
S
Sean McGivern 已提交
39

40 41
      wait_for_requests

42
      click_on 'Changes'
43
      wait_for_requests
S
Sean McGivern 已提交
44

45 46
      find('.js-toggle-tree-list').click

47 48 49
      within find('.diff-file', text: 'files/ruby/popen.rb') do
        expect(page).to have_selector('.line_content.new', text: "vars = { 'PWD' => path }")
        expect(page).to have_selector('.line_content.new', text: "options = { chdir: path }")
S
Sean McGivern 已提交
50
      end
51

52 53 54 55 56 57 58 59 60 61
      within find('.diff-file', text: 'files/ruby/regex.rb') do
        expect(page).to have_selector('.line_content.new', text: "def username_regexp")
        expect(page).to have_selector('.line_content.new', text: "def project_name_regexp")
        expect(page).to have_selector('.line_content.new', text: "def path_regexp")
        expect(page).to have_selector('.line_content.new', text: "def archive_formats_regexp")
        expect(page).to have_selector('.line_content.new', text: "def git_reference_regexp")
        expect(page).to have_selector('.line_content.new', text: "def default_regexp")
      end
    end
  end
62

63 64 65
  shared_examples "conflicts are resolved in Edit inline mode" do
    it 'conflicts are resolved in Edit inline mode' do
      expect(find('#conflicts')).to have_content('popen.rb')
66

67 68
      within find('.files-wrapper .diff-file', text: 'files/ruby/popen.rb') do
        click_button 'Edit inline'
69
        wait_for_requests
70
        find('.files-wrapper .diff-file pre')
71
        execute_script('ace.edit($(".files-wrapper .diff-file pre")[0]).setValue("One morning");')
72
      end
73 74 75

      within find('.files-wrapper .diff-file', text: 'files/ruby/regex.rb') do
        click_button 'Edit inline'
76
        wait_for_requests
77
        find('.files-wrapper .diff-file pre')
78 79 80
        execute_script('ace.edit($(".files-wrapper .diff-file pre")[1]).setValue("Gregor Samsa woke from troubled dreams");')
      end

81
      find_button('Commit to source branch').send_keys(:return)
82

83 84 85
      expect(page).to have_content('All merge conflicts were resolved')
      merge_request.reload_diff

86 87
      wait_for_requests

88
      click_on 'Changes'
89
      wait_for_requests
90 91 92

      expect(page).to have_content('One morning')
      expect(page).to have_content('Gregor Samsa woke from troubled dreams')
S
Sean McGivern 已提交
93 94 95
    end
  end

96
  context 'can be resolved in the UI' do
97
    before do
98
      project.add_developer(user)
99
      sign_in(user)
100 101 102 103 104
    end

    context 'the conflicts are resolvable' do
      let(:merge_request) { create_merge_request('conflict-resolvable') }

105
      before do
106
        visit project_merge_request_path(project, merge_request)
107
      end
108 109

      it 'shows a link to the conflict resolution page' do
110
        expect(page).to have_link('conflicts', href: %r{/conflicts\Z})
111 112 113
      end

      context 'in Inline view mode' do
114
        before do
115
          click_link('conflicts', href: %r{/conflicts\Z})
116
        end
117

118 119
        include_examples "conflicts are resolved in Interactive mode"
        include_examples "conflicts are resolved in Edit inline mode"
120 121 122 123
      end

      context 'in Parallel view mode' do
        before do
124
          click_link('conflicts', href: %r{/conflicts\Z})
125 126
          click_button 'Side-by-side'
        end
127

128 129
        include_examples "conflicts are resolved in Interactive mode"
        include_examples "conflicts are resolved in Edit inline mode"
130
      end
131 132
    end

133 134 135 136
    context 'the conflict contain markers' do
      let(:merge_request) { create_merge_request('conflict-contains-conflict-markers') }

      before do
137
        visit project_merge_request_path(project, merge_request)
138
        click_link('conflicts', href: %r{/conflicts\Z})
139 140 141 142 143 144 145 146
      end

      it 'conflicts can not be resolved in Interactive mode' do
        within find('.files-wrapper .diff-file', text: 'files/markdown/ruby-style-guide.md') do
          expect(page).not_to have_content 'Interactive mode'
          expect(page).not_to have_content 'Edit inline'
        end
      end
147

148
      # TODO: https://gitlab.com/gitlab-org/gitlab-foss/issues/48034
F
Felipe Artur 已提交
149
      xit 'conflicts are resolved in Edit inline mode' do
150
        within find('.files-wrapper .diff-file', text: 'files/markdown/ruby-style-guide.md') do
151
          wait_for_requests
152
          find('.files-wrapper .diff-file pre')
153
          execute_script('ace.edit($(".files-wrapper .diff-file pre")[0]).setValue("Gregor Samsa woke from troubled dreams");')
154 155
        end

156
        click_button 'Commit to source branch'
157 158 159 160 161

        expect(page).to have_content('All merge conflicts were resolved')

        merge_request.reload_diff

162 163
        wait_for_requests

164
        click_on 'Changes'
165
        wait_for_requests
166
        click_link 'Expand all'
167
        wait_for_requests
168 169 170 171

        expect(page).to have_content('Gregor Samsa woke from troubled dreams')
      end
    end
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

    context "with malicious branch name" do
      let(:bad_branch_name) { "malicious-branch-{{toString.constructor('alert(/xss/)')()}}" }
      let(:branch) { project.repository.create_branch(bad_branch_name, 'conflict-resolvable') }
      let(:merge_request) { create_merge_request(branch.name) }

      before do
        visit project_merge_request_path(project, merge_request)
        click_link('conflicts', href: %r{/conflicts\Z})
      end

      it "renders bad name without xss issues" do
        expect(find('.resolve-conflicts-form .resolve-info')).to have_content(bad_branch_name)
      end
    end
187 188
  end

S
Sean McGivern 已提交
189 190 191
  UNRESOLVABLE_CONFLICTS = {
    'conflict-too-large' => 'when the conflicts contain a large file',
    'conflict-binary-file' => 'when the conflicts contain a binary file',
192
    'conflict-missing-side' => 'when the conflicts contain a file edited in one branch and deleted in another',
193
    'conflict-non-utf8' => 'when the conflicts contain a non-UTF-8 file'
D
Douwe Maan 已提交
194
  }.freeze
S
Sean McGivern 已提交
195 196 197 198 199 200

  UNRESOLVABLE_CONFLICTS.each do |source_branch, description|
    context description do
      let(:merge_request) { create_merge_request(source_branch) }

      before do
201
        project.add_developer(user)
202
        sign_in(user)
203
        visit project_merge_request_path(project, merge_request)
S
Sean McGivern 已提交
204 205 206
      end

      it 'does not show a link to the conflict resolution page' do
207
        expect(page).not_to have_link('conflicts', href: %r{/conflicts\Z})
S
Sean McGivern 已提交
208 209 210 211
      end

      it 'shows an error if the conflicts page is visited directly' do
        visit current_url + '/conflicts'
212
        wait_for_requests
S
Sean McGivern 已提交
213

214
        expect(find('#conflicts')).to have_content('Please try to resolve them locally.')
S
Sean McGivern 已提交
215 216 217 218
      end
    end
  end
end