BigW Consortium Gitlab

groups_spec.rb 20.5 KB
Newer Older
1 2
require 'spec_helper'

3
describe API::Groups do
4
  include UploadHelpers
5

6
  let(:user1) { create(:user, can_create_group: false) }
Izaak Alpert committed
7
  let(:user2) { create(:user) }
8
  let(:user3) { create(:user) }
9
  let(:admin) { create(:admin) }
10
  let!(:group1) { create(:group, avatar: File.open(uploaded_image_temp_path)) }
Douwe Maan committed
11
  let!(:group2) { create(:group, :private) }
12 13 14
  let!(:project1) { create(:project, namespace: group1) }
  let!(:project2) { create(:project, namespace: group2) }
  let!(:project3) { create(:project, namespace: group1, path: 'test', visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
15 16 17 18 19

  before do
    group1.add_owner(user1)
    group2.add_owner(user2)
  end
20 21 22

  describe "GET /groups" do
    context "when unauthenticated" do
23
      it "returns public groups" do
24
        get api("/groups")
25

26
        expect(response).to have_gitlab_http_status(200)
27 28 29 30 31
        expect(response).to include_pagination_headers
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(1)
        expect(json_response)
          .to satisfy_one { |group| group['name'] == group1.name }
32 33 34 35
      end
    end

    context "when authenticated as user" do
36
      it "normal user: returns an array of groups of user1" do
37
        get api("/groups", user1)
38

39
        expect(response).to have_gitlab_http_status(200)
40
        expect(response).to include_pagination_headers
41 42
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(1)
43 44
        expect(json_response)
          .to satisfy_one { |group| group['name'] == group1.name }
45
      end
46 47 48 49

      it "does not include statistics" do
        get api("/groups", user1), statistics: true

50
        expect(response).to have_gitlab_http_status(200)
51
        expect(response).to include_pagination_headers
52 53 54
        expect(json_response).to be_an Array
        expect(json_response.first).not_to include 'statistics'
      end
55
    end
56

57
    context "when authenticated as admin" do
58
      it "admin: returns an array of all groups" do
59
        get api("/groups", admin)
60

61
        expect(response).to have_gitlab_http_status(200)
62
        expect(response).to include_pagination_headers
63 64
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(2)
65
      end
66 67 68 69

      it "does not include statistics by default" do
        get api("/groups", admin)

70
        expect(response).to have_gitlab_http_status(200)
71
        expect(response).to include_pagination_headers
72 73 74 75 76 77 78 79 80
        expect(json_response).to be_an Array
        expect(json_response.first).not_to include('statistics')
      end

      it "includes statistics if requested" do
        attributes = {
          storage_size: 702,
          repository_size: 123,
          lfs_objects_size: 234,
81
          build_artifacts_size: 345
82
        }.stringify_keys
83
        exposed_attributes = attributes.dup
Toon Claes committed
84
        exposed_attributes['job_artifacts_size'] = exposed_attributes.delete('build_artifacts_size')
85 86 87 88 89

        project1.statistics.update!(attributes)

        get api("/groups", admin), statistics: true

90
        expect(response).to have_gitlab_http_status(200)
91
        expect(response).to include_pagination_headers
92
        expect(json_response).to be_an Array
93
        expect(json_response)
Toon Claes committed
94
          .to satisfy_one { |group| group['statistics'] == exposed_attributes }
95
      end
96
    end
barthc committed
97 98 99 100 101

    context "when using skip_groups in request" do
      it "returns all groups excluding skipped groups" do
        get api("/groups", admin), skip_groups: [group2.id]

102
        expect(response).to have_gitlab_http_status(200)
103
        expect(response).to include_pagination_headers
barthc committed
104 105 106 107
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(1)
      end
    end
108 109

    context "when using all_available in request" do
110 111
      let(:response_groups) { json_response.map { |group| group['name'] } }

112 113
      it "returns all groups you have access to" do
        public_group = create :group, :public
114

115 116
        get api("/groups", user1), all_available: true

117
        expect(response).to have_gitlab_http_status(200)
118
        expect(response).to include_pagination_headers
119
        expect(json_response).to be_an Array
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
        expect(response_groups).to contain_exactly(public_group.name, group1.name)
      end
    end

    context "when using sorting" do
      let(:group3) { create(:group, name: "a#{group1.name}", path: "z#{group1.path}") }
      let(:response_groups) { json_response.map { |group| group['name'] } }

      before do
        group3.add_owner(user1)
      end

      it "sorts by name ascending by default" do
        get api("/groups", user1)

135
        expect(response).to have_gitlab_http_status(200)
136
        expect(response).to include_pagination_headers
137 138 139 140 141 142 143
        expect(json_response).to be_an Array
        expect(response_groups).to eq([group3.name, group1.name])
      end

      it "sorts in descending order when passed" do
        get api("/groups", user1), sort: "desc"

144
        expect(response).to have_gitlab_http_status(200)
145
        expect(response).to include_pagination_headers
146 147 148 149 150 151 152
        expect(json_response).to be_an Array
        expect(response_groups).to eq([group1.name, group3.name])
      end

      it "sorts by the order_by param" do
        get api("/groups", user1), order_by: "path"

153
        expect(response).to have_gitlab_http_status(200)
154
        expect(response).to include_pagination_headers
155 156
        expect(json_response).to be_an Array
        expect(response_groups).to eq([group1.name, group3.name])
157 158
      end
    end
159

160
    context 'when using owned in the request' do
161
      it 'returns an array of groups the user owns' do
162 163
        group1.add_master(user2)

164
        get api('/groups', user2), owned: true
165

166
        expect(response).to have_gitlab_http_status(200)
167
        expect(response).to include_pagination_headers
168
        expect(json_response).to be_an Array
169
        expect(json_response.length).to eq(1)
170 171 172 173 174
        expect(json_response.first['name']).to eq(group2.name)
      end
    end
  end

175
  describe "GET /groups/:id" do
176 177 178
    context 'when unauthenticated' do
      it 'returns 404 for a private group' do
        get api("/groups/#{group2.id}")
179
        expect(response).to have_gitlab_http_status(404)
180 181 182 183
      end

      it 'returns 200 for a public group' do
        get api("/groups/#{group1.id}")
184
        expect(response).to have_gitlab_http_status(200)
185 186 187
      end
    end

188
    context "when authenticated as user" do
189
      it "returns one of user1's groups" do
190
        project = create(:project, namespace: group2, path: 'Foo')
191 192
        create(:project_group_link, project: project, group: group1)

193
        get api("/groups/#{group1.id}", user1)
194

195
        expect(response).to have_gitlab_http_status(200)
196 197 198 199
        expect(json_response['id']).to eq(group1.id)
        expect(json_response['name']).to eq(group1.name)
        expect(json_response['path']).to eq(group1.path)
        expect(json_response['description']).to eq(group1.description)
200
        expect(json_response['visibility']).to eq(Gitlab::VisibilityLevel.string_level(group1.visibility_level))
201
        expect(json_response['avatar_url']).to eq(group1.avatar_url(only_path: false))
202
        expect(json_response['web_url']).to eq(group1.web_url)
203 204 205
        expect(json_response['request_access_enabled']).to eq(group1.request_access_enabled)
        expect(json_response['full_name']).to eq(group1.full_name)
        expect(json_response['full_path']).to eq(group1.full_path)
206
        expect(json_response['parent_id']).to eq(group1.parent_id)
207 208 209 210 211
        expect(json_response['projects']).to be_an Array
        expect(json_response['projects'].length).to eq(2)
        expect(json_response['shared_projects']).to be_an Array
        expect(json_response['shared_projects'].length).to eq(1)
        expect(json_response['shared_projects'][0]['id']).to eq(project.id)
212
      end
213

214
      it "does not return a non existing group" do
215
        get api("/groups/1328", user1)
216

217
        expect(response).to have_gitlab_http_status(404)
218
      end
219

220
      it "does not return a group not attached to user1" do
221
        get api("/groups/#{group2.id}", user1)
222

223
        expect(response).to have_gitlab_http_status(404)
224 225
      end
    end
226

227
    context "when authenticated as admin" do
228
      it "returns any existing group" do
229
        get api("/groups/#{group2.id}", admin)
230

231
        expect(response).to have_gitlab_http_status(200)
232
        expect(json_response['name']).to eq(group2.name)
233
      end
234

235
      it "does not return a non existing group" do
236
        get api("/groups/1328", admin)
237

238
        expect(response).to have_gitlab_http_status(404)
239 240
      end
    end
241 242

    context 'when using group path in URL' do
243
      it 'returns any existing group' do
244
        get api("/groups/#{group1.path}", admin)
245

246
        expect(response).to have_gitlab_http_status(200)
247
        expect(json_response['name']).to eq(group1.name)
248 249
      end

250
      it 'does not return a non existing group' do
251
        get api('/groups/unknown', admin)
252

253
        expect(response).to have_gitlab_http_status(404)
254 255
      end

256
      it 'does not return a group not attached to user1' do
257
        get api("/groups/#{group2.path}", user1)
258

259
        expect(response).to have_gitlab_http_status(404)
260 261
      end
    end
262
  end
263

264 265 266
  describe 'PUT /groups/:id' do
    let(:new_group_name) { 'New Group'}

267
    context 'when authenticated as the group owner' do
268
      it 'updates the group' do
269
        put api("/groups/#{group1.id}", user1), name: new_group_name, request_access_enabled: true
270

271
        expect(response).to have_gitlab_http_status(200)
272
        expect(json_response['name']).to eq(new_group_name)
273
        expect(json_response['request_access_enabled']).to eq(true)
274 275 276
      end

      it 'returns 404 for a non existing group' do
277
        put api('/groups/1328', user1), name: new_group_name
278

279
        expect(response).to have_gitlab_http_status(404)
280 281 282
      end
    end

283
    context 'when authenticated as the admin' do
284 285 286
      it 'updates the group' do
        put api("/groups/#{group1.id}", admin), name: new_group_name

287
        expect(response).to have_gitlab_http_status(200)
288 289 290 291
        expect(json_response['name']).to eq(new_group_name)
      end
    end

292 293
    context 'when authenticated as an user that can see the group' do
      it 'does not updates the group' do
294 295
        put api("/groups/#{group1.id}", user2), name: new_group_name

296
        expect(response).to have_gitlab_http_status(403)
297 298
      end
    end
299 300

    context 'when authenticated as an user that cannot see the group' do
301
      it 'returns 404 when trying to update the group' do
302 303
        put api("/groups/#{group2.id}", user1), name: new_group_name

304
        expect(response).to have_gitlab_http_status(404)
305 306
      end
    end
307 308
  end

309 310
  describe "GET /groups/:id/projects" do
    context "when authenticated as user" do
311
      it "returns the group's projects" do
312
        get api("/groups/#{group1.id}/projects", user1)
313

314
        expect(response).to have_gitlab_http_status(200)
315
        expect(response).to include_pagination_headers
316
        expect(json_response.length).to eq(2)
317
        project_names = json_response.map { |proj| proj['name'] }
318
        expect(project_names).to match_array([project1.name, project3.name])
319
        expect(json_response.first['visibility']).to be_present
320 321 322 323 324
      end

      it "returns the group's projects with simple representation" do
        get api("/groups/#{group1.id}/projects", user1), simple: true

325
        expect(response).to have_gitlab_http_status(200)
326
        expect(response).to include_pagination_headers
327
        expect(json_response.length).to eq(2)
328
        project_names = json_response.map { |proj| proj['name'] }
329
        expect(project_names).to match_array([project1.name, project3.name])
330
        expect(json_response.first['visibility']).not_to be_present
331 332
      end

333
      it 'filters the groups projects' do
334
        public_project = create(:project, :public, path: 'test1', group: group1)
335 336 337

        get api("/groups/#{group1.id}/projects", user1), visibility: 'public'

338
        expect(response).to have_gitlab_http_status(200)
339
        expect(response).to include_pagination_headers
340 341
        expect(json_response).to be_an(Array)
        expect(json_response.length).to eq(1)
342
        expect(json_response.first['name']).to eq(public_project.name)
343 344
      end

345
      it "does not return a non existing group" do
346
        get api("/groups/1328/projects", user1)
347

348
        expect(response).to have_gitlab_http_status(404)
349 350
      end

351
      it "does not return a group not attached to user1" do
352
        get api("/groups/#{group2.id}/projects", user1)
353

354
        expect(response).to have_gitlab_http_status(404)
355
      end
356

357
      it "only returns projects to which user has access" do
358 359 360 361
        project3.team << [user3, :developer]

        get api("/groups/#{group1.id}/projects", user3)

362
        expect(response).to have_gitlab_http_status(200)
363
        expect(response).to include_pagination_headers
364 365 366
        expect(json_response.length).to eq(1)
        expect(json_response.first['name']).to eq(project3.name)
      end
367 368 369 370 371 372

      it 'only returns the projects owned by user' do
        project2.group.add_owner(user3)

        get api("/groups/#{project2.group.id}/projects", user3), owned: true

373
        expect(response).to have_gitlab_http_status(200)
374 375 376 377 378 379 380 381 382
        expect(json_response.length).to eq(1)
        expect(json_response.first['name']).to eq(project2.name)
      end

      it 'only returns the projects starred by user' do
        user1.starred_projects = [project1]

        get api("/groups/#{group1.id}/projects", user1), starred: true

383
        expect(response).to have_gitlab_http_status(200)
384 385 386
        expect(json_response.length).to eq(1)
        expect(json_response.first['name']).to eq(project1.name)
      end
387 388 389
    end

    context "when authenticated as admin" do
390
      it "returns any existing group" do
391
        get api("/groups/#{group2.id}/projects", admin)
392

393
        expect(response).to have_gitlab_http_status(200)
394
        expect(response).to include_pagination_headers
395 396 397 398
        expect(json_response.length).to eq(1)
        expect(json_response.first['name']).to eq(project2.name)
      end

399
      it "does not return a non existing group" do
400
        get api("/groups/1328/projects", admin)
401

402
        expect(response).to have_gitlab_http_status(404)
403 404 405 406
      end
    end

    context 'when using group path in URL' do
407
      it 'returns any existing group' do
408
        get api("/groups/#{group1.path}/projects", admin)
409

410
        expect(response).to have_gitlab_http_status(200)
411
        expect(response).to include_pagination_headers
412
        project_names = json_response.map { |proj| proj['name'] }
413
        expect(project_names).to match_array([project1.name, project3.name])
414 415
      end

416
      it 'does not return a non existing group' do
417
        get api('/groups/unknown/projects', admin)
418

419
        expect(response).to have_gitlab_http_status(404)
420 421
      end

422
      it 'does not return a group not attached to user1' do
423
        get api("/groups/#{group2.path}/projects", user1)
424

425
        expect(response).to have_gitlab_http_status(404)
426 427 428 429
      end
    end
  end

430
  describe "POST /groups" do
431
    context "when authenticated as user without group permissions" do
432
      it "does not create group" do
433
        post api("/groups", user1), attributes_for(:group)
434

435
        expect(response).to have_gitlab_http_status(403)
436
      end
437 438 439 440 441 442 443 444 445

      context 'as owner', :nested_groups do
        before do
          group2.add_owner(user1)
        end

        it 'can create subgroups' do
          post api("/groups", user1), parent_id: group2.id, name: 'foo', path: 'foo'

446
          expect(response).to have_gitlab_http_status(201)
447 448 449 450 451 452 453 454 455 456 457
        end
      end

      context 'as master', :nested_groups do
        before do
          group2.add_master(user1)
        end

        it 'cannot create subgroups' do
          post api("/groups", user1), parent_id: group2.id, name: 'foo', path: 'foo'

458
          expect(response).to have_gitlab_http_status(403)
459 460
        end
      end
461
    end
462

463
    context "when authenticated as user with group permissions" do
464
      it "creates group" do
465 466 467
        group = attributes_for(:group, { request_access_enabled: false })

        post api("/groups", user3), group
468

469
        expect(response).to have_gitlab_http_status(201)
470 471 472 473

        expect(json_response["name"]).to eq(group[:name])
        expect(json_response["path"]).to eq(group[:path])
        expect(json_response["request_access_enabled"]).to eq(group[:request_access_enabled])
474
        expect(json_response["visibility"]).to eq(Gitlab::VisibilityLevel.string_level(Gitlab::CurrentSettings.current_application_settings.default_group_visibility))
475
      end
476

477
      it "creates a nested group", :nested_groups do
478 479 480 481 482 483
        parent = create(:group)
        parent.add_owner(user3)
        group = attributes_for(:group, { parent_id: parent.id })

        post api("/groups", user3), group

484
        expect(response).to have_gitlab_http_status(201)
485 486 487 488 489

        expect(json_response["full_path"]).to eq("#{parent.path}/#{group[:path]}")
        expect(json_response["parent_id"]).to eq(parent.id)
      end

490
      it "does not create group, duplicate" do
491
        post api("/groups", user3), { name: 'Duplicate Test', path: group2.path }
492

493
        expect(response).to have_gitlab_http_status(400)
494
        expect(response.message).to eq("Bad Request")
495
      end
496

497
      it "returns 400 bad request error if name not given" do
498
        post api("/groups", user3), { path: group2.path }
499

500
        expect(response).to have_gitlab_http_status(400)
501 502
      end

503
      it "returns 400 bad request error if path not given" do
504
        post api("/groups", user3), { name: 'test' }
505

506
        expect(response).to have_gitlab_http_status(400)
507
      end
508 509
    end
  end
Angus MacArthur committed
510

511 512
  describe "DELETE /groups/:id" do
    context "when authenticated as user" do
513
      it "removes group" do
514
        delete api("/groups/#{group1.id}", user1)
515

516
        expect(response).to have_gitlab_http_status(204)
517 518
      end

519 520 521 522
      it_behaves_like '412 response' do
        let(:request) { api("/groups/#{group1.id}", user1) }
      end

523
      it "does not remove a group if not an owner" do
524
        user4 = create(:user)
525
        group1.add_master(user4)
526

527
        delete api("/groups/#{group1.id}", user3)
528

529
        expect(response).to have_gitlab_http_status(403)
530 531
      end

532
      it "does not remove a non existing group" do
533
        delete api("/groups/1328", user1)
534

535
        expect(response).to have_gitlab_http_status(404)
536 537
      end

538
      it "does not remove a group not attached to user1" do
539
        delete api("/groups/#{group2.id}", user1)
540

541
        expect(response).to have_gitlab_http_status(404)
542 543 544 545
      end
    end

    context "when authenticated as admin" do
546
      it "removes any existing group" do
547
        delete api("/groups/#{group2.id}", admin)
548

549
        expect(response).to have_gitlab_http_status(204)
550 551
      end

552
      it "does not remove a non existing group" do
553
        delete api("/groups/1328", admin)
554

555
        expect(response).to have_gitlab_http_status(404)
556 557 558 559
      end
    end
  end

Angus MacArthur committed
560
  describe "POST /groups/:id/projects/:project_id" do
561
    let(:project) { create(:project) }
562
    let(:project_path) { CGI.escape(project.full_path) }
563

564
    before do
565 566
      allow_any_instance_of(Projects::TransferService)
        .to receive(:execute).and_return(true)
Angus MacArthur committed
567 568 569
    end

    context "when authenticated as user" do
570
      it "does not transfer project to group" do
Angus MacArthur committed
571
        post api("/groups/#{group1.id}/projects/#{project.id}", user2)
572

573
        expect(response).to have_gitlab_http_status(403)
Angus MacArthur committed
574 575 576 577
      end
    end

    context "when authenticated as admin" do
578
      it "transfers project to group" do
Angus MacArthur committed
579
        post api("/groups/#{group1.id}/projects/#{project.id}", admin)
580

581
        expect(response).to have_gitlab_http_status(201)
Angus MacArthur committed
582
      end
583 584 585 586 587 588

      context 'when using project path in URL' do
        context 'with a valid project path' do
          it "transfers project to group" do
            post api("/groups/#{group1.id}/projects/#{project_path}", admin)

589
            expect(response).to have_gitlab_http_status(201)
590 591 592 593 594 595 596
          end
        end

        context 'with a non-existent project path' do
          it "does not transfer project to group" do
            post api("/groups/#{group1.id}/projects/nogroup%2Fnoproject", admin)

597
            expect(response).to have_gitlab_http_status(404)
598 599 600 601 602 603 604 605 606
          end
        end
      end

      context 'when using a group path in URL' do
        context 'with a valid group path' do
          it "transfers project to group" do
            post api("/groups/#{group1.path}/projects/#{project_path}", admin)

607
            expect(response).to have_gitlab_http_status(201)
608 609 610 611 612 613 614
          end
        end

        context 'with a non-existent group path' do
          it "does not transfer project to group" do
            post api("/groups/noexist/projects/#{project_path}", admin)

615
            expect(response).to have_gitlab_http_status(404)
616 617 618
          end
        end
      end
Angus MacArthur committed
619 620
    end
  end
621
end