projects_spec.rb 32.4 KB
Newer Older
1
# -*- coding: utf-8 -*-
N
Nihad Abbasov 已提交
2 3
require 'spec_helper'

J
Jeroen van Baarsen 已提交
4
describe API::API, api: true  do
5
  include ApiHelpers
6
  include Gitlab::CurrentSettings
7 8 9
  let(:user) { create(:user) }
  let(:user2) { create(:user) }
  let(:user3) { create(:user) }
A
Angus MacArthur 已提交
10
  let(:admin) { create(:admin) }
D
Dmitriy Zaporozhets 已提交
11
  let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
12 13
  let(:project2) { create(:project, path: 'project2', creator_id: user.id, namespace: user.namespace) }
  let(:project3) { create(:project, path: 'project3', creator_id: user.id, namespace: user.namespace) }
D
Dmitriy Zaporozhets 已提交
14
  let(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') }
15 16
  let(:project_member) { create(:project_member, user: user, project: project, access_level: ProjectMember::MASTER) }
  let(:project_member2) { create(:project_member, user: user3, project: project, access_level: ProjectMember::DEVELOPER) }
17
  let(:user4) { create(:user) }
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
  let(:project3) do
    create(:project,
    name: 'second_project',
    path: 'second_project',
    creator_id: user.id,
    namespace: user.namespace,
    merge_requests_enabled: false,
    issues_enabled: false, wiki_enabled: false,
    snippets_enabled: false, visibility_level: 0)
  end
  let(:project_member3) do
    create(:project_member,
    user: user4,
    project: project3,
    access_level: ProjectMember::MASTER)
  end
  let(:project4) do
    create(:project,
    name: 'third_project',
    path: 'third_project',
    creator_id: user4.id,
    namespace: user4.namespace)
  end

  describe 'GET /projects' do
D
Dmitriy Zaporozhets 已提交
43 44
    before { project }

45 46 47
    context 'when unauthenticated' do
      it 'should return authentication error' do
        get api('/projects')
48
        expect(response.status).to eq(401)
49
      end
N
Nihad Abbasov 已提交
50 51
    end

52 53 54
    context 'when authenticated' do
      it 'should return an array of projects' do
        get api('/projects', user)
55 56 57 58
        expect(response.status).to eq(200)
        expect(json_response).to be_an Array
        expect(json_response.first['name']).to eq(project.name)
        expect(json_response.first['owner']['username']).to eq(user.username)
N
Nihad Abbasov 已提交
59
      end
60

61 62
      it 'should include the project labels as the tag_list' do
        get api('/projects', user)
63 64 65
        expect(response.status).to eq 200
        expect(json_response).to be_an Array
        expect(json_response.first.keys).to include('tag_list')
66
      end
67

S
Stan Hu 已提交
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
      it 'should include open_issues_count' do
        get api('/projects', user)
        expect(response.status).to eq 200
        expect(json_response).to be_an Array
        expect(json_response.first.keys).to include('open_issues_count')
      end

      it 'should not include open_issues_count' do
        project.update_attributes( { issues_enabled: false } )

        get api('/projects', user)
        expect(response.status).to eq 200
        expect(json_response).to be_an Array
        expect(json_response.first.keys).not_to include('open_issues_count')
      end

84 85 86
      context 'and using search' do
        it 'should return searched project' do
          get api('/projects', user), { search: project.name }
87 88 89
          expect(response.status).to eq(200)
          expect(json_response).to be_an Array
          expect(json_response.length).to eq(1)
90 91 92
        end
      end

93
      context 'and using sorting' do
94 95 96 97 98
        before do
          project2
          project3
        end

99
        it 'should return the correct order when sorted by id' do
100
          get api('/projects', user), { order_by: 'id', sort: 'desc' }
101 102 103
          expect(response.status).to eq(200)
          expect(json_response).to be_an Array
          expect(json_response.first['id']).to eq(project3.id)
104 105
        end
      end
N
Nihad Abbasov 已提交
106 107 108
    end
  end

109
  describe 'GET /projects/all' do
D
Dmitriy Zaporozhets 已提交
110 111
    before { project }

112 113 114
    context 'when unauthenticated' do
      it 'should return authentication error' do
        get api('/projects/all')
115
        expect(response.status).to eq(401)
D
Dmitriy Zaporozhets 已提交
116 117 118
      end
    end

119 120 121
    context 'when authenticated as regular user' do
      it 'should return authentication error' do
        get api('/projects/all', user)
122
        expect(response.status).to eq(403)
D
Dmitriy Zaporozhets 已提交
123 124 125
      end
    end

126 127 128
    context 'when authenticated as admin' do
      it 'should return an array of all projects' do
        get api('/projects/all', admin)
129 130
        expect(response.status).to eq(200)
        expect(json_response).to be_an Array
M
Marin Jankovski 已提交
131

132 133
        expect(json_response).to satisfy do |response|
          response.one? do |entry|
134
            entry.has_key?('permissions') &&
135
            entry['name'] == project.name &&
136
              entry['owner']['username'] == user.username
137 138
          end
        end
D
Dmitriy Zaporozhets 已提交
139 140 141 142
      end
    end
  end

143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
  describe 'GET /projects/starred' do
    before do
      admin.starred_projects << project
      admin.save!
    end

    it 'should return the starred projects' do
      get api('/projects/all', admin)
      expect(response.status).to eq(200)
      expect(json_response).to be_an Array

      expect(json_response).to satisfy do |response|
        response.one? do |entry|
          entry['name'] == project.name
        end
      end
    end
  end

162 163
  describe 'POST /projects' do
    context 'maximum number of projects reached' do
164
      it 'should not create new project and respond with 403' do
165
        allow_any_instance_of(User).to receive(:projects_limit_left).and_return(0)
166 167
        expect { post api('/projects', user2), name: 'foo' }.
          to change {Project.count}.by(0)
168
        expect(response.status).to eq(403)
169 170 171
      end
    end

172 173 174
    it 'should create new project without path and return 201' do
      expect { post api('/projects', user), name: 'foo' }.
        to change { Project.count }.by(1)
175
      expect(response.status).to eq(201)
176 177
    end

178
    it 'should create last project before reaching project limit' do
179
      allow_any_instance_of(User).to receive(:projects_limit_left).and_return(1)
180
      post api('/projects', user2), name: 'foo'
181
      expect(response.status).to eq(201)
182 183
    end

184
    it 'should not create new project without name and return 400' do
185
      expect { post api('/projects', user) }.not_to change { Project.count }
186
      expect(response.status).to eq(400)
187
    end
A
Alex Denisov 已提交
188

189
    it "should assign attributes to project" do
190
      project = attributes_for(:project, {
191
        path: 'camelCasePath',
R
Robert Speicher 已提交
192
        description: FFaker::Lorem.sentence,
193 194 195
        issues_enabled: false,
        merge_requests_enabled: false,
        wiki_enabled: false
A
Alex Denisov 已提交
196 197
      })

198
      post api('/projects', user), project
A
Alex Denisov 已提交
199

200
      project.each_pair do |k,v|
201
        expect(json_response[k.to_s]).to eq(v)
A
Alex Denisov 已提交
202
      end
203
    end
204

205
    it 'should set a project as public' do
206
      project = attributes_for(:project, :public)
207
      post api('/projects', user), project
208 209
      expect(json_response['public']).to be_truthy
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC)
210 211
    end

212
    it 'should set a project as public using :public' do
213
      project = attributes_for(:project, { public: true })
214
      post api('/projects', user), project
215 216
      expect(json_response['public']).to be_truthy
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC)
217 218
    end

219
    it 'should set a project as internal' do
220
      project = attributes_for(:project, :internal)
221
      post api('/projects', user), project
222 223
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL)
224 225
    end

226
    it 'should set a project as internal overriding :public' do
227
      project = attributes_for(:project, :internal, { public: true })
228
      post api('/projects', user), project
229 230
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL)
231 232
    end

233
    it 'should set a project as private' do
234
      project = attributes_for(:project, :private)
235
      post api('/projects', user), project
236 237
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE)
238 239
    end

240
    it 'should set a project as private using :public' do
241
      project = attributes_for(:project, { public: false })
242
      post api('/projects', user), project
243 244
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE)
245
    end
246 247 248 249

    context 'when a visibility level is restricted' do
      before do
        @project = attributes_for(:project, { public: true })
250
        stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
      end

      it 'should not allow a non-admin to use a restricted visibility level' do
        post api('/projects', user), @project
        expect(response.status).to eq(400)
        expect(json_response['message']['visibility_level'].first).to(
          match('restricted by your GitLab administrator')
        )
      end

      it 'should allow an admin to override restricted visibility settings' do
        post api('/projects', admin), @project
        expect(json_response['public']).to be_truthy
        expect(json_response['visibility_level']).to(
          eq(Gitlab::VisibilityLevel::PUBLIC)
        )
      end
    end
269 270
  end

271
  describe 'POST /projects/user/:id' do
D
Dmitriy Zaporozhets 已提交
272
    before { project }
A
Angus MacArthur 已提交
273 274
    before { admin }

275
    it 'should create new project without path and return 201' do
276
      expect { post api("/projects/user/#{user.id}", admin), name: 'foo' }.to change {Project.count}.by(1)
277
      expect(response.status).to eq(201)
A
Angus MacArthur 已提交
278 279
    end

280 281
    it 'should respond with 400 on failure and not project' do
      expect { post api("/projects/user/#{user.id}", admin) }.
282
        not_to change { Project.count }
283

284 285
      expect(response.status).to eq(400)
      expect(json_response['message']['name']).to eq([
J
jubianchi 已提交
286 287
        'can\'t be blank',
        'is too short (minimum is 0 characters)',
D
Douwe Maan 已提交
288
        Gitlab::Regex.project_name_regex_message
289 290
      ])
      expect(json_response['message']['path']).to eq([
J
jubianchi 已提交
291 292
        'can\'t be blank',
        'is too short (minimum is 0 characters)',
D
Douwe Maan 已提交
293
        Gitlab::Regex.send(:project_path_regex_message)
294
      ])
A
Angus MacArthur 已提交
295 296
    end

297
    it 'should assign attributes to project' do
A
Angus MacArthur 已提交
298
      project = attributes_for(:project, {
R
Robert Speicher 已提交
299
        description: FFaker::Lorem.sentence,
300 301 302
        issues_enabled: false,
        merge_requests_enabled: false,
        wiki_enabled: false
A
Angus MacArthur 已提交
303 304 305 306
      })

      post api("/projects/user/#{user.id}", admin), project

307
      project.each_pair do |k,v|
A
Angus MacArthur 已提交
308
        next if k == :path
309
        expect(json_response[k.to_s]).to eq(v)
A
Angus MacArthur 已提交
310 311
      end
    end
312

313
    it 'should set a project as public' do
314
      project = attributes_for(:project, :public)
315
      post api("/projects/user/#{user.id}", admin), project
316 317
      expect(json_response['public']).to be_truthy
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC)
318 319
    end

320
    it 'should set a project as public using :public' do
321 322
      project = attributes_for(:project, { public: true })
      post api("/projects/user/#{user.id}", admin), project
323 324
      expect(json_response['public']).to be_truthy
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC)
325
    end
326

327
    it 'should set a project as internal' do
328
      project = attributes_for(:project, :internal)
329
      post api("/projects/user/#{user.id}", admin), project
330 331
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL)
332 333
    end

334
    it 'should set a project as internal overriding :public' do
335
      project = attributes_for(:project, :internal, { public: true })
336
      post api("/projects/user/#{user.id}", admin), project
337 338
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL)
339
    end
340

341
    it 'should set a project as private' do
342
      project = attributes_for(:project, :private)
343
      post api("/projects/user/#{user.id}", admin), project
344 345
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE)
346 347
    end

348
    it 'should set a project as private using :public' do
349 350
      project = attributes_for(:project, { public: false })
      post api("/projects/user/#{user.id}", admin), project
351 352
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE)
353
    end
A
Angus MacArthur 已提交
354 355
  end

356
  describe 'GET /projects/:id' do
D
Dmitriy Zaporozhets 已提交
357
    before { project }
358
    before { project_member }
D
Dmitriy Zaporozhets 已提交
359

360
    it 'should return a project by id' do
R
Robert Speicher 已提交
361
      get api("/projects/#{project.id}", user)
362 363 364
      expect(response.status).to eq(200)
      expect(json_response['name']).to eq(project.name)
      expect(json_response['owner']['username']).to eq(user.username)
N
Nihad Abbasov 已提交
365
    end
366

367
    it 'should return a project by path name' do
368
      get api("/projects/#{project.id}", user)
369 370
      expect(response.status).to eq(200)
      expect(json_response['name']).to eq(project.name)
371
    end
N
Nihad Abbasov 已提交
372

373 374
    it 'should return a 404 error if not found' do
      get api('/projects/42', user)
375 376
      expect(response.status).to eq(404)
      expect(json_response['message']).to eq('404 Project Not Found')
N
Nihad Abbasov 已提交
377
    end
378

379
    it 'should return a 404 error if user is not a member' do
380 381
      other_user = create(:user)
      get api("/projects/#{project.id}", other_user)
382
      expect(response.status).to eq(404)
383
    end
384

385 386 387 388 389 390 391 392 393
    it 'should handle users with dots' do
      dot_user = create(:user, username: 'dot.user')
      project = create(:project, creator_id: dot_user.id, namespace: dot_user.namespace)

      get api("/projects/#{dot_user.namespace.name}%2F#{project.path}", dot_user)
      expect(response.status).to eq(200)
      expect(json_response['name']).to eq(project.name)
    end

394
    describe 'permissions' do
395 396 397 398 399 400 401 402 403 404 405 406
      context 'all projects' do
        it 'Contains permission information' do
          project.team << [user, :master]
          get api("/projects", user)

          expect(response.status).to eq(200)
          expect(json_response.first['permissions']['project_access']['access_level']).
              to eq(Gitlab::Access::MASTER)
          expect(json_response.first['permissions']['group_access']).to be_nil
        end
      end

407
      context 'personal project' do
408
        it 'Sets project access and returns 200' do
D
Dmitriy Zaporozhets 已提交
409 410
          project.team << [user, :master]
          get api("/projects/#{project.id}", user)
411

412 413 414 415 416
          expect(response.status).to eq(200)
          expect(json_response['permissions']['project_access']['access_level']).
            to eq(Gitlab::Access::MASTER)
          expect(json_response['permissions']['group_access']).to be_nil
        end
417 418 419
      end

      context 'group project' do
420
        it 'should set the owner and return 200' do
421 422 423 424
          project2 = create(:project, group: create(:group))
          project2.group.add_owner(user)
          get api("/projects/#{project2.id}", user)

425 426 427 428 429
          expect(response.status).to eq(200)
          expect(json_response['permissions']['project_access']).to be_nil
          expect(json_response['permissions']['group_access']['access_level']).
            to eq(Gitlab::Access::OWNER)
        end
430 431
      end
    end
N
Nihad Abbasov 已提交
432 433
  end

434
  describe 'GET /projects/:id/events' do
D
Douwe Maan 已提交
435
    before { project_member2 }
D
Dmitriy Zaporozhets 已提交
436

D
Dmitriy Zaporozhets 已提交
437 438 439 440 441 442 443 444 445 446 447
    context 'valid request' do
      before do
        note = create(:note_on_issue, note: 'What an awesome day!', project: project)
        EventCreateService.new.leave_note(note, note.author)
        get api("/projects/#{project.id}/events", user)
      end

      it { expect(response.status).to eq(200) }

      context 'joined event' do
        let(:json_event) { json_response[1] }
D
Dmitriy Zaporozhets 已提交
448

D
Dmitriy Zaporozhets 已提交
449 450 451 452 453 454 455 456 457 458 459 460
        it { expect(json_event['action_name']).to eq('joined') }
        it { expect(json_event['project_id'].to_i).to eq(project.id) }
        it { expect(json_event['author_username']).to eq(user3.username) }
        it { expect(json_event['author']['name']).to eq(user3.name) }
      end

      context 'comment event' do
        let(:json_event) { json_response.first }

        it { expect(json_event['action_name']).to eq('commented on') }
        it { expect(json_event['note']['body']).to eq('What an awesome day!') }
      end
D
Dmitriy Zaporozhets 已提交
461 462
    end

463 464
    it 'should return a 404 error if not found' do
      get api('/projects/42/events', user)
465 466
      expect(response.status).to eq(404)
      expect(json_response['message']).to eq('404 Project Not Found')
D
Dmitriy Zaporozhets 已提交
467 468
    end

469
    it 'should return a 404 error if user is not a member' do
D
Dmitriy Zaporozhets 已提交
470 471
      other_user = create(:user)
      get api("/projects/#{project.id}/events", other_user)
472
      expect(response.status).to eq(404)
D
Dmitriy Zaporozhets 已提交
473 474 475
    end
  end

476
  describe 'GET /projects/:id/snippets' do
D
Dmitriy Zaporozhets 已提交
477 478
    before { snippet }

479
    it 'should return an array of project snippets' do
480
      get api("/projects/#{project.id}/snippets", user)
481 482 483
      expect(response.status).to eq(200)
      expect(json_response).to be_an Array
      expect(json_response.first['title']).to eq(snippet.title)
N
Nihad Abbasov 已提交
484 485 486
    end
  end

487 488
  describe 'GET /projects/:id/snippets/:snippet_id' do
    it 'should return a project snippet' do
489
      get api("/projects/#{project.id}/snippets/#{snippet.id}", user)
490 491
      expect(response.status).to eq(200)
      expect(json_response['title']).to eq(snippet.title)
N
Nihad Abbasov 已提交
492
    end
493

494
    it 'should return a 404 error if snippet id not found' do
495
      get api("/projects/#{project.id}/snippets/1234", user)
496
      expect(response.status).to eq(404)
497
    end
N
Nihad Abbasov 已提交
498 499
  end

500 501
  describe 'POST /projects/:id/snippets' do
    it 'should create a new project snippet' do
502
      post api("/projects/#{project.id}/snippets", user),
503 504
        title: 'api test', file_name: 'sample.rb', code: 'test',
        visibility_level: '0'
505 506
      expect(response.status).to eq(201)
      expect(json_response['title']).to eq('api test')
N
Nihad Abbasov 已提交
507
    end
508

509 510 511
    it 'should return a 400 error if invalid snippet is given' do
      post api("/projects/#{project.id}/snippets", user)
      expect(status).to eq(400)
512
    end
N
Nihad Abbasov 已提交
513 514
  end

515
  describe 'PUT /projects/:id/snippets/:snippet_id' do
516
    it 'should update an existing project snippet' do
517
      put api("/projects/#{project.id}/snippets/#{snippet.id}", user),
518
        code: 'updated code'
519 520 521
      expect(response.status).to eq(200)
      expect(json_response['title']).to eq('example')
      expect(snippet.reload.content).to eq('updated code')
522
    end
523

524
    it 'should update an existing project snippet with new title' do
525
      put api("/projects/#{project.id}/snippets/#{snippet.id}", user),
526
        title: 'other api test'
527 528
      expect(response.status).to eq(200)
      expect(json_response['title']).to eq('other api test')
529
    end
530 531
  end

532
  describe 'DELETE /projects/:id/snippets/:snippet_id' do
D
Dmitriy Zaporozhets 已提交
533 534
    before { snippet }

535
    it 'should delete existing project snippet' do
536
      expect do
537
        delete api("/projects/#{project.id}/snippets/#{snippet.id}", user)
538
      end.to change { Snippet.count }.by(-1)
539
      expect(response.status).to eq(200)
540 541
    end

J
jubianchi 已提交
542
    it 'should return 404 when deleting unknown snippet id' do
543
      delete api("/projects/#{project.id}/snippets/1234", user)
544
      expect(response.status).to eq(404)
N
Nihad Abbasov 已提交
545 546
    end
  end
547

548 549
  describe 'GET /projects/:id/snippets/:snippet_id/raw' do
    it 'should get a raw project snippet' do
550
      get api("/projects/#{project.id}/snippets/#{snippet.id}/raw", user)
551
      expect(response.status).to eq(200)
552
    end
553

554
    it 'should return a 404 error if raw project snippet not found' do
555
      get api("/projects/#{project.id}/snippets/5555/raw", user)
556
      expect(response.status).to eq(404)
557
    end
558
  end
559

560 561 562
  describe :deploy_keys do
    let(:deploy_keys_project) { create(:deploy_keys_project, project: project) }
    let(:deploy_key) { deploy_keys_project.deploy_key }
M
Matt Humphrey 已提交
563

564
    describe 'GET /projects/:id/keys' do
565
      before { deploy_key }
M
Matt Humphrey 已提交
566

567
      it 'should return array of ssh keys' do
568
        get api("/projects/#{project.id}/keys", user)
569 570 571
        expect(response.status).to eq(200)
        expect(json_response).to be_an Array
        expect(json_response.first['title']).to eq(deploy_key.title)
572
      end
M
Matt Humphrey 已提交
573 574
    end

575 576
    describe 'GET /projects/:id/keys/:key_id' do
      it 'should return a single key' do
577
        get api("/projects/#{project.id}/keys/#{deploy_key.id}", user)
578 579
        expect(response.status).to eq(200)
        expect(json_response['title']).to eq(deploy_key.title)
580
      end
M
Matt Humphrey 已提交
581

582
      it 'should return 404 Not Found with invalid ID' do
583
        get api("/projects/#{project.id}/keys/404", user)
584
        expect(response.status).to eq(404)
585
      end
M
Matt Humphrey 已提交
586 587
    end

588 589 590
    describe 'POST /projects/:id/keys' do
      it 'should not create an invalid ssh key' do
        post api("/projects/#{project.id}/keys", user), { title: 'invalid key' }
591 592
        expect(response.status).to eq(400)
        expect(json_response['message']['key']).to eq([
J
jubianchi 已提交
593 594 595
          'can\'t be blank',
          'is too short (minimum is 0 characters)',
          'is invalid'
596
        ])
J
jubianchi 已提交
597 598 599 600
      end

      it 'should not create a key without title' do
        post api("/projects/#{project.id}/keys", user), key: 'some key'
601 602
        expect(response.status).to eq(400)
        expect(json_response['message']['title']).to eq([
J
jubianchi 已提交
603 604
          'can\'t be blank',
          'is too short (minimum is 0 characters)'
605
        ])
606 607
      end

608
      it 'should create new ssh key' do
609
        key_attrs = attributes_for :key
610
        expect do
611
          post api("/projects/#{project.id}/keys", user), key_attrs
612
        end.to change{ project.deploy_keys.count }.by(1)
613
      end
M
Matt Humphrey 已提交
614 615
    end

616
    describe 'DELETE /projects/:id/keys/:key_id' do
617 618
      before { deploy_key }

619
      it 'should delete existing key' do
620
        expect do
621
          delete api("/projects/#{project.id}/keys/#{deploy_key.id}", user)
622
        end.to change{ project.deploy_keys.count }.by(-1)
623 624
      end

625
      it 'should return 404 Not Found with invalid ID' do
626
        delete api("/projects/#{project.id}/keys/404", user)
627
        expect(response.status).to eq(404)
628
      end
M
Matt Humphrey 已提交
629 630
    end
  end
631 632 633

  describe :fork_admin do
    let(:project_fork_target) { create(:project) }
634
    let(:project_fork_source) { create(:project, :public) }
635

636
    describe 'POST /projects/:id/fork/:forked_from_id' do
637
      let(:new_project_fork_source) { create(:project, :public) }
638 639 640

      it "shouldn't available for non admin users" do
        post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
641
        expect(response.status).to eq(403)
642 643
      end

644
      it 'should allow project to be forked from an existing project' do
645
        expect(project_fork_target.forked?).not_to be_truthy
646
        post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
647
        expect(response.status).to eq(201)
648
        project_fork_target.reload
649 650 651
        expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
        expect(project_fork_target.forked_project_link).not_to be_nil
        expect(project_fork_target.forked?).to be_truthy
652 653
      end

654
      it 'should fail if forked_from project which does not exist' do
655
        post api("/projects/#{project_fork_target.id}/fork/9999", admin)
656
        expect(response.status).to eq(404)
657 658
      end

659
      it 'should fail with 409 if already forked' do
660 661
        post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
        project_fork_target.reload
662
        expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
663
        post api("/projects/#{project_fork_target.id}/fork/#{new_project_fork_source.id}", admin)
664
        expect(response.status).to eq(409)
665
        project_fork_target.reload
666 667
        expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
        expect(project_fork_target.forked?).to be_truthy
668 669 670
      end
    end

671
    describe 'DELETE /projects/:id/fork' do
672

673
      it "shouldn't be visible to users outside group" do
674
        delete api("/projects/#{project_fork_target.id}/fork", user)
675
        expect(response.status).to eq(404)
676 677
      end

678 679
      context 'when users belong to project group' do
        let(:project_fork_target) { create(:project, group: create(:group)) }
680

681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
        before do
          project_fork_target.group.add_owner user
          project_fork_target.group.add_developer user2
        end

        it 'should be forbidden to non-owner users' do
          delete api("/projects/#{project_fork_target.id}/fork", user2)
          expect(response.status).to eq(403)
        end

        it 'should make forked project unforked' do
          post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
          project_fork_target.reload
          expect(project_fork_target.forked_from_project).not_to be_nil
          expect(project_fork_target.forked?).to be_truthy
          delete api("/projects/#{project_fork_target.id}/fork", admin)
          expect(response.status).to eq(200)
          project_fork_target.reload
          expect(project_fork_target.forked_from_project).to be_nil
          expect(project_fork_target.forked?).not_to be_truthy
        end

        it 'should be idempotent if not forked' do
          expect(project_fork_target.forked_from_project).to be_nil
          delete api("/projects/#{project_fork_target.id}/fork", admin)
          expect(response.status).to eq(200)
          expect(project_fork_target.reload.forked_from_project).to be_nil
        end
709 710 711
      end
    end
  end
712

713
  describe 'GET /projects/search/:query' do
714
    let!(:query) { 'query'}
D
Dmitriy Zaporozhets 已提交
715 716 717 718 719
    let!(:search)           { create(:empty_project, name: query, creator_id: user.id, namespace: user.namespace) }
    let!(:pre)              { create(:empty_project, name: "pre_#{query}", creator_id: user.id, namespace: user.namespace) }
    let!(:post)             { create(:empty_project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) }
    let!(:pre_post)         { create(:empty_project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) }
    let!(:unfound)          { create(:empty_project, name: 'unfound', creator_id: user.id, namespace: user.namespace) }
720 721 722 723
    let!(:internal)         { create(:empty_project, :internal, name: "internal #{query}") }
    let!(:unfound_internal) { create(:empty_project, :internal, name: 'unfound internal') }
    let!(:public)           { create(:empty_project, :public, name: "public #{query}") }
    let!(:unfound_public)   { create(:empty_project, :public, name: 'unfound public') }
724

725 726
    context 'when unauthenticated' do
      it 'should return authentication error' do
727
        get api("/projects/search/#{query}")
728
        expect(response.status).to eq(401)
729 730 731
      end
    end

732 733
    context 'when authenticated' do
      it 'should return an array of projects' do
734
        get api("/projects/search/#{query}",user)
735 736 737 738
        expect(response.status).to eq(200)
        expect(json_response).to be_an Array
        expect(json_response.size).to eq(6)
        json_response.each {|project| expect(project['name']).to match(/.*query.*/)}
739 740 741
      end
    end

742 743
    context 'when authenticated as a different user' do
      it 'should return matching public projects' do
744
        get api("/projects/search/#{query}", user2)
745 746 747 748
        expect(response.status).to eq(200)
        expect(json_response).to be_an Array
        expect(json_response.size).to eq(2)
        json_response.each {|project| expect(project['name']).to match(/(internal|public) query/)}
749 750 751
      end
    end
  end
752

753 754 755 756 757 758 759 760 761 762 763 764 765 766
  describe 'PUT /projects/:id̈́' do
    before { project }
    before { user }
    before { user3 }
    before { user4 }
    before { project3 }
    before { project4 }
    before { project_member3 }
    before { project_member2 }

    context 'when unauthenticated' do
      it 'should return authentication error' do
        project_param = { name: 'bar' }
        put api("/projects/#{project.id}"), project_param
767
        expect(response.status).to eq(401)
768 769 770 771 772 773 774
      end
    end

    context 'when authenticated as project owner' do
      it 'should update name' do
        project_param = { name: 'bar' }
        put api("/projects/#{project.id}", user), project_param
775
        expect(response.status).to eq(200)
776
        project_param.each_pair do |k, v|
777
          expect(json_response[k.to_s]).to eq(v)
778 779 780 781 782 783
        end
      end

      it 'should update visibility_level' do
        project_param = { visibility_level: 20 }
        put api("/projects/#{project3.id}", user), project_param
784
        expect(response.status).to eq(200)
785
        project_param.each_pair do |k, v|
786
          expect(json_response[k.to_s]).to eq(v)
787 788 789
        end
      end

790 791 792 793 794 795 796 797 798 799 800 801
      it 'should update visibility_level from public to private' do
        project3.update_attributes({ visibility_level: Gitlab::VisibilityLevel::PUBLIC })

        project_param = { public: false }
        put api("/projects/#{project3.id}", user), project_param
        expect(response.status).to eq(200)
        project_param.each_pair do |k, v|
          expect(json_response[k.to_s]).to eq(v)
        end
        expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE)
      end

802 803 804
      it 'should not update name to existing name' do
        project_param = { name: project3.name }
        put api("/projects/#{project.id}", user), project_param
805 806
        expect(response.status).to eq(400)
        expect(json_response['message']['name']).to eq(['has already been taken'])
807 808 809 810 811
      end

      it 'should update path & name to existing path & name in different namespace' do
        project_param = { path: project4.path, name: project4.name }
        put api("/projects/#{project3.id}", user), project_param
812
        expect(response.status).to eq(200)
813
        project_param.each_pair do |k, v|
814
          expect(json_response[k.to_s]).to eq(v)
815 816 817 818 819 820 821 822
        end
      end
    end

    context 'when authenticated as project master' do
      it 'should update path' do
        project_param = { path: 'bar' }
        put api("/projects/#{project3.id}", user4), project_param
823
        expect(response.status).to eq(200)
824
        project_param.each_pair do |k, v|
825
          expect(json_response[k.to_s]).to eq(v)
826 827 828 829 830 831 832 833 834 835 836
        end
      end

      it 'should update other attributes' do
        project_param = { issues_enabled: true,
                          wiki_enabled: true,
                          snippets_enabled: true,
                          merge_requests_enabled: true,
                          description: 'new description' }

        put api("/projects/#{project3.id}", user4), project_param
837
        expect(response.status).to eq(200)
838
        project_param.each_pair do |k, v|
839
          expect(json_response[k.to_s]).to eq(v)
840 841 842 843 844 845
        end
      end

      it 'should not update path to existing path' do
        project_param = { path: project.path }
        put api("/projects/#{project3.id}", user4), project_param
846 847
        expect(response.status).to eq(400)
        expect(json_response['message']['path']).to eq(['has already been taken'])
848 849 850 851 852
      end

      it 'should not update name' do
        project_param = { name: 'bar' }
        put api("/projects/#{project3.id}", user4), project_param
853
        expect(response.status).to eq(403)
854 855 856 857 858
      end

      it 'should not update visibility_level' do
        project_param = { visibility_level: 20 }
        put api("/projects/#{project3.id}", user4), project_param
859
        expect(response.status).to eq(403)
860 861 862 863 864 865 866 867 868 869 870 871
      end
    end

    context 'when authenticated as project developer' do
      it 'should not update other attributes' do
        project_param = { path: 'bar',
                          issues_enabled: true,
                          wiki_enabled: true,
                          snippets_enabled: true,
                          merge_requests_enabled: true,
                          description: 'new description' }
        put api("/projects/#{project.id}", user3), project_param
872
        expect(response.status).to eq(403)
873 874 875 876
      end
    end
  end

877 878 879
  describe 'DELETE /projects/:id' do
    context 'when authenticated as user' do
      it 'should remove project' do
880
        delete api("/projects/#{project.id}", user)
881
        expect(response.status).to eq(200)
882 883
      end

884
      it 'should not remove a project if not an owner' do
885 886 887
        user3 = create(:user)
        project.team << [user3, :developer]
        delete api("/projects/#{project.id}", user3)
888
        expect(response.status).to eq(403)
889 890
      end

891 892
      it 'should not remove a non existing project' do
        delete api('/projects/1328', user)
893
        expect(response.status).to eq(404)
894 895
      end

896
      it 'should not remove a project not attached to user' do
897
        delete api("/projects/#{project.id}", user2)
898
        expect(response.status).to eq(404)
899 900 901
      end
    end

902 903
    context 'when authenticated as admin' do
      it 'should remove any existing project' do
904
        delete api("/projects/#{project.id}", admin)
905
        expect(response.status).to eq(200)
906 907
      end

908 909
      it 'should not remove a non existing project' do
        delete api('/projects/1328', admin)
910
        expect(response.status).to eq(404)
911 912 913
      end
    end
  end
N
Nihad Abbasov 已提交
914
end