BigW Consortium Gitlab

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

3
describe API::Groups, api: true  do
4
  include ApiHelpers
5
  include UploadHelpers
6

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

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

  describe "GET /groups" do
    context "when unauthenticated" do
24
      it "returns authentication error" do
25
        get api("/groups")
26

27
        expect(response).to have_http_status(401)
28 29 30 31
      end
    end

    context "when authenticated as user" do
32
      it "normal user: returns an array of groups of user1" do
33
        get api("/groups", user1)
34

35
        expect(response).to have_http_status(200)
36
        expect(response).to include_pagination_headers
37 38
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(1)
39 40
        expect(json_response)
          .to satisfy_one { |group| group['name'] == group1.name }
41
      end
42 43 44 45 46

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

        expect(response).to have_http_status(200)
47
        expect(response).to include_pagination_headers
48 49 50
        expect(json_response).to be_an Array
        expect(json_response.first).not_to include 'statistics'
      end
51
    end
52

53
    context "when authenticated as admin" do
54
      it "admin: returns an array of all groups" do
55
        get api("/groups", admin)
56

57
        expect(response).to have_http_status(200)
58
        expect(response).to include_pagination_headers
59 60
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(2)
61
      end
62 63 64 65 66

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

        expect(response).to have_http_status(200)
67
        expect(response).to include_pagination_headers
68 69 70 71 72 73 74 75 76 77
        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,
          build_artifacts_size: 345,
78
        }.stringify_keys
79
        exposed_attributes = attributes.dup
Toon Claes committed
80
        exposed_attributes['job_artifacts_size'] = exposed_attributes.delete('build_artifacts_size')
81 82 83 84 85 86

        project1.statistics.update!(attributes)

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

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

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

        expect(response).to have_http_status(200)
99
        expect(response).to include_pagination_headers
barthc committed
100 101 102 103
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(1)
      end
    end
104 105

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

108 109
      it "returns all groups you have access to" do
        public_group = create :group, :public
110

111 112 113
        get api("/groups", user1), all_available: true

        expect(response).to have_http_status(200)
114
        expect(response).to include_pagination_headers
115
        expect(json_response).to be_an Array
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
        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)

        expect(response).to have_http_status(200)
132
        expect(response).to include_pagination_headers
133 134 135 136 137 138 139 140
        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"

        expect(response).to have_http_status(200)
141
        expect(response).to include_pagination_headers
142 143 144 145 146 147 148 149
        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"

        expect(response).to have_http_status(200)
150
        expect(response).to include_pagination_headers
151 152
        expect(json_response).to be_an Array
        expect(response_groups).to eq([group1.name, group3.name])
153 154
      end
    end
155

156
    context 'when using owned in the request' do
157
      it 'returns an array of groups the user owns' do
158
        get api('/groups', user2), owned: true
159

160
        expect(response).to have_http_status(200)
161
        expect(response).to include_pagination_headers
162 163 164 165 166 167
        expect(json_response).to be_an Array
        expect(json_response.first['name']).to eq(group2.name)
      end
    end
  end

168 169
  describe "GET /groups/:id" do
    context "when authenticated as user" do
170
      it "returns one of user1's groups" do
171
        project = create(:empty_project, namespace: group2, path: 'Foo')
172 173
        create(:project_group_link, project: project, group: group1)

174
        get api("/groups/#{group1.id}", user1)
175

176
        expect(response).to have_http_status(200)
177 178 179 180
        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)
181
        expect(json_response['visibility']).to eq(Gitlab::VisibilityLevel.string_level(group1.visibility_level))
182 183
        expect(json_response['avatar_url']).to eq(group1.avatar_url)
        expect(json_response['web_url']).to eq(group1.web_url)
184 185 186
        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)
187
        expect(json_response['parent_id']).to eq(group1.parent_id)
188 189 190 191 192
        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)
193
      end
194

195
      it "does not return a non existing group" do
196
        get api("/groups/1328", user1)
197

198
        expect(response).to have_http_status(404)
199
      end
200

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

204
        expect(response).to have_http_status(404)
205 206
      end
    end
207

208
    context "when authenticated as admin" do
209
      it "returns any existing group" do
210
        get api("/groups/#{group2.id}", admin)
211

212
        expect(response).to have_http_status(200)
213
        expect(json_response['name']).to eq(group2.name)
214
      end
215

216
      it "does not return a non existing group" do
217
        get api("/groups/1328", admin)
218

219
        expect(response).to have_http_status(404)
220 221
      end
    end
222 223

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

227
        expect(response).to have_http_status(200)
228
        expect(json_response['name']).to eq(group1.name)
229 230
      end

231
      it 'does not return a non existing group' do
232
        get api('/groups/unknown', admin)
233

234
        expect(response).to have_http_status(404)
235 236
      end

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

240
        expect(response).to have_http_status(404)
241 242
      end
    end
243
  end
244

245 246 247
  describe 'PUT /groups/:id' do
    let(:new_group_name) { 'New Group'}

248
    context 'when authenticated as the group owner' do
249
      it 'updates the group' do
250
        put api("/groups/#{group1.id}", user1), name: new_group_name, request_access_enabled: true
251

252
        expect(response).to have_http_status(200)
253
        expect(json_response['name']).to eq(new_group_name)
254
        expect(json_response['request_access_enabled']).to eq(true)
255 256 257
      end

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

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

264
    context 'when authenticated as the admin' do
265 266 267
      it 'updates the group' do
        put api("/groups/#{group1.id}", admin), name: new_group_name

268
        expect(response).to have_http_status(200)
269 270 271 272
        expect(json_response['name']).to eq(new_group_name)
      end
    end

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

277
        expect(response).to have_http_status(403)
278 279
      end
    end
280 281

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

285
        expect(response).to have_http_status(404)
286 287
      end
    end
288 289
  end

290 291
  describe "GET /groups/:id/projects" do
    context "when authenticated as user" do
292
      it "returns the group's projects" do
293
        get api("/groups/#{group1.id}/projects", user1)
294

295
        expect(response).to have_http_status(200)
296
        expect(response).to include_pagination_headers
297
        expect(json_response.length).to eq(2)
298
        project_names = json_response.map { |proj| proj['name'] }
299
        expect(project_names).to match_array([project1.name, project3.name])
300
        expect(json_response.first['visibility']).to be_present
301 302 303 304 305 306
      end

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

        expect(response).to have_http_status(200)
307
        expect(response).to include_pagination_headers
308
        expect(json_response.length).to eq(2)
309
        project_names = json_response.map { |proj| proj['name'] }
310
        expect(project_names).to match_array([project1.name, project3.name])
311
        expect(json_response.first['visibility']).not_to be_present
312 313
      end

314
      it 'filters the groups projects' do
315
        public_project = create(:empty_project, :public, path: 'test1', group: group1)
316 317 318 319

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

        expect(response).to have_http_status(200)
320
        expect(response).to include_pagination_headers
321 322
        expect(json_response).to be_an(Array)
        expect(json_response.length).to eq(1)
323
        expect(json_response.first['name']).to eq(public_project.name)
324 325
      end

326
      it "does not return a non existing group" do
327
        get api("/groups/1328/projects", user1)
328

329
        expect(response).to have_http_status(404)
330 331
      end

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

335
        expect(response).to have_http_status(404)
336
      end
337

338
      it "only returns projects to which user has access" do
339 340 341 342
        project3.team << [user3, :developer]

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

343
        expect(response).to have_http_status(200)
344
        expect(response).to include_pagination_headers
345 346 347
        expect(json_response.length).to eq(1)
        expect(json_response.first['name']).to eq(project3.name)
      end
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367

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

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

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

        expect(response).to have_http_status(200)
        expect(json_response.length).to eq(1)
        expect(json_response.first['name']).to eq(project1.name)
      end
368 369 370
    end

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

374
        expect(response).to have_http_status(200)
375
        expect(response).to include_pagination_headers
376 377 378 379
        expect(json_response.length).to eq(1)
        expect(json_response.first['name']).to eq(project2.name)
      end

380
      it "does not return a non existing group" do
381
        get api("/groups/1328/projects", admin)
382

383
        expect(response).to have_http_status(404)
384 385 386 387
      end
    end

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

391
        expect(response).to have_http_status(200)
392
        expect(response).to include_pagination_headers
393
        project_names = json_response.map { |proj| proj['name'] }
394
        expect(project_names).to match_array([project1.name, project3.name])
395 396
      end

397
      it 'does not return a non existing group' do
398
        get api('/groups/unknown/projects', admin)
399

400
        expect(response).to have_http_status(404)
401 402
      end

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

406
        expect(response).to have_http_status(404)
407 408 409 410
      end
    end
  end

411
  describe "POST /groups" do
412
    context "when authenticated as user without group permissions" do
413
      it "does not create group" do
414
        post api("/groups", user1), attributes_for(:group)
415

416
        expect(response).to have_http_status(403)
417 418
      end
    end
419

420
    context "when authenticated as user with group permissions" do
421
      it "creates group" do
422 423 424
        group = attributes_for(:group, { request_access_enabled: false })

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

426
        expect(response).to have_http_status(201)
427 428 429 430

        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])
431
      end
432

433 434 435 436 437 438 439 440 441 442 443 444 445
      it "creates a nested group" do
        parent = create(:group)
        parent.add_owner(user3)
        group = attributes_for(:group, { parent_id: parent.id })

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

        expect(response).to have_http_status(201)

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

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

449
        expect(response).to have_http_status(400)
450
        expect(response.message).to eq("Bad Request")
451
      end
452

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

456
        expect(response).to have_http_status(400)
457 458
      end

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

462
        expect(response).to have_http_status(400)
463
      end
464 465
    end
  end
Angus MacArthur committed
466

467 468
  describe "DELETE /groups/:id" do
    context "when authenticated as user" do
469
      it "removes group" do
470
        delete api("/groups/#{group1.id}", user1)
471

472
        expect(response).to have_http_status(204)
473 474
      end

475
      it "does not remove a group if not an owner" do
476
        user4 = create(:user)
477
        group1.add_master(user4)
478

479
        delete api("/groups/#{group1.id}", user3)
480

481
        expect(response).to have_http_status(403)
482 483
      end

484
      it "does not remove a non existing group" do
485
        delete api("/groups/1328", user1)
486

487
        expect(response).to have_http_status(404)
488 489
      end

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

493
        expect(response).to have_http_status(404)
494 495 496 497
      end
    end

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

501
        expect(response).to have_http_status(204)
502 503
      end

504
      it "does not remove a non existing group" do
505
        delete api("/groups/1328", admin)
506

507
        expect(response).to have_http_status(404)
508 509 510 511
      end
    end
  end

Angus MacArthur committed
512
  describe "POST /groups/:id/projects/:project_id" do
513
    let(:project) { create(:empty_project) }
514
    let(:project_path) { project.full_path.gsub('/', '%2F') }
515

Angus MacArthur committed
516
    before(:each) do
517 518
      allow_any_instance_of(Projects::TransferService).
        to receive(:execute).and_return(true)
Angus MacArthur committed
519 520 521
    end

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

525
        expect(response).to have_http_status(403)
Angus MacArthur committed
526 527 528 529
      end
    end

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

533
        expect(response).to have_http_status(201)
Angus MacArthur committed
534
      end
535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570

      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)

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

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

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

            expect(response).to have_http_status(404)
          end
        end
      end
Angus MacArthur committed
571 572
    end
  end
573
end