summaryrefslogtreecommitdiff
path: root/spec/features/expand_collapse_diffs_spec.rb
blob: 7cff196c8d9532706a992f77603cf3bd54c6acd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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
164
165
166
167
168
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
202
203
204
205
206
207
require 'spec_helper'

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

  before do
    login_as :admin
    project = create(:project)
    branch = 'expand-collapse-diffs'

    # Ensure that undiffable.md is in .gitattributes
    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

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

        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)

        expect(new_line).to have_content('three copies')
      end
    end

    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
          large_diff.find('.line_holder', 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
          expect(evaluate_script('ajaxUris')).to be_empty
        end
      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
          expect(evaluate_script('ajaxUris')).to be_empty
        end
      end
    end
  end
end