commit_controller_spec.rb 11.2 KB
Newer Older
S
Sean McGivern 已提交
1
require 'spec_helper'
2 3

describe Projects::CommitController do
4
  let(:project)  { create(:project, :repository) }
5 6
  let(:user)     { create(:user) }
  let(:commit)   { project.commit("master") }
S
Sean McGivern 已提交
7 8 9 10 11 12 13 14
  let(:master_pickable_sha) { '7d3b0f7cff5f37573aea97cebfd5692ea1689924' }
  let(:master_pickable_commit)  { project.commit(master_pickable_sha) }

  before do
    sign_in(user)
    project.team << [user, :master]
  end

S
Sean McGivern 已提交
15
  describe 'GET show' do
16 17
    render_views

S
Sean McGivern 已提交
18 19
    def go(extra_params = {})
      params = {
20 21
        namespace_id: project.namespace,
        project_id: project
S
Sean McGivern 已提交
22 23 24 25 26
      }

      get :show, params.merge(extra_params)
    end

27 28
    context 'with valid id' do
      it 'responds with 200' do
S
Sean McGivern 已提交
29
        go(id: commit.id)
30 31 32 33 34 35 36

        expect(response).to be_ok
      end
    end

    context 'with invalid id' do
      it 'responds with 404' do
S
Sean McGivern 已提交
37
        go(id: commit.id.reverse)
38 39 40 41 42

        expect(response).to be_not_found
      end
    end

43
    it 'handles binary files' do
S
Sean McGivern 已提交
44 45 46 47 48 49
      go(id: TestEnv::BRANCH_SHA['binary-encoding'], format: 'html')

      expect(response).to be_success
    end

    shared_examples "export as" do |format|
50
      it "does generally work" do
S
Sean McGivern 已提交
51 52 53 54 55
        go(id: commit.id, format: format)

        expect(response).to be_success
      end

56
      it "generates it" do
S
Sean McGivern 已提交
57 58 59 60 61
        expect_any_instance_of(Commit).to receive(:"to_#{format}")

        go(id: commit.id, format: format)
      end

62
      it "renders it" do
S
Sean McGivern 已提交
63 64 65 66 67
        go(id: commit.id, format: format)

        expect(response.body).to eq(commit.send(:"to_#{format}"))
      end

68
      it "does not escape Html" do
69 70
        allow_any_instance_of(Commit).to receive(:"to_#{format}")
          .and_return('HTML entities &<>" ')
S
Sean McGivern 已提交
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

        go(id: commit.id, format: format)

        expect(response.body).not_to include('&amp;')
        expect(response.body).not_to include('&gt;')
        expect(response.body).not_to include('&lt;')
        expect(response.body).not_to include('&quot;')
      end
    end

    describe "as diff" do
      include_examples "export as", :diff
      let(:format) { :diff }

      it "should really only be a git diff" do
86
        go(id: '66eceea0db202bb39c4e445e8ca28689645366c5', format: format)
S
Sean McGivern 已提交
87 88 89 90

        expect(response.body).to start_with("diff --git")
      end

91
      it "is only be a git diff without whitespace changes" do
S
Sean McGivern 已提交
92 93 94
        go(id: '66eceea0db202bb39c4e445e8ca28689645366c5', format: format, w: 1)

        expect(response.body).to start_with("diff --git")
95 96 97

        # without whitespace option, there are more than 2 diff_splits for other formats
        diff_splits = assigns(:diffs).diff_files.first.diff.diff.split("\n")
S
Sean McGivern 已提交
98 99 100 101 102 103 104
        expect(diff_splits.length).to be <= 2
      end
    end

    describe "as patch" do
      include_examples "export as", :patch
      let(:format) { :patch }
105
      let(:commit2) { project.commit('498214de67004b1da3d820901307bed2a68a8ef6') }
S
Sean McGivern 已提交
106

107
      it "is a git email patch" do
108
        go(id: commit2.id, format: format)
S
Sean McGivern 已提交
109

110
        expect(response.body).to start_with("From #{commit2.id}")
S
Sean McGivern 已提交
111 112
      end

113
      it "contains a git diff" do
114
        go(id: commit2.id, format: format)
S
Sean McGivern 已提交
115 116 117 118 119 120 121 122 123 124 125 126 127

        expect(response.body).to match(/^diff --git/)
      end
    end

    context 'commit that removes a submodule' do
      render_views

      let(:fork_project) { create(:forked_project_with_submodules, visibility_level: 20) }
      let(:commit) { fork_project.commit('remove-submodule') }

      it 'renders it' do
        get(:show,
128 129
            namespace_id: fork_project.namespace,
            project_id: fork_project,
S
Sean McGivern 已提交
130 131 132 133 134 135 136
            id: commit.id)

        expect(response).to be_success
      end
    end
  end

137 138
  describe 'GET branches' do
    it 'contains branch and tags information' do
139 140
      commit = project.commit('5937ac0a7beb003549fc5fd26fc247adbce4a52e')

S
Sean McGivern 已提交
141
      get(:branches,
142 143
          namespace_id: project.namespace,
          project_id: project,
S
Sean McGivern 已提交
144
          id: commit.id)
145

146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
      expect(assigns(:branches)).to include('master', 'feature_conflict')
      expect(assigns(:branches_limit_exceeded)).to be_falsey
      expect(assigns(:tags)).to include('v1.1.0')
      expect(assigns(:tags_limit_exceeded)).to be_falsey
    end

    it 'returns :limit_exceeded when number of branches/tags reach a threshhold' do
      commit = project.commit('5937ac0a7beb003549fc5fd26fc247adbce4a52e')
      allow_any_instance_of(Repository).to receive(:branch_count).and_return(1001)
      allow_any_instance_of(Repository).to receive(:tag_count).and_return(1001)

      get(:branches,
          namespace_id: project.namespace,
          project_id: project,
          id: commit.id)

      expect(assigns(:branches)).to eq([])
      expect(assigns(:branches_limit_exceeded)).to be_truthy
      expect(assigns(:tags)).to eq([])
      expect(assigns(:tags_limit_exceeded)).to be_truthy
S
Sean McGivern 已提交
166 167 168
    end
  end

S
Sean McGivern 已提交
169
  describe 'POST revert' do
S
Sean McGivern 已提交
170
    context 'when target branch is not provided' do
171
      it 'renders the 404 page' do
S
Sean McGivern 已提交
172
        post(:revert,
173 174
            namespace_id: project.namespace,
            project_id: project,
S
Sean McGivern 已提交
175 176 177
            id: commit.id)

        expect(response).not_to be_success
178
        expect(response).to have_gitlab_http_status(404)
S
Sean McGivern 已提交
179 180 181 182
      end
    end

    context 'when the revert was successful' do
183
      it 'redirects to the commits page' do
S
Sean McGivern 已提交
184
        post(:revert,
185 186
            namespace_id: project.namespace,
            project_id: project,
187
            start_branch: 'master',
S
Sean McGivern 已提交
188 189
            id: commit.id)

190
        expect(response).to redirect_to project_commits_path(project, 'master')
S
Sean McGivern 已提交
191 192 193 194 195 196 197
        expect(flash[:notice]).to eq('The commit has been successfully reverted.')
      end
    end

    context 'when the revert failed' do
      before do
        post(:revert,
198 199
            namespace_id: project.namespace,
            project_id: project,
200
            start_branch: 'master',
S
Sean McGivern 已提交
201 202 203
            id: commit.id)
      end

204
      it 'redirects to the commit page' do
S
Sean McGivern 已提交
205 206
        # Reverting a commit that has been already reverted.
        post(:revert,
207 208
            namespace_id: project.namespace,
            project_id: project,
209
            start_branch: 'master',
S
Sean McGivern 已提交
210 211
            id: commit.id)

212
        expect(response).to redirect_to project_commit_path(project, commit.id)
S
Sean McGivern 已提交
213 214 215 216 217
        expect(flash[:alert]).to match('Sorry, we cannot revert this commit automatically.')
      end
    end
  end

S
Sean McGivern 已提交
218
  describe 'POST cherry_pick' do
S
Sean McGivern 已提交
219
    context 'when target branch is not provided' do
220
      it 'renders the 404 page' do
S
Sean McGivern 已提交
221
        post(:cherry_pick,
222 223
            namespace_id: project.namespace,
            project_id: project,
S
Sean McGivern 已提交
224 225 226
            id: master_pickable_commit.id)

        expect(response).not_to be_success
227
        expect(response).to have_gitlab_http_status(404)
S
Sean McGivern 已提交
228 229 230 231
      end
    end

    context 'when the cherry-pick was successful' do
232
      it 'redirects to the commits page' do
S
Sean McGivern 已提交
233
        post(:cherry_pick,
234 235
            namespace_id: project.namespace,
            project_id: project,
236
            start_branch: 'master',
S
Sean McGivern 已提交
237 238
            id: master_pickable_commit.id)

239
        expect(response).to redirect_to project_commits_path(project, 'master')
S
Sean McGivern 已提交
240 241
        expect(flash[:notice]).to eq('The commit has been successfully cherry-picked.')
      end
242 243
    end

S
Sean McGivern 已提交
244 245 246
    context 'when the cherry_pick failed' do
      before do
        post(:cherry_pick,
247 248
            namespace_id: project.namespace,
            project_id: project,
249
            start_branch: 'master',
S
Sean McGivern 已提交
250 251 252
            id: master_pickable_commit.id)
      end

253
      it 'redirects to the commit page' do
S
Sean McGivern 已提交
254 255
        # Cherry-picking a commit that has been already cherry-picked.
        post(:cherry_pick,
256 257
            namespace_id: project.namespace,
            project_id: project,
258
            start_branch: 'master',
S
Sean McGivern 已提交
259 260
            id: master_pickable_commit.id)

261
        expect(response).to redirect_to project_commit_path(project, master_pickable_commit.id)
S
Sean McGivern 已提交
262 263 264 265 266
        expect(flash[:alert]).to match('Sorry, we cannot cherry-pick this commit automatically.')
      end
    end
  end

S
Sean McGivern 已提交
267
  describe 'GET diff_for_path' do
S
Sean McGivern 已提交
268 269
    def diff_for_path(extra_params = {})
      params = {
270 271
        namespace_id: project.namespace,
        project_id: project
S
Sean McGivern 已提交
272 273 274 275 276 277
      }

      get :diff_for_path, params.merge(extra_params)
    end

    let(:existing_path) { '.gitmodules' }
278
    let(:commit2) { project.commit('5937ac0a7beb003549fc5fd26fc247adbce4a52e') }
S
Sean McGivern 已提交
279 280 281 282 283

    context 'when the commit exists' do
      context 'when the user has access to the project' do
        context 'when the path exists in the diff' do
          it 'enables diff notes' do
284
            diff_for_path(id: commit2.id, old_path: existing_path, new_path: existing_path)
S
Sean McGivern 已提交
285 286

            expect(assigns(:diff_notes_disabled)).to be_falsey
287
            expect(assigns(:new_diff_note_attrs)).to eq(noteable_type: 'Commit',
D
Douwe Maan 已提交
288
                                                        commit_id: commit2.id)
S
Sean McGivern 已提交
289 290 291
          end

          it 'only renders the diffs for the path given' do
292 293 294
            expect(controller).to receive(:render_diff_for_path).and_wrap_original do |meth, diffs|
              expect(diffs.diff_files.map(&:new_path)).to contain_exactly(existing_path)
              meth.call(diffs)
S
Sean McGivern 已提交
295 296
            end

297
            diff_for_path(id: commit2.id, old_path: existing_path, new_path: existing_path)
S
Sean McGivern 已提交
298 299 300 301
          end
        end

        context 'when the path does not exist in the diff' do
302 303 304
          before do
            diff_for_path(id: commit.id, old_path: existing_path.succ, new_path: existing_path.succ)
          end
S
Sean McGivern 已提交
305 306

          it 'returns a 404' do
307
            expect(response).to have_gitlab_http_status(404)
S
Sean McGivern 已提交
308 309 310 311 312 313 314
          end
        end
      end

      context 'when the user does not have access to the project' do
        before do
          project.team.truncate
315
          diff_for_path(id: commit.id, old_path: existing_path, new_path: existing_path)
S
Sean McGivern 已提交
316 317 318
        end

        it 'returns a 404' do
319
          expect(response).to have_gitlab_http_status(404)
S
Sean McGivern 已提交
320 321 322 323 324
        end
      end
    end

    context 'when the commit does not exist' do
325 326 327
      before do
        diff_for_path(id: commit.id.succ, old_path: existing_path, new_path: existing_path)
      end
S
Sean McGivern 已提交
328 329

      it 'returns a 404' do
330
        expect(response).to have_gitlab_http_status(404)
S
Sean McGivern 已提交
331
      end
332 333
    end
  end
334 335 336 337

  describe 'GET pipelines' do
    def get_pipelines(extra_params = {})
      params = {
338 339
        namespace_id: project.namespace,
        project_id: project
340 341 342 343 344 345
      }

      get :pipelines, params.merge(extra_params)
    end

    context 'when the commit exists' do
346 347 348 349 350 351 352 353 354 355 356 357
      context 'when the commit has pipelines' do
        before do
          create(:ci_pipeline, project: project, sha: commit.id)
        end

        context 'when rendering a HTML format' do
          it 'shows pipelines' do
            get_pipelines(id: commit.id)

            expect(response).to be_ok
          end
        end
358

359 360 361 362 363
        context 'when rendering a JSON format' do
          it 'responds with serialized pipelines' do
            get_pipelines(id: commit.id, format: :json)

            expect(response).to be_ok
364 365
            expect(JSON.parse(response.body)['pipelines']).not_to be_empty
            expect(JSON.parse(response.body)['count']['all']).to eq 1
366
          end
367 368 369 370 371 372 373 374 375 376
        end
      end
    end

    context 'when the commit does not exist' do
      before do
        get_pipelines(id: 'e7a412c8da9f6d0081a633a4a402dde1c4694ebd')
      end

      it 'returns a 404' do
377
        expect(response).to have_gitlab_http_status(404)
378 379 380
      end
    end
  end
381
end