BigW Consortium Gitlab

projects_spec.rb 48.7 KB
Newer Older
1
# -*- coding: utf-8 -*-
Nihad Abbasov committed
2 3
require 'spec_helper'

4
describe API::Projects, 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) }
Angus MacArthur committed
10
  let(:admin) { create(:admin) }
11
  let(:project) { create(:project, creator_id: user.id, namespace: user.namespace) }
12
  let(:project2) { create(:project, path: 'project2', creator_id: user.id, namespace: user.namespace) }
13
  let(:snippet) { create(:project_snippet, :public, author: user, project: project, title: 'example') }
14 15
  let(:project_member) { create(:project_member, :master, user: user, project: project) }
  let(:project_member2) { create(:project_member, :developer, user: user3, project: project) }
16
  let(:user4) { create(:user) }
17 18
  let(:project3) do
    create(:project,
19
    :private,
20 21 22 23 24 25
    name: 'second_project',
    path: 'second_project',
    creator_id: user.id,
    namespace: user.namespace,
    merge_requests_enabled: false,
    issues_enabled: false, wiki_enabled: false,
26
    snippets_enabled: false)
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
  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
43 44
    before { project }

45
    context 'when unauthenticated' do
46
      it 'returns authentication error' do
47
        get api('/projects')
48
        expect(response).to have_http_status(401)
49
      end
Nihad Abbasov committed
50 51
    end

52
    context 'when authenticated' do
53
      it 'returns an array of projects' do
54
        get api('/projects', user)
55
        expect(response).to have_http_status(200)
56 57 58
        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)
Nihad Abbasov committed
59
      end
60

61
      it 'includes the project labels as the tag_list' do
62
        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

68
      it 'includes open_issues_count' do
69 70 71 72 73 74
        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

75
      it 'does not include open_issues_count' do
76
        project.project_feature.update_attribute(:issues_access_level, ProjectFeature::DISABLED)
77 78 79 80 81 82 83

        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
      context 'GET /projects?simple=true' do
85
        it 'returns a simplified version of all the projects' do
86
          expected_keys = ["id", "http_url_to_repo", "web_url", "name", "name_with_namespace", "path", "path_with_namespace"]
87

88
          get api('/projects?simple=true', user)
89

90 91
          expect(response).to have_http_status(200)
          expect(json_response).to be_an Array
92
          expect(json_response.first.keys).to match_array expected_keys
93 94 95
        end
      end

96
      context 'and using search' do
97
        it 'returns searched project' do
98
          get api('/projects', user), { search: project.name }
99
          expect(response).to have_http_status(200)
100 101
          expect(json_response).to be_an Array
          expect(json_response.length).to eq(1)
102 103 104
        end
      end

Josh Frye committed
105
      context 'and using the visibility filter' do
106
        it 'filters based on private visibility param' do
Josh Frye committed
107
          get api('/projects', user), { visibility: 'private' }
108
          expect(response).to have_http_status(200)
Josh Frye committed
109 110 111 112
          expect(json_response).to be_an Array
          expect(json_response.length).to eq(user.namespace.projects.where(visibility_level: Gitlab::VisibilityLevel::PRIVATE).count)
        end

113
        it 'filters based on internal visibility param' do
Josh Frye committed
114
          get api('/projects', user), { visibility: 'internal' }
115
          expect(response).to have_http_status(200)
Josh Frye committed
116 117 118 119
          expect(json_response).to be_an Array
          expect(json_response.length).to eq(user.namespace.projects.where(visibility_level: Gitlab::VisibilityLevel::INTERNAL).count)
        end

120
        it 'filters based on public visibility param' do
Josh Frye committed
121
          get api('/projects', user), { visibility: 'public' }
122
          expect(response).to have_http_status(200)
Josh Frye committed
123 124 125 126 127
          expect(json_response).to be_an Array
          expect(json_response.length).to eq(user.namespace.projects.where(visibility_level: Gitlab::VisibilityLevel::PUBLIC).count)
        end
      end

128
      context 'and using sorting' do
129 130 131 132 133
        before do
          project2
          project3
        end

134
        it 'returns the correct order when sorted by id' do
135
          get api('/projects', user), { order_by: 'id', sort: 'desc' }
136
          expect(response).to have_http_status(200)
137 138
          expect(json_response).to be_an Array
          expect(json_response.first['id']).to eq(project3.id)
139 140
        end
      end
Nihad Abbasov committed
141 142 143
    end
  end

144
  describe 'GET /projects/all' do
145 146
    before { project }

147
    context 'when unauthenticated' do
148
      it 'returns authentication error' do
149
        get api('/projects/all')
150
        expect(response).to have_http_status(401)
151 152 153
      end
    end

154
    context 'when authenticated as regular user' do
155
      it 'returns authentication error' do
156
        get api('/projects/all', user)
157
        expect(response).to have_http_status(403)
158 159 160
      end
    end

161
    context 'when authenticated as admin' do
162
      it 'returns an array of all projects' do
163
        get api('/projects/all', admin)
164
        expect(response).to have_http_status(200)
165
        expect(json_response).to be_an Array
Marin Jankovski committed
166

167 168
        expect(json_response).to satisfy do |response|
          response.one? do |entry|
169
            entry.has_key?('permissions') &&
170
            entry['name'] == project.name &&
171
              entry['owner']['username'] == user.username
172 173
          end
        end
174 175 176 177
      end
    end
  end

178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
  describe 'GET /projects/owned' do
    before do
      project3
      project4
    end

    context 'when unauthenticated' do
      it 'returns authentication error' do
        get api('/projects/owned')
        expect(response).to have_http_status(401)
      end
    end

    context 'when authenticated as project owner' do
      it 'returns an array of projects the user owns' do
        get api('/projects/owned', user4)
        expect(response).to have_http_status(200)
        expect(json_response).to be_an Array
        expect(json_response.first['name']).to eq(project4.name)
        expect(json_response.first['owner']['username']).to eq(user4.username)
      end
    end
  end

202
  describe 'GET /projects/visible' do
203 204 205 206 207 208 209 210 211
    shared_examples_for 'visible projects response' do
      it 'returns the visible projects' do
        get api('/projects/visible', current_user)

        expect(response).to have_http_status(200)
        expect(json_response).to be_an Array
        expect(json_response.map { |p| p['id'] }).to contain_exactly(*projects.map(&:id))
      end
    end
212

213
    let!(:public_project) { create(:project, :public) }
214 215 216 217 218 219 220
    before do
      project
      project2
      project3
      project4
    end

221 222 223 224 225
    context 'when unauthenticated' do
      it_behaves_like 'visible projects response' do
        let(:current_user) { nil }
        let(:projects) { [public_project] }
      end
226 227
    end

228 229 230 231 232 233
    context 'when authenticated' do
      it_behaves_like 'visible projects response' do
        let(:current_user) { user }
        let(:projects) { [public_project, project, project2, project3] }
      end
    end
234

235 236 237 238 239
    context 'when authenticated as a different user' do
      it_behaves_like 'visible projects response' do
        let(:current_user) { user2 }
        let(:projects) { [public_project] }
      end
240 241 242
    end
  end

243
  describe 'GET /projects/starred' do
244 245
    let(:public_project) { create(:project, :public) }

246
    before do
247 248
      project_member2
      user3.update_attributes(starred_projects: [project, project2, project3, public_project])
249 250
    end

251
    it 'returns the starred projects viewable by the user' do
252
      get api('/projects/starred', user3)
253
      expect(response).to have_http_status(200)
254
      expect(json_response).to be_an Array
255
      expect(json_response.map { |project| project['id'] }).to contain_exactly(project.id, public_project.id)
256 257 258
    end
  end

259 260
  describe 'POST /projects' do
    context 'maximum number of projects reached' do
261
      it 'does not create new project and respond with 403' do
262
        allow_any_instance_of(User).to receive(:projects_limit_left).and_return(0)
263 264
        expect { post api('/projects', user2), name: 'foo' }.
          to change {Project.count}.by(0)
265
        expect(response).to have_http_status(403)
266 267 268
      end
    end

269
    it 'creates new project without path and return 201' do
270 271
      expect { post api('/projects', user), name: 'foo' }.
        to change { Project.count }.by(1)
272
      expect(response).to have_http_status(201)
273 274
    end

275
    it 'creates last project before reaching project limit' do
276
      allow_any_instance_of(User).to receive(:projects_limit_left).and_return(1)
277
      post api('/projects', user2), name: 'foo'
278
      expect(response).to have_http_status(201)
279 280
    end

281
    it 'does not create new project without name and return 400' do
282
      expect { post api('/projects', user) }.not_to change { Project.count }
283
      expect(response).to have_http_status(400)
284
    end
Alex Denisov committed
285

286
    it "assigns attributes to project" do
287
      project = attributes_for(:project, {
288
        path: 'camelCasePath',
Robert Speicher committed
289
        description: FFaker::Lorem.sentence,
290 291
        issues_enabled: false,
        merge_requests_enabled: false,
292
        wiki_enabled: false,
293
        only_allow_merge_if_build_succeeds: false,
294 295
        request_access_enabled: true,
        only_allow_merge_if_all_discussions_are_resolved: false
Alex Denisov committed
296 297
      })

298
      post api('/projects', user), project
Alex Denisov committed
299

300
      project.each_pair do |k, v|
301
        next if %i[has_external_issue_tracker issues_enabled merge_requests_enabled wiki_enabled].include?(k)
302
        expect(json_response[k.to_s]).to eq(v)
Alex Denisov committed
303
      end
304 305 306 307 308 309

      # Check feature permissions attributes
      project = Project.find_by_path(project[:path])
      expect(project.project_feature.issues_access_level).to eq(ProjectFeature::DISABLED)
      expect(project.project_feature.merge_requests_access_level).to eq(ProjectFeature::DISABLED)
      expect(project.project_feature.wiki_access_level).to eq(ProjectFeature::DISABLED)
310
    end
311

312
    it 'sets a project as public' do
313
      project = attributes_for(:project, :public)
314
      post api('/projects', user), project
315 316
      expect(json_response['public']).to be_truthy
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC)
317 318
    end

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

326
    it 'sets a project as internal' do
327
      project = attributes_for(:project, :internal)
328
      post api('/projects', user), project
329 330
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL)
331 332
    end

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

340
    it 'sets a project as private' do
341
      project = attributes_for(:project, :private)
342
      post api('/projects', user), project
343 344
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE)
345 346
    end

347
    it 'sets a project as private using :public' do
348
      project = attributes_for(:project, { public: false })
349
      post api('/projects', user), project
350 351
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE)
352
    end
353

354 355 356 357 358 359 360 361 362 363 364 365
    it 'sets a project as allowing merge even if build fails' do
      project = attributes_for(:project, { only_allow_merge_if_build_succeeds: false })
      post api('/projects', user), project
      expect(json_response['only_allow_merge_if_build_succeeds']).to be_falsey
    end

    it 'sets a project as allowing merge only if build succeeds' do
      project = attributes_for(:project, { only_allow_merge_if_build_succeeds: true })
      post api('/projects', user), project
      expect(json_response['only_allow_merge_if_build_succeeds']).to be_truthy
    end

366 367 368 369 370 371 372 373
    it 'sets a project as allowing merge even if discussions are unresolved' do
      project = attributes_for(:project, { only_allow_merge_if_all_discussions_are_resolved: false })

      post api('/projects', user), project

      expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_falsey
    end

374 375 376 377 378 379 380 381
    it 'sets a project as allowing merge if only_allow_merge_if_all_discussions_are_resolved is nil' do
      project = attributes_for(:project, only_allow_merge_if_all_discussions_are_resolved: nil)

      post api('/projects', user), project

      expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_falsey
    end

382 383 384 385 386 387 388 389
    it 'sets a project as allowing merge only if all discussions are resolved' do
      project = attributes_for(:project, { only_allow_merge_if_all_discussions_are_resolved: true })

      post api('/projects', user), project

      expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_truthy
    end

390 391 392
    context 'when a visibility level is restricted' do
      before do
        @project = attributes_for(:project, { public: true })
393
        stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
394 395
      end

396
      it 'does not allow a non-admin to use a restricted visibility level' do
397
        post api('/projects', user), @project
Felipe Artur committed
398

399
        expect(response).to have_http_status(400)
400 401 402 403 404
        expect(json_response['message']['visibility_level'].first).to(
          match('restricted by your GitLab administrator')
        )
      end

405
      it 'allows an admin to override restricted visibility settings' do
406 407 408 409 410 411 412
        post api('/projects', admin), @project
        expect(json_response['public']).to be_truthy
        expect(json_response['visibility_level']).to(
          eq(Gitlab::VisibilityLevel::PUBLIC)
        )
      end
    end
413 414
  end

415
  describe 'POST /projects/user/:id' do
416
    before { project }
Angus MacArthur committed
417 418
    before { admin }

419
    it 'should create new project without path and return 201' do
420
      expect { post api("/projects/user/#{user.id}", admin), name: 'foo' }.to change {Project.count}.by(1)
421
      expect(response).to have_http_status(201)
Angus MacArthur committed
422 423
    end

424
    it 'responds with 400 on failure and not project' do
425
      expect { post api("/projects/user/#{user.id}", admin) }.
426
        not_to change { Project.count }
427

428
      expect(response).to have_http_status(400)
429
      expect(json_response['error']).to eq('name is missing')
Angus MacArthur committed
430 431
    end

432
    it 'assigns attributes to project' do
Angus MacArthur committed
433
      project = attributes_for(:project, {
Robert Speicher committed
434
        description: FFaker::Lorem.sentence,
435 436
        issues_enabled: false,
        merge_requests_enabled: false,
437 438
        wiki_enabled: false,
        request_access_enabled: true
Angus MacArthur committed
439 440 441 442
      })

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

443
      expect(response).to have_http_status(201)
444
      project.each_pair do |k, v|
445
        next if %i[has_external_issue_tracker path].include?(k)
446
        expect(json_response[k.to_s]).to eq(v)
Angus MacArthur committed
447 448
      end
    end
449

450
    it 'sets a project as public' do
451
      project = attributes_for(:project, :public)
452
      post api("/projects/user/#{user.id}", admin), project
453 454

      expect(response).to have_http_status(201)
455 456
      expect(json_response['public']).to be_truthy
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC)
457 458
    end

459
    it 'sets a project as public using :public' do
460 461
      project = attributes_for(:project, { public: true })
      post api("/projects/user/#{user.id}", admin), project
462 463

      expect(response).to have_http_status(201)
464 465
      expect(json_response['public']).to be_truthy
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PUBLIC)
466
    end
467

468
    it 'sets a project as internal' do
469
      project = attributes_for(:project, :internal)
470
      post api("/projects/user/#{user.id}", admin), project
471 472

      expect(response).to have_http_status(201)
473 474
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL)
475 476
    end

477
    it 'sets a project as internal overriding :public' do
478
      project = attributes_for(:project, :internal, { public: true })
479
      post api("/projects/user/#{user.id}", admin), project
480
      expect(response).to have_http_status(201)
481 482
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::INTERNAL)
483
    end
484

485
    it 'sets a project as private' do
486
      project = attributes_for(:project, :private)
487
      post api("/projects/user/#{user.id}", admin), project
488 489
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE)
490 491
    end

492
    it 'sets a project as private using :public' do
493 494
      project = attributes_for(:project, { public: false })
      post api("/projects/user/#{user.id}", admin), project
495 496
      expect(json_response['public']).to be_falsey
      expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE)
497
    end
498 499 500 501 502 503 504 505 506 507 508 509

    it 'sets a project as allowing merge even if build fails' do
      project = attributes_for(:project, { only_allow_merge_if_build_succeeds: false })
      post api("/projects/user/#{user.id}", admin), project
      expect(json_response['only_allow_merge_if_build_succeeds']).to be_falsey
    end

    it 'sets a project as allowing merge only if build succeeds' do
      project = attributes_for(:project, { only_allow_merge_if_build_succeeds: true })
      post api("/projects/user/#{user.id}", admin), project
      expect(json_response['only_allow_merge_if_build_succeeds']).to be_truthy
    end
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525

    it 'sets a project as allowing merge even if discussions are unresolved' do
      project = attributes_for(:project, { only_allow_merge_if_all_discussions_are_resolved: false })

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

      expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_falsey
    end

    it 'sets a project as allowing merge only if all discussions are resolved' do
      project = attributes_for(:project, { only_allow_merge_if_all_discussions_are_resolved: true })

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

      expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to be_truthy
    end
Angus MacArthur committed
526 527
  end

528 529 530 531 532 533
  describe "POST /projects/:id/uploads" do
    before { project }

    it "uploads the file and returns its info" do
      post api("/projects/#{project.id}/uploads", user), file: fixture_file_upload(Rails.root + "spec/fixtures/dk.png", "image/png")

534
      expect(response).to have_http_status(201)
535 536 537 538 539 540
      expect(json_response['alt']).to eq("dk")
      expect(json_response['url']).to start_with("/uploads/")
      expect(json_response['url']).to end_with("/dk.png")
    end
  end

541
  describe 'GET /projects/:id' do
542 543 544
    context 'when unauthenticated' do
      it 'returns the public projects' do
        public_project = create(:project, :public)
545

546
        get api("/projects/#{public_project.id}")
547

548 549 550 551 552
        expect(response).to have_http_status(200)
        expect(json_response['id']).to eq(public_project.id)
        expect(json_response['description']).to eq(public_project.description)
        expect(json_response.keys).not_to include('permissions')
      end
553
    end
554

555 556 557 558 559
    context 'when authenticated' do
      before do
        project
        project_member
      end
560

561 562 563
      it 'returns a project by id' do
        group = create(:group)
        link = create(:project_group_link, project: project, group: group)
564

565
        get api("/projects/#{project.id}", user)
566

567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604
        expect(response).to have_http_status(200)
        expect(json_response['id']).to eq(project.id)
        expect(json_response['description']).to eq(project.description)
        expect(json_response['default_branch']).to eq(project.default_branch)
        expect(json_response['tag_list']).to be_an Array
        expect(json_response['public']).to be_falsey
        expect(json_response['archived']).to be_falsey
        expect(json_response['visibility_level']).to be_present
        expect(json_response['ssh_url_to_repo']).to be_present
        expect(json_response['http_url_to_repo']).to be_present
        expect(json_response['web_url']).to be_present
        expect(json_response['owner']).to be_a Hash
        expect(json_response['owner']).to be_a Hash
        expect(json_response['name']).to eq(project.name)
        expect(json_response['path']).to be_present
        expect(json_response['issues_enabled']).to be_present
        expect(json_response['merge_requests_enabled']).to be_present
        expect(json_response['wiki_enabled']).to be_present
        expect(json_response['builds_enabled']).to be_present
        expect(json_response['snippets_enabled']).to be_present
        expect(json_response['container_registry_enabled']).to be_present
        expect(json_response['created_at']).to be_present
        expect(json_response['last_activity_at']).to be_present
        expect(json_response['shared_runners_enabled']).to be_present
        expect(json_response['creator_id']).to be_present
        expect(json_response['namespace']).to be_present
        expect(json_response['avatar_url']).to be_nil
        expect(json_response['star_count']).to be_present
        expect(json_response['forks_count']).to be_present
        expect(json_response['public_builds']).to be_present
        expect(json_response['shared_with_groups']).to be_an Array
        expect(json_response['shared_with_groups'].length).to eq(1)
        expect(json_response['shared_with_groups'][0]['group_id']).to eq(group.id)
        expect(json_response['shared_with_groups'][0]['group_name']).to eq(group.name)
        expect(json_response['shared_with_groups'][0]['group_access_level']).to eq(link.group_access)
        expect(json_response['only_allow_merge_if_build_succeeds']).to eq(project.only_allow_merge_if_build_succeeds)
        expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
      end
605

606 607 608 609 610
      it 'returns a project by path name' do
        get api("/projects/#{project.id}", user)
        expect(response).to have_http_status(200)
        expect(json_response['name']).to eq(project.name)
      end
611

612 613 614 615 616
      it 'returns a 404 error if not found' do
        get api('/projects/42', user)
        expect(response).to have_http_status(404)
        expect(json_response['message']).to eq('404 Project Not Found')
      end
617

618 619 620 621
      it 'returns a 404 error if user is not a member' do
        other_user = create(:user)
        get api("/projects/#{project.id}", other_user)
        expect(response).to have_http_status(404)
622 623
      end

624 625 626
      it 'handles users with dots' do
        dot_user = create(:user, username: 'dot.user')
        project = create(:project, creator_id: dot_user.id, namespace: dot_user.namespace)
627

628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
        get api("/projects/#{dot_user.namespace.name}%2F#{project.path}", dot_user)
        expect(response).to have_http_status(200)
        expect(json_response['name']).to eq(project.name)
      end

      describe 'permissions' do
        context 'all projects' do
          before { project.team << [user, :master] }

          it 'contains permission information' do
            get api("/projects", user)

            expect(response).to have_http_status(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

        context 'personal project' do
          it 'sets project access and returns 200' do
            project.team << [user, :master]
            get api("/projects/#{project.id}", user)

            expect(response).to have_http_status(200)
            expect(json_response['permissions']['project_access']['access_level']).
654
            to eq(Gitlab::Access::MASTER)
655 656
            expect(json_response['permissions']['group_access']).to be_nil
          end
657
        end
658

659 660
        context 'group project' do
          let(:project2) { create(:project, group: create(:group)) }
661

662
          before { project2.group.add_owner(user) }
663

664 665
          it 'sets the owner and return 200' do
            get api("/projects/#{project2.id}", user)
666

667 668 669
            expect(response).to have_http_status(200)
            expect(json_response['permissions']['project_access']).to be_nil
            expect(json_response['permissions']['group_access']['access_level']).
670
            to eq(Gitlab::Access::OWNER)
671
          end
672
        end
673 674
      end
    end
Nihad Abbasov committed
675 676
  end

677
  describe 'GET /projects/:id/events' do
678 679 680 681
    shared_examples_for 'project events response' do
      it 'returns the project events' do
        member = create(:user)
        create(:project_member, :developer, user: member, project: project)
682 683 684
        note = create(:note_on_issue, note: 'What an awesome day!', project: project)
        EventCreateService.new.leave_note(note, note.author)

685
        get api("/projects/#{project.id}/events", current_user)
686

687
        expect(response).to have_http_status(200)
688

689
        first_event = json_response.first
690

691 692
        expect(first_event['action_name']).to eq('commented on')
        expect(first_event['note']['body']).to eq('What an awesome day!')
693

694 695 696 697
        last_event = json_response.last

        expect(last_event['action_name']).to eq('joined')
        expect(last_event['project_id'].to_i).to eq(project.id)
698 699
        expect(last_event['author_username']).to eq(member.username)
        expect(last_event['author']['name']).to eq(member.name)
700
      end
701 702
    end

703 704 705 706 707 708
    context 'when unauthenticated' do
      it_behaves_like 'project events response' do
        let(:project) { create(:project, :public) }
        let(:current_user) { nil }
      end
    end
709

710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
    context 'when authenticated' do
      context 'valid request' do
        it_behaves_like 'project events response' do
          let(:current_user) { user }
        end
      end

      it 'returns a 404 error if not found' do
        get api('/projects/42/events', user)

        expect(response).to have_http_status(404)
        expect(json_response['message']).to eq('404 Project Not Found')
      end

      it 'returns a 404 error if user is not a member' do
        other_user = create(:user)

        get api("/projects/#{project.id}/events", other_user)

        expect(response).to have_http_status(404)
      end
731
    end
732
  end
733

734 735 736 737 738
  describe 'GET /projects/:id/users' do
    shared_examples_for 'project users response' do
      it 'returns the project users' do
        member = create(:user)
        create(:project_member, :developer, user: member, project: project)
739

740
        get api("/projects/#{project.id}/users", current_user)
741

742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781
        expect(response).to have_http_status(200)
        expect(json_response).to be_an Array
        expect(json_response.size).to eq(1)

        first_user = json_response.first

        expect(first_user['username']).to eq(member.username)
        expect(first_user['name']).to eq(member.name)
        expect(first_user.keys).to contain_exactly(*%w[name username id state avatar_url web_url])
      end
    end

    context 'when unauthenticated' do
      it_behaves_like 'project users response' do
        let(:project) { create(:project, :public) }
        let(:current_user) { nil }
      end
    end

    context 'when authenticated' do
      context 'valid request' do
        it_behaves_like 'project users response' do
          let(:current_user) { user }
        end
      end

      it 'returns a 404 error if not found' do
        get api('/projects/42/users', user)

        expect(response).to have_http_status(404)
        expect(json_response['message']).to eq('404 Project Not Found')
      end

      it 'returns a 404 error if user is not a member' do
        other_user = create(:user)

        get api("/projects/#{project.id}/users", other_user)

        expect(response).to have_http_status(404)
      end
782 783 784
    end
  end

785
  describe 'GET /projects/:id/snippets' do
786 787
    before { snippet }

788
    it 'returns an array of project snippets' do
789
      get api("/projects/#{project.id}/snippets", user)
790
      expect(response).to have_http_status(200)
791 792
      expect(json_response).to be_an Array
      expect(json_response.first['title']).to eq(snippet.title)
793 794 795
    end
  end

796
  describe 'GET /projects/:id/snippets/:snippet_id' do
797
    it 'returns a project snippet' do
798
      get api("/projects/#{project.id}/snippets/#{snippet.id}", user)
799
      expect(response).to have_http_status(200)
800
      expect(json_response['title']).to eq(snippet.title)
Nihad Abbasov committed
801
    end
802

803
    it 'returns a 404 error if snippet id not found' do
804
      get api("/projects/#{project.id}/snippets/1234", user)
805
      expect(response).to have_http_status(404)
806
    end
Nihad Abbasov committed
807 808
  end

809
  describe 'POST /projects/:id/snippets' do
810
    it 'creates a new project snippet' do
811
      post api("/projects/#{project.id}/snippets", user),
812 813
        title: 'api test', file_name: 'sample.rb', code: 'test',
        visibility_level: '0'
814
      expect(response).to have_http_status(201)
815
      expect(json_response['title']).to eq('api test')
Nihad Abbasov committed
816
    end
817

818
    it 'returns a 400 error if invalid snippet is given' do
819 820
      post api("/projects/#{project.id}/snippets", user)
      expect(status).to eq(400)
821
    end
Nihad Abbasov committed
822 823
  end

824
  describe 'PUT /projects/:id/snippets/:snippet_id' do
825
    it 'updates an existing project snippet' do
826
      put api("/projects/#{project.id}/snippets/#{snippet.id}", user),
827
        code: 'updated code'
828
      expect(response).to have_http_status(200)
829 830
      expect(json_response['title']).to eq('example')
      expect(snippet.reload.content).to eq('updated code')
831
    end
832

833
    it 'updates an existing project snippet with new title' do
834
      put api("/projects/#{project.id}/snippets/#{snippet.id}", user),
835
        title: 'other api test'
836
      expect(response).to have_http_status(200)
837
      expect(json_response['title']).to eq('other api test')
838
    end
839 840
  end

841
  describe 'DELETE /projects/:id/snippets/:snippet_id' do
842 843
    before { snippet }

844
    it 'deletes existing project snippet' do
845
      expect do
846
        delete api("/projects/#{project.id}/snippets/#{snippet.id}", user)
847
      end.to change { Snippet.count }.by(-1)
848
      expect(response).to have_http_status(200)
849 850
    end

851
    it 'returns 404 when deleting unknown snippet id' do
852
      delete api("/projects/#{project.id}/snippets/1234", user)
853
      expect(response).to have_http_status(404)
Nihad Abbasov committed
854 855
    end
  end
856

857
  describe 'GET /projects/:id/snippets/:snippet_id/raw' do
858
    it 'gets a raw project snippet' do
859
      get api("/projects/#{project.id}/snippets/#{snippet.id}/raw", user)
860
      expect(response).to have_http_status(200)
861
    end
862

863
    it 'returns a 404 error if raw project snippet not found' do
864
      get api("/projects/#{project.id}/snippets/5555/raw", user)
865
      expect(response).to have_http_status(404)
866
    end
867
  end
868

869 870
  describe :fork_admin do
    let(:project_fork_target) { create(:project) }
871
    let(:project_fork_source) { create(:project, :public) }
872

873
    describe 'POST /projects/:id/fork/:forked_from_id' do
874
      let(:new_project_fork_source) { create(:project, :public) }
875

876
      it "is not available for non admin users" do
877
        post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
878
        expect(response).to have_http_status(403)
879 880
      end

881
      it 'allows project to be forked from an existing project' do
882
        expect(project_fork_target.forked?).not_to be_truthy
883
        post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
884
        expect(response).to have_http_status(201)
885
        project_fork_target.reload
886 887 888
        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
889 890
      end

891
      it 'fails if forked_from project which does not exist' do
892
        post api("/projects/#{project_fork_target.id}/fork/9999", admin)
893
        expect(response).to have_http_status(404)
894 895
      end

896
      it 'fails with 409 if already forked' do
897 898
        post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
        project_fork_target.reload
899
        expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
900
        post api("/projects/#{project_fork_target.id}/fork/#{new_project_fork_source.id}", admin)
901
        expect(response).to have_http_status(409)
902
        project_fork_target.reload
903 904
        expect(project_fork_target.forked_from_project.id).to eq(project_fork_source.id)
        expect(project_fork_target.forked?).to be_truthy
905 906 907
      end
    end

908
    describe 'DELETE /projects/:id/fork' do
909
      it "is not visible to users outside group" do
910
        delete api("/projects/#{project_fork_target.id}/fork", user)
911
        expect(response).to have_http_status(404)
912 913
      end

914 915
      context 'when users belong to project group' do
        let(:project_fork_target) { create(:project, group: create(:group)) }
916

917 918 919 920 921
        before do
          project_fork_target.group.add_owner user
          project_fork_target.group.add_developer user2
        end

922
        it 'is forbidden to non-owner users' do
923
          delete api("/projects/#{project_fork_target.id}/fork", user2)
924
          expect(response).to have_http_status(403)
925 926
        end

927
        it 'makes forked project unforked' do
928 929 930 931 932
          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)
933
          expect(response).to have_http_status(200)
934 935 936 937 938
          project_fork_target.reload
          expect(project_fork_target.forked_from_project).to be_nil
          expect(project_fork_target.forked?).not_to be_truthy
        end

939
        it 'is idempotent if not forked' do
940 941
          expect(project_fork_target.forked_from_project).to be_nil
          delete api("/projects/#{project_fork_target.id}/fork", admin)
942
          expect(response).to have_http_status(304)
943 944
          expect(project_fork_target.reload.forked_from_project).to be_nil
        end
945 946 947
      end
    end
  end
948

949 950 951
  describe "POST /projects/:id/share" do
    let(:group) { create(:group) }

952
    it "shares project with group" do
953 954
      expires_at = 10.days.from_now.to_date

955
      expect do
956
        post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: Gitlab::Access::DEVELOPER, expires_at: expires_at
957 958
      end.to change { ProjectGroupLink.count }.by(1)

959
      expect(response).to have_http_status(201)
960 961 962
      expect(json_response['group_id']).to eq(group.id)
      expect(json_response['group_access']).to eq(Gitlab::Access::DEVELOPER)
      expect(json_response['expires_at']).to eq(expires_at.to_s)
963 964
    end

965
    it "returns a 400 error when group id is not given" do
966
      post api("/projects/#{project.id}/share", user), group_access: Gitlab::Access::DEVELOPER
967
      expect(response).to have_http_status(400)
968 969
    end

970
    it "returns a 400 error when access level is not given" do
971
      post api("/projects/#{project.id}/share", user), group_id: group.id
972
      expect(response).to have_http_status(400)
973 974
    end

975
    it "returns a 400 error when sharing is disabled" do
976 977
      project.namespace.update(share_with_group_lock: true)
      post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: Gitlab::Access::DEVELOPER
978
      expect(response).to have_http_status(400)
979 980
    end

981 982 983 984 985
    it 'returns a 404 error when user cannot read group' do
      private_group = create(:group, :private)

      post api("/projects/#{project.id}/share", user), group_id: private_group.id, group_access: Gitlab::Access::DEVELOPER

986
      expect(response).to have_http_status(404)
987 988 989 990 991
    end

    it 'returns a 404 error when group does not exist' do
      post api("/projects/#{project.id}/share", user), group_id: 1234, group_access: Gitlab::Access::DEVELOPER

992
      expect(response).to have_http_status(404)
993 994
    end

995
    it "returns a 400 error when wrong params passed" do
996
      post api("/projects/#{project.id}/share", user), group_id: group.id, group_access: 1234
997 998 999

      expect(response).to have_http_status(400)
      expect(json_response['error']).to eq 'group_access does not have a valid value'
1000 1001 1002
    end
  end

1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
  describe 'DELETE /projects/:id/share/:group_id' do
    it 'returns 204 when deleting a group share' do
      group = create(:group, :public)
      create(:project_group_link, group: group, project: project)

      delete api("/projects/#{project.id}/share/#{group.id}", user)

      expect(response).to have_http_status(204)
      expect(project.project_group_links).to be_empty
    end

    it 'returns a 400 when group id is not an integer' do
      delete api("/projects/#{project.id}/share/foo", user)

      expect(response).to have_http_status(400)
    end

    it 'returns a 404 error when group link does not exist' do
      delete api("/projects/#{project.id}/share/1234", user)

      expect(response).to have_http_status(404)
    end

    it 'returns a 404 error when project does not exist' do
      delete api("/projects/123/share/1234", user)

      expect(response).to have_http_status(404)
    end
  end

1033
  describe 'GET /projects/search/:query' do
1034
    let!(:query) { 'query'}
1035 1036 1037 1038 1039
    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) }
1040 1041 1042 1043
    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') }
1044

1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
    shared_examples_for 'project search response' do |args = {}|
      it 'returns project search responses' do
        get api("/projects/search/#{query}", current_user)

        expect(response).to have_http_status(200)
        expect(json_response).to be_an Array
        expect(json_response.size).to eq(args[:results])
        json_response.each { |project| expect(project['name']).to match(args[:match_regex] || /.*query.*/) }
      end
    end

1056
    context 'when unauthenticated' do
1057 1058
      it_behaves_like 'project search response', results: 1 do
        let(:current_user) { nil }
1059 1060 1061
      end
    end

1062
    context 'when authenticated' do
1063 1064
      it_behaves_like 'project search response', results: 6 do
        let(:current_user) { user }
1065 1066 1067
      end
    end

1068
    context 'when authenticated as a different user' do
1069 1070
      it_behaves_like 'project search response', results: 2, match_regex: /(internal|public) query/ do
        let(:current_user) { user2 }
1071 1072 1073
      end
    end
  end
1074

1075
  describe 'PUT /projects/:id' do
1076 1077 1078 1079 1080 1081 1082 1083 1084 1085
    before { project }
    before { user }
    before { user3 }
    before { user4 }
    before { project3 }
    before { project4 }
    before { project_member3 }
    before { project_member2 }

    context 'when unauthenticated' do
1086
      it 'returns authentication error' do
1087 1088
        project_param = { name: 'bar' }
        put api("/projects/#{project.id}"), project_param
1089
        expect(response).to have_http_status(401)
1090 1091 1092 1093
      end
    end

    context 'when authenticated as project owner' do
1094
      it 'updates name' do
1095 1096
        project_param = { name: 'bar' }
        put api("/projects/#{project.id}", user), project_param
1097
        expect(response).to have_http_status(200)
1098
        project_param.each_pair do |k, v|
1099
          expect(json_response[k.to_s]).to eq(v)
1100 1101 1102
        end
      end

1103
      it 'updates visibility_level' do
1104 1105
        project_param = { visibility_level: 20 }
        put api("/projects/#{project3.id}", user), project_param
1106
        expect(response).to have_http_status(200)
1107
        project_param.each_pair do |k, v|
1108
          expect(json_response[k.to_s]).to eq(v)
1109 1110 1111
        end
      end

1112
      it 'updates visibility_level from public to private' do
1113 1114 1115
        project3.update_attributes({ visibility_level: Gitlab::VisibilityLevel::PUBLIC })
        project_param = { public: false }
        put api("/projects/#{project3.id}", user), project_param
1116
        expect(response).to have_http_status(200)
1117 1118 1119 1120 1121 1122
        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

1123
      it 'does not update name to existing name' do
1124 1125
        project_param = { name: project3.name }
        put api("/projects/#{project.id}", user), project_param
1126
        expect(response).to have_http_status(400)
1127
        expect(json_response['message']['name']).to eq(['has already been taken'])
1128 1129
      end

1130 1131 1132 1133 1134 1135 1136 1137 1138
      it 'updates request_access_enabled' do
        project_param = { request_access_enabled: false }

        put api("/projects/#{project.id}", user), project_param

        expect(response).to have_http_status(200)
        expect(json_response['request_access_enabled']).to eq(false)
      end

1139
      it 'updates path & name to existing path & name in different namespace' do
1140 1141
        project_param = { path: project4.path, name: project4.name }
        put api("/projects/#{project3.id}", user), project_param
1142
        expect(response).to have_http_status(200)
1143
        project_param.each_pair do |k, v|
1144
          expect(json_response[k.to_s]).to eq(v)
1145 1146 1147 1148 1149
        end
      end
    end

    context 'when authenticated as project master' do
1150
      it 'updates path' do
1151 1152
        project_param = { path: 'bar' }
        put api("/projects/#{project3.id}", user4), project_param
1153
        expect(response).to have_http_status(200)
1154
        project_param.each_pair do |k, v|
1155
          expect(json_response[k.to_s]).to eq(v)
1156 1157 1158
        end
      end

1159
      it 'updates other attributes' do
1160 1161 1162 1163 1164 1165 1166
        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
1167
        expect(response).to have_http_status(200)
1168
        project_param.each_pair do |k, v|
1169
          expect(json_response[k.to_s]).to eq(v)
1170 1171 1172
        end
      end

1173
      it 'does not update path to existing path' do
1174 1175
        project_param = { path: project.path }
        put api("/projects/#{project3.id}", user4), project_param
1176
        expect(response).to have_http_status(400)
1177
        expect(json_response['message']['path']).to eq(['has already been taken'])
1178 1179
      end

1180
      it 'does not update name' do
1181 1182
        project_param = { name: 'bar' }
        put api("/projects/#{project3.id}", user4), project_param
1183
        expect(response).to have_http_status(403)
1184 1185
      end

1186
      it 'does not update visibility_level' do
1187 1188
        project_param = { visibility_level: 20 }
        put api("/projects/#{project3.id}", user4), project_param
1189
        expect(response).to have_http_status(403)
1190 1191 1192 1193
      end
    end

    context 'when authenticated as project developer' do
1194
      it 'does not update other attributes' do
1195 1196 1197 1198 1199
        project_param = { path: 'bar',
                          issues_enabled: true,
                          wiki_enabled: true,
                          snippets_enabled: true,
                          merge_requests_enabled: true,
1200 1201
                          description: 'new description',
                          request_access_enabled: true }
1202
        put api("/projects/#{project.id}", user3), project_param
1203
        expect(response).to have_http_status(403)
1204 1205 1206 1207
      end
    end
  end

1208
  describe 'POST /projects/:id/archive' do
1209 1210
    context 'on an unarchived project' do
      it 'archives the project' do
1211
        post api("/projects/#{project.id}/archive", user)
1212

1213
        expect(response).to have_http_status(201)
1214 1215 1216 1217 1218 1219 1220 1221 1222 1223
        expect(json_response['archived']).to be_truthy
      end
    end

    context 'on an archived project' do
      before do
        project.archive!
      end

      it 'remains archived' do
1224
        post api("/projects/#{project.id}/archive", user)
1225

1226
        expect(response).to have_http_status(201)
1227 1228
        expect(json_response['archived']).to be_truthy
      end
1229
    end
1230

1231 1232 1233 1234
    context 'user without archiving rights to the project' do
      before do
        project.team << [user3, :developer]
      end
1235

1236 1237 1238
      it 'rejects the action' do
        post api("/projects/#{project.id}/archive", user3)

1239
        expect(response).to have_http_status(403)
1240 1241 1242 1243
      end
    end
  end

1244
  describe 'POST /projects/:id/unarchive' do
1245 1246
    context 'on an unarchived project' do
      it 'remains unarchived' do
1247
        post api("/projects/#{project.id}/unarchive", user)
1248

1249
        expect(response).to have_http_status(201)
1250 1251 1252 1253 1254 1255 1256 1257 1258
        expect(json_response['archived']).to be_falsey
      end
    end

    context 'on an archived project' do
      before do
        project.archive!
      end

1259 1260
      it 'unarchives the project' do
        post api("/projects/#{project.id}/unarchive", user)
1261

1262
        expect(response).to have_http_status(201)
1263 1264
        expect(json_response['archived']).to be_falsey
      end
1265
    end
1266

1267 1268 1269 1270
    context 'user without archiving rights to the project' do
      before do
        project.team << [user3, :developer]
      end
1271

1272 1273 1274
      it 'rejects the action' do
        post api("/projects/#{project.id}/unarchive", user3)

1275
        expect(response).to have_http_status(403)
1276 1277 1278 1279
      end
    end
  end

1280 1281 1282
  describe 'POST /projects/:id/star' do
    context 'on an unstarred project' do
      it 'stars the project' do
1283
        expect { post api("/projects/#{project.id}/star", user) }.to change { project.reload.star_count }.by(1)
1284

1285
        expect(response).to have_http_status(201)
1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
        expect(json_response['star_count']).to eq(1)
      end
    end

    context 'on a starred project' do
      before do
        user.toggle_star(project)
        project.reload
      end

      it 'does not modify the star count' do
1297
        expect { post api("/projects/#{project.id}/star", user) }.not_to change { project.reload.star_count }
1298

1299
        expect(response).to have_http_status(304)
1300 1301 1302 1303
      end
    end
  end

1304
  describe 'DELETE /projects/:id/star' do
1305 1306 1307 1308 1309 1310 1311
    context 'on a starred project' do
      before do
        user.toggle_star(project)
        project.reload
      end

      it 'unstars the project' do
1312
        expect { delete api("/projects/#{project.id}/star", user) }.to change { project.reload.star_count }.by(-1)
1313

1314
        expect(response).to have_http_status(200)
1315 1316 1317 1318 1319 1320
        expect(json_response['star_count']).to eq(0)
      end
    end

    context 'on an unstarred project' do
      it 'does not modify the star count' do
1321
        expect { delete api("/projects/#{project.id}/star", user) }.not_to change { project.reload.star_count }
1322

1323
        expect(response).to have_http_status(304)
1324 1325 1326 1327
      end
    end
  end

1328 1329
  describe 'DELETE /projects/:id' do
    context 'when authenticated as user' do
1330
      it 'removes project' do
1331
        delete api("/projects/#{project.id}", user)
1332
        expect(response).to have_http_status(200)
1333 1334
      end

1335
      it 'does not remove a project if not an owner' do
1336 1337 1338
        user3 = create(:user)
        project.team << [user3, :developer]
        delete api("/projects/#{project.id}", user3)
1339
        expect(response).to have_http_status(403)
1340 1341
      end

1342
      it 'does not remove a non existing project' do
1343
        delete api('/projects/1328', user)
1344
        expect(response).to have_http_status(404)
1345 1346
      end

1347
      it 'does not remove a project not attached to user' do
1348
        delete api("/projects/#{project.id}", user2)
1349
        expect(response).to have_http_status(404)
1350 1351 1352
      end
    end

1353
    context 'when authenticated as admin' do
1354
      it 'removes any existing project' do
1355
        delete api("/projects/#{project.id}", admin)
1356
        expect(response).to have_http_status(200)
1357 1358
      end

1359
      it 'does not remove a non existing project' do
1360
        delete api('/projects/1328', admin)
1361
        expect(response).to have_http_status(404)
1362 1363 1364
      end
    end
  end
Nihad Abbasov committed
1365
end