Skip to content
Snippets Groups Projects
expand_collapse_diffs_spec.rb 8.07 KiB
Newer Older
  • Learn to ignore specific revisions
  • require 'spec_helper'
    
    feature 'Expand and collapse diffs', js: true, feature: true do
      include WaitForAjax
    
    
      let(:branch) { 'expand-collapse-diffs' }
    
    
      before do
        login_as :admin
    
    Sean McGivern's avatar
    Sean McGivern committed
        project = create(:project)
    
    
        # Ensure that undiffable.md is in .gitattributes
    
    Sean McGivern's avatar
    Sean McGivern committed
        project.repository.copy_gitattributes(branch)
        visit namespace_project_commit_path(project.namespace, project, project.commit(branch))
    
        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.
      #
    
      files = [
        'small_diff.md', 'large_diff.md', 'large_diff_renamed.md', 'undiffable.md',
        'too_large.md', 'too_large_image.jpg'
      ]
    
      files.each do |file|
    
        define_method(file.split('.').first) { file_container(file) }
      end
    
    
    Sean McGivern's avatar
    Sean McGivern committed
      context 'visiting a commit with collapsed diffs' do
    
        it 'shows small diffs immediately' do
          expect(small_diff).to have_selector('.code')
          expect(small_diff).not_to have_selector('.nothing-here-block')
        end
    
    
        it 'collapses large diffs by default' do
    
          expect(large_diff).not_to have_selector('.code')
          expect(large_diff).to have_selector('.nothing-here-block')
        end
    
    
        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
    
    
        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
    
    
        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
            expect(old_line).to have_content('two copies')
    
          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
            expect(new_line).to have_content('three copies')
    
        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
              large_diff.find('.diff-line-num', match: :prefer_exact).hover
    
              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
              expect(evaluate_script('ajaxUris')).not_to include(a_string_matching('small_diff.md'))
    
      context 'visiting a commit without collapsed diffs' do
        let(:branch) { 'feature' }
    
        it 'does not show Expand all button' do
          expect(page).not_to have_link('Expand all')
        end
      end
    
      context 'visiting a commit with more than safe files' do
        let(:branch) { 'expand-collapse-files' }
    
        # safe-files -> 100 | safe-lines -> 5000 | commit-files -> 105
        it 'does collapsing from the safe number of files to the end on small files' do
          expect(page).to have_link('Expand all')
    
          expect(page).to have_selector('.diff-content', count: 105)
          expect(page).to have_selector('.diff-collapsed', count: 5)
    
          %w(file-95.txt file-96.txt file-97.txt file-98.txt file-99.txt).each do |filename|
            expect(find("[data-blob-diff-path*='#{filename}']")).to have_selector('.diff-collapsed')
          end
        end
      end
    
      context 'visiting a commit with more than safe lines' do
        let(:branch) { 'expand-collapse-lines' }
    
        # safe-files -> 100 | safe-lines -> 5000 | commit_files -> 8 (each 1250 lines)
        it 'does collapsing from the safe number of lines to the end' do
          expect(page).to have_link('Expand all')
    
          expect(page).to have_selector('.diff-content', count: 6)
          expect(page).to have_selector('.diff-collapsed', count: 2)
    
          %w(file-4.txt file-5.txt).each do |filename|
            expect(find("[data-blob-diff-path*='#{filename}']")).to have_selector('.diff-collapsed')
          end
        end
      end
    
    
      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
              expect(evaluate_script('ajaxUris')).not_to include(a_string_matching('small_diff.md'))