BigW Consortium Gitlab

conflicts_spec.rb 6.5 KB
Newer Older
1 2
require 'spec_helper'

3
feature 'Merge request conflict resolution', :js do
4
  let(:user) { create(:user) }
5
  let(:project) { create(:project, :repository) }
6

7 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)
  end

12 13 14 15 16 17
  def create_merge_request(source_branch)
    create(:merge_request, source_branch: source_branch, target_branch: 'conflict-start', source_project: project) do |mr|
      mr.mark_as_unmergeable
    end
  end

18 19 20 21 22
  shared_examples "conflicts are resolved in Interactive mode" do
    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
23

24 25
      within find('.files-wrapper .diff-file', text: 'files/ruby/regex.rb') do
        all('button', text: 'Use ours').each do |button|
26
          button.trigger('click')
27 28
        end
      end
29

30
      click_button 'Commit conflict resolution'
31

32 33
      expect(page).to have_content('All merge conflicts were resolved')
      merge_request.reload_diff
34

35 36
      wait_for_requests

37
      click_on 'Changes'
38
      wait_for_requests
39

40 41 42
      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 }")
43
      end
44

45 46 47 48 49 50 51 52 53 54
      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
55

56 57 58
  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')
59

60 61
      within find('.files-wrapper .diff-file', text: 'files/ruby/popen.rb') do
        click_button 'Edit inline'
62
        wait_for_requests
63
        execute_script('ace.edit($(".files-wrapper .diff-file pre")[0]).setValue("One morning");')
64
      end
65 66 67

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

      click_button 'Commit conflict resolution'
73

74 75 76
      expect(page).to have_content('All merge conflicts were resolved')
      merge_request.reload_diff

77 78
      wait_for_requests

79
      click_on 'Changes'
80
      wait_for_requests
81 82 83

      expect(page).to have_content('One morning')
      expect(page).to have_content('Gregor Samsa woke from troubled dreams')
84 85 86
    end
  end

87
  context 'can be resolved in the UI' do
88 89
    before do
      project.team << [user, :developer]
90
      sign_in(user)
91 92 93 94 95
    end

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

96
      before do
97
        visit project_merge_request_path(project, merge_request)
98
      end
99 100 101 102 103 104

      it 'shows a link to the conflict resolution page' do
        expect(page).to have_link('conflicts', href: /\/conflicts\Z/)
      end

      context 'in Inline view mode' do
105 106 107
        before do
          click_link('conflicts', href: /\/conflicts\Z/)
        end
108 109 110 111 112 113 114

        include_examples "conflicts are resolved in Interactive mode"
        include_examples "conflicts are resolved in Edit inline mode"
      end

      context 'in Parallel view mode' do
        before do
115
          click_link('conflicts', href: /\/conflicts\Z/)
116 117
          click_button 'Side-by-side'
        end
118

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

124 125 126 127
    context 'the conflict contain markers' do
      let(:merge_request) { create_merge_request('conflict-contains-conflict-markers') }

      before do
128
        visit project_merge_request_path(project, merge_request)
129 130 131 132 133 134 135 136 137
        click_link('conflicts', href: /\/conflicts\Z/)
      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
138

139
      it 'conflicts are resolved in Edit inline mode' do
140
        within find('.files-wrapper .diff-file', text: 'files/markdown/ruby-style-guide.md') do
141
          wait_for_requests
142
          execute_script('ace.edit($(".files-wrapper .diff-file pre")[0]).setValue("Gregor Samsa woke from troubled dreams");')
143 144 145 146 147 148 149 150
        end

        click_button 'Commit conflict resolution'

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

        merge_request.reload_diff

151 152
        wait_for_requests

153
        click_on 'Changes'
154
        wait_for_requests
155
        click_link 'Expand all'
156
        wait_for_requests
157 158 159 160 161 162

        expect(page).to have_content('Gregor Samsa woke from troubled dreams')
      end
    end
  end

163 164 165
  UNRESOLVABLE_CONFLICTS = {
    'conflict-too-large' => 'when the conflicts contain a large file',
    'conflict-binary-file' => 'when the conflicts contain a binary file',
166
    'conflict-missing-side' => 'when the conflicts contain a file edited in one branch and deleted in another',
167
    'conflict-non-utf8' => 'when the conflicts contain a non-UTF-8 file'
168
  }.freeze
169 170 171 172 173 174 175

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

      before do
        project.team << [user, :developer]
176
        sign_in(user)
177

178
        visit project_merge_request_path(project, merge_request)
179 180 181 182 183 184 185 186
      end

      it 'does not show a link to the conflict resolution page' do
        expect(page).not_to have_link('conflicts', href: /\/conflicts\Z/)
      end

      it 'shows an error if the conflicts page is visited directly' do
        visit current_url + '/conflicts'
187
        wait_for_requests
188

189
        expect(find('#conflicts')).to have_content('Please try to resolve them locally.')
190 191 192 193
      end
    end
  end
end