expand_collapse_diffs_spec.rb 6.65 KB
Newer Older
1 2 3 4 5 6 7
require 'spec_helper'

feature 'Expand and collapse diffs', js: true, feature: true do
  include WaitForAjax

  before do
    login_as :admin
Sean McGivern's avatar
Sean McGivern committed
8 9
    project = create(:project)
    branch = 'expand-collapse-diffs'
10 11

    # Ensure that undiffable.md is in .gitattributes
Sean McGivern's avatar
Sean McGivern committed
12 13
    project.repository.copy_gitattributes(branch)
    visit namespace_project_commit_path(project.namespace, project, project.commit(branch))
14 15 16 17 18 19 20 21 22 23
    execute_script('window.ajaxUris = []; $(document).ajaxSend(function(event, xhr, settings) { ajaxUris.push(settings.url) });')
  end

  def file_container(filename)
    find("[data-blob-diff-path*='#{filename}']")
  end

  # Use define_method instead of let (which is memoized) so that this just works across a
  # reload.
  #
24 25 26 27 28 29
  files = [
    'small_diff.md', 'large_diff.md', 'large_diff_renamed.md', 'undiffable.md',
    'too_large.md', 'too_large_image.jpg'
  ]

  files.each do |file|
30 31 32
    define_method(file.split('.').first) { file_container(file) }
  end

Sean McGivern's avatar
Sean McGivern committed
33
  context 'visiting a commit with collapsed diffs' do
34 35 36 37 38
    it 'shows small diffs immediately' do
      expect(small_diff).to have_selector('.code')
      expect(small_diff).not_to have_selector('.nothing-here-block')
    end

39
    it 'collapses large diffs by default' do
40 41 42 43
      expect(large_diff).not_to have_selector('.code')
      expect(large_diff).to have_selector('.nothing-here-block')
    end

44 45 46 47 48 49 50
    it 'collapses large diffs for renamed files by default' do
      expect(large_diff_renamed).not_to have_selector('.code')
      expect(large_diff_renamed).to have_selector('.nothing-here-block')
      expect(large_diff_renamed).to have_selector('.file-title .deletion')
      expect(large_diff_renamed).to have_selector('.file-title .addition')
    end

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
    it 'shows non-renderable diffs as such immediately, regardless of their size' do
      expect(undiffable).not_to have_selector('.code')
      expect(undiffable).to have_selector('.nothing-here-block')
      expect(undiffable).to have_content('gitattributes')
    end

    it 'does not allow diffs that are larger than the maximum size to be expanded' do
      expect(too_large).not_to have_selector('.code')
      expect(too_large).to have_selector('.nothing-here-block')
      expect(too_large).to have_content('too large')
    end

    it 'shows image diffs immediately, regardless of their size' do
      expect(too_large_image).not_to have_selector('.nothing-here-block')
      expect(too_large_image).to have_selector('.image')
    end

68 69 70 71 72 73 74 75 76
    context 'expanding a diff for a renamed file' do
      before do
        large_diff_renamed.find('.nothing-here-block').click
        wait_for_ajax
      end

      it 'shows the old content' do
        old_line = large_diff_renamed.find('.line_content.old')

Sean McGivern's avatar
Sean McGivern committed
77
        expect(old_line).to have_content('two copies')
78 79 80 81 82
      end

      it 'shows the new content' do
        new_line = large_diff_renamed.find('.line_content.new', match: :prefer_exact)

Sean McGivern's avatar
Sean McGivern committed
83
        expect(new_line).to have_content('three copies')
84 85 86
      end
    end

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
    context 'expanding a large diff' do
      before do
        click_link('large_diff.md')
        wait_for_ajax
      end

      it 'makes a request to get the content' do
        ajax_uris = evaluate_script('ajaxUris')

        expect(ajax_uris).not_to be_empty
        expect(ajax_uris.first).to include('large_diff.md')
      end

      it 'shows the diff content' do
        expect(large_diff).to have_selector('.code')
        expect(large_diff).not_to have_selector('.nothing-here-block')
      end

      context 'adding a comment to the expanded diff' do
        let(:comment_text) { 'A comment' }

        before do
Sean McGivern's avatar
Sean McGivern committed
109
          large_diff.find('.diff-line-num', match: :prefer_exact).hover
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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
          large_diff.find('.add-diff-note').click
          large_diff.find('.note-textarea').send_keys comment_text
          large_diff.find_button('Comment').click
          wait_for_ajax
        end

        it 'adds the comment' do
          expect(large_diff.find('.notes')).to have_content comment_text
        end

        context 'reloading the page' do
          before { refresh }

          it 'collapses the large diff by default' do
            expect(large_diff).not_to have_selector('.code')
            expect(large_diff).to have_selector('.nothing-here-block')
          end

          context 'expanding the diff' do
            before do
              click_link('large_diff.md')
              wait_for_ajax
            end

            it 'shows the diff content' do
              expect(large_diff).to have_selector('.code')
              expect(large_diff).not_to have_selector('.nothing-here-block')
            end

            it 'shows the diff comment' do
              expect(large_diff.find('.notes')).to have_content comment_text
            end
          end
        end
      end
    end

    context 'collapsing an expanded diff' do
      before { click_link('small_diff.md') }

      it 'hides the diff content' do
        expect(small_diff).not_to have_selector('.code')
        expect(small_diff).to have_selector('.nothing-here-block')
      end

      context 're-expanding the same diff' do
        before { click_link('small_diff.md') }

        it 'shows the diff content' do
          expect(small_diff).to have_selector('.code')
          expect(small_diff).not_to have_selector('.nothing-here-block')
        end

        it 'does not make a new HTTP request' do
Sean McGivern's avatar
Sean McGivern committed
164
          expect(evaluate_script('ajaxUris')).not_to include(a_string_matching('small_diff.md'))
165 166 167 168
        end
      end
    end
  end
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201

  context 'expanding all diffs' do
    before do
      click_link('Expand all')
      wait_for_ajax
      execute_script('window.ajaxUris = []; $(document).ajaxSend(function(event, xhr, settings) { ajaxUris.push(settings.url) });')
    end

    it 'reloads the page with all diffs expanded' do
      expect(small_diff).to have_selector('.code')
      expect(small_diff).not_to have_selector('.nothing-here-block')

      expect(large_diff).to have_selector('.code')
      expect(large_diff).not_to have_selector('.nothing-here-block')
    end

    context 'collapsing an expanded diff' do
      before { click_link('small_diff.md') }

      it 'hides the diff content' do
        expect(small_diff).not_to have_selector('.code')
        expect(small_diff).to have_selector('.nothing-here-block')
      end

      context 're-expanding the same diff' do
        before { click_link('small_diff.md') }

        it 'shows the diff content' do
          expect(small_diff).to have_selector('.code')
          expect(small_diff).not_to have_selector('.nothing-here-block')
        end

        it 'does not make a new HTTP request' do
Sean McGivern's avatar
Sean McGivern committed
202
          expect(evaluate_script('ajaxUris')).not_to include(a_string_matching('small_diff.md'))
203 204 205 206
        end
      end
    end
  end
207
end