builds_spec.rb 9.29 KB
Newer Older
1 2
require 'spec_helper'

Lin Jen-Shin's avatar
Lin Jen-Shin committed
3
describe API::API, api: true do
4 5 6
  include ApiHelpers

  let(:user) { create(:user) }
Kamil Trzcinski's avatar
Kamil Trzcinski committed
7
  let(:api_user) { user }
8 9
  let(:user2) { create(:user) }
  let!(:project) { create(:project, creator_id: user.id) }
10 11
  let!(:developer) { create(:project_member, :developer, user: user, project: project) }
  let!(:reporter) { create(:project_member, :reporter, user: user2, project: project) }
12 13
  let!(:pipeline) { create(:ci_pipeline, project: project, sha: project.commit.id) }
  let!(:build) { create(:ci_build, pipeline: pipeline) }
14 15

  describe 'GET /projects/:id/builds ' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
16 17 18 19
    let(:query) { '' }

    before { get api("/projects/#{project.id}/builds?#{query}", api_user) }

20 21
    context 'authorized user' do
      it 'should return project builds' do
22
        expect(response).to have_http_status(200)
23 24 25
        expect(json_response).to be_an Array
      end

26 27 28 29 30
      it 'returns correct values' do
        expect(json_response).not_to be_empty
        expect(json_response.first['commit']['id']).to eq project.commit.id
      end

Kamil Trzcinski's avatar
Kamil Trzcinski committed
31 32
      context 'filter project with one scope element' do
        let(:query) { 'scope=pending' }
33

Kamil Trzcinski's avatar
Kamil Trzcinski committed
34
        it do
35
          expect(response).to have_http_status(200)
Kamil Trzcinski's avatar
Kamil Trzcinski committed
36 37
          expect(json_response).to be_an Array
        end
38 39
      end

Kamil Trzcinski's avatar
Kamil Trzcinski committed
40 41
      context 'filter project with array of scope elements' do
        let(:query) { 'scope[0]=pending&scope[1]=running' }
42

Kamil Trzcinski's avatar
Kamil Trzcinski committed
43
        it do
44
          expect(response).to have_http_status(200)
Kamil Trzcinski's avatar
Kamil Trzcinski committed
45 46
          expect(json_response).to be_an Array
        end
47
      end
48

Kamil Trzcinski's avatar
Kamil Trzcinski committed
49 50
      context 'respond 400 when scope contains invalid state' do
        let(:query) { 'scope[0]=pending&scope[1]=unknown_status' }
51

52
        it { expect(response).to have_http_status(400) }
53
      end
54 55 56
    end

    context 'unauthorized user' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
57
      let(:api_user) { nil }
58

Kamil Trzcinski's avatar
Kamil Trzcinski committed
59
      it 'should not return project builds' do
60
        expect(response).to have_http_status(401)
61 62 63 64
      end
    end
  end

65
  describe 'GET /projects/:id/repository/commits/:sha/builds' do
66 67 68 69
    context 'when commit does not exist in repository' do
      before do
        get api("/projects/#{project.id}/repository/commits/1a271fd1/builds", api_user)
      end
70

71 72 73
      it 'responds with 404' do
        expect(response).to have_http_status(404)
      end
Kamil Trzcinski's avatar
Kamil Trzcinski committed
74 75
    end

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
    context 'when commit exists in repository' do
      context 'when user is authorized' do
        context 'when pipeline has builds' do
          before do
            create(:ci_pipeline, project: project, sha: project.commit.id)
            create(:ci_build, pipeline: pipeline)
            create(:ci_build)

            get api("/projects/#{project.id}/repository/commits/#{project.commit.id}/builds", api_user)
          end

          it 'should return project builds for specific commit' do
            expect(response).to have_http_status(200)
            expect(json_response).to be_an Array
            expect(json_response.size).to eq 2
          end
        end

        context 'when pipeline has no builds' do
          before do
            branch_head = project.commit('feature').id
            get api("/projects/#{project.id}/repository/commits/#{branch_head}/builds", api_user)
          end

          it 'returns an empty array' do
            expect(response).to have_http_status(200)
            expect(json_response).to be_an Array
            expect(json_response).to be_empty
          end
        end
106 107
      end

108 109 110 111
      context 'when user is not authorized' do
        before do
          create(:ci_pipeline, project: project, sha: project.commit.id)
          create(:ci_build, pipeline: pipeline)
112

113 114 115 116 117 118 119
          get api("/projects/#{project.id}/repository/commits/#{project.commit.id}/builds", nil)
        end

        it 'should not return project builds' do
          expect(response).to have_http_status(401)
          expect(json_response.except('message')).to be_empty
        end
120 121 122
      end
    end
  end
123

124
  describe 'GET /projects/:id/builds/:build_id' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
125 126
    before { get api("/projects/#{project.id}/builds/#{build.id}", api_user) }

127 128
    context 'authorized user' do
      it 'should return specific build data' do
129
        expect(response).to have_http_status(200)
130 131
        expect(json_response['name']).to eq('test')
      end
132 133 134
    end

    context 'unauthorized user' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
135
      let(:api_user) { nil }
136

Kamil Trzcinski's avatar
Kamil Trzcinski committed
137
      it 'should not return specific build data' do
138
        expect(response).to have_http_status(401)
139 140 141 142
      end
    end
  end

143
  describe 'GET /projects/:id/builds/:build_id/artifacts' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
144
    before { get api("/projects/#{project.id}/builds/#{build.id}/artifacts", api_user) }
145

Kamil Trzcinski's avatar
Kamil Trzcinski committed
146
    context 'build with artifacts' do
147
      let(:build) { create(:ci_build, :artifacts, pipeline: pipeline) }
148

Kamil Trzcinski's avatar
Kamil Trzcinski committed
149 150
      context 'authorized user' do
        let(:download_headers) do
151 152
          { 'Content-Transfer-Encoding' => 'binary',
            'Content-Disposition' => 'attachment; filename=ci_build_artifacts.zip' }
Kamil Trzcinski's avatar
Kamil Trzcinski committed
153
        end
154

Kamil Trzcinski's avatar
Kamil Trzcinski committed
155
        it 'should return specific build artifacts' do
156
          expect(response).to have_http_status(200)
Kamil Trzcinski's avatar
Kamil Trzcinski committed
157 158
          expect(response.headers).to include(download_headers)
        end
159 160
      end

Kamil Trzcinski's avatar
Kamil Trzcinski committed
161 162
      context 'unauthorized user' do
        let(:api_user) { nil }
163

Kamil Trzcinski's avatar
Kamil Trzcinski committed
164
        it 'should not return specific build artifacts' do
165
          expect(response).to have_http_status(401)
Kamil Trzcinski's avatar
Kamil Trzcinski committed
166
        end
167 168
      end
    end
Kamil Trzcinski's avatar
Kamil Trzcinski committed
169 170

    it 'should not return build artifacts if not uploaded' do
171
      expect(response).to have_http_status(404)
Kamil Trzcinski's avatar
Kamil Trzcinski committed
172
    end
173 174
  end

175
  describe 'GET /projects/:id/builds/:build_id/trace' do
176
    let(:build) { create(:ci_build, :trace, pipeline: pipeline) }
177

Kamil Trzcinski's avatar
Kamil Trzcinski committed
178 179
    before { get api("/projects/#{project.id}/builds/#{build.id}/trace", api_user) }

180
    context 'authorized user' do
181
      it 'should return specific build trace' do
182
        expect(response).to have_http_status(200)
Kamil Trzcinski's avatar
Kamil Trzcinski committed
183
        expect(response.body).to eq(build.trace)
184 185 186 187
      end
    end

    context 'unauthorized user' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
188
      let(:api_user) { nil }
189

Kamil Trzcinski's avatar
Kamil Trzcinski committed
190
      it 'should not return specific build trace' do
191
        expect(response).to have_http_status(401)
192 193 194
      end
    end
  end
195

196
  describe 'POST /projects/:id/builds/:build_id/cancel' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
197 198
    before { post api("/projects/#{project.id}/builds/#{build.id}/cancel", api_user) }

199
    context 'authorized user' do
200
      context 'user with :update_build persmission' do
201
        it 'should cancel running or pending build' do
202
          expect(response).to have_http_status(201)
203 204 205 206
          expect(project.builds.first.status).to eq('canceled')
        end
      end

207
      context 'user without :update_build permission' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
208
        let(:api_user) { user2 }
209

Kamil Trzcinski's avatar
Kamil Trzcinski committed
210
        it 'should not cancel build' do
211
          expect(response).to have_http_status(403)
212 213 214 215 216
        end
      end
    end

    context 'unauthorized user' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
217
      let(:api_user) { nil }
218

Kamil Trzcinski's avatar
Kamil Trzcinski committed
219
      it 'should not cancel build' do
220
        expect(response).to have_http_status(401)
221 222 223 224
      end
    end
  end

225
  describe 'POST /projects/:id/builds/:build_id/retry' do
226
    let(:build) { create(:ci_build, :canceled, pipeline: pipeline) }
Kamil Trzcinski's avatar
Kamil Trzcinski committed
227 228 229

    before { post api("/projects/#{project.id}/builds/#{build.id}/retry", api_user) }

230
    context 'authorized user' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
231
      context 'user with :update_build permission' do
232
        it 'should retry non-running build' do
233
          expect(response).to have_http_status(201)
234 235 236 237 238
          expect(project.builds.first.status).to eq('canceled')
          expect(json_response['status']).to eq('pending')
        end
      end

239
      context 'user without :update_build permission' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
240
        let(:api_user) { user2 }
241

Kamil Trzcinski's avatar
Kamil Trzcinski committed
242
        it 'should not retry build' do
243
          expect(response).to have_http_status(403)
244 245 246 247 248
        end
      end
    end

    context 'unauthorized user' do
Kamil Trzcinski's avatar
Kamil Trzcinski committed
249
      let(:api_user) { nil }
250

Kamil Trzcinski's avatar
Kamil Trzcinski committed
251
      it 'should not retry build' do
252
        expect(response).to have_http_status(401)
253 254 255
      end
    end
  end
256

257
  describe 'POST /projects/:id/builds/:build_id/erase' do
258
    before do
259
      post api("/projects/#{project.id}/builds/#{build.id}/erase", user)
260 261
    end

262
    context 'build is erasable' do
263
      let(:build) { create(:ci_build, :trace, :artifacts, :success, project: project, pipeline: pipeline) }
264 265

      it 'should erase build content' do
266
        expect(response.status).to eq 201
267 268 269 270
        expect(build.trace).to be_empty
        expect(build.artifacts_file.exists?).to be_falsy
        expect(build.artifacts_metadata.exists?).to be_falsy
      end
271 272 273 274 275

      it 'should update build' do
        expect(build.reload.erased_at).to be_truthy
        expect(build.reload.erased_by).to eq user
      end
276 277
    end

278
    context 'build is not erasable' do
279
      let(:build) { create(:ci_build, :trace, project: project, pipeline: pipeline) }
280 281 282 283 284 285

      it 'should respond with forbidden' do
        expect(response.status).to eq 403
      end
    end
  end
286 287 288 289 290 291 292 293 294 295 296 297

  describe 'POST /projects/:id/builds/:build_id/artifacts/keep' do
    before do
      post api("/projects/#{project.id}/builds/#{build.id}/artifacts/keep", user)
    end

    context 'artifacts did not expire' do
      let(:build) do
        create(:ci_build, :trace, :artifacts, :success,
               project: project, pipeline: pipeline, artifacts_expire_at: Time.now + 7.days)
      end

298
      it 'keeps artifacts' do
299
        expect(response.status).to eq 200
300
        expect(build.reload.artifacts_expire_at).to be_nil
301 302 303 304 305 306
      end
    end

    context 'no artifacts' do
      let(:build) { create(:ci_build, project: project, pipeline: pipeline) }

307
      it 'responds with not found' do
308 309 310 311
        expect(response.status).to eq 404
      end
    end
  end
312
end