BigW Consortium Gitlab

groups_spec.rb 18.6 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(: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) }
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 authentication error" do
24
        get api("/groups")
25

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

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

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

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

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

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

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

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

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

        project1.statistics.update!(attributes)

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

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

    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)
98
        expect(response).to include_pagination_headers
barthc committed
99 100 101 102
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(1)
      end
    end
103 104

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

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

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

        expect(response).to have_http_status(200)
113
        expect(response).to include_pagination_headers
114
        expect(json_response).to be_an Array
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
        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)
131
        expect(response).to include_pagination_headers
132 133 134 135 136 137 138 139
        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)
140
        expect(response).to include_pagination_headers
141 142 143 144 145 146 147 148
        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)
149
        expect(response).to include_pagination_headers
150 151
        expect(json_response).to be_an Array
        expect(response_groups).to eq([group1.name, group3.name])
152 153
      end
    end
154

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

294
        expect(response).to have_http_status(200)
295
        expect(response).to include_pagination_headers
296
        expect(json_response.length).to eq(2)
297
        project_names = json_response.map { |proj| proj['name'] }
298
        expect(project_names).to match_array([project1.name, project3.name])
299
        expect(json_response.first['visibility']).to be_present
300 301 302 303 304 305
      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)
306
        expect(response).to include_pagination_headers
307
        expect(json_response.length).to eq(2)
308
        project_names = json_response.map { |proj| proj['name'] }
309
        expect(project_names).to match_array([project1.name, project3.name])
310
        expect(json_response.first['visibility']).not_to be_present
311 312
      end

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

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

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

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

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

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

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

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

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

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

      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
367 368 369
    end

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

432 433 434 435 436 437 438 439 440 441 442 443 444
      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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

532
        expect(response).to have_http_status(201)
Angus MacArthur committed
533
      end
534 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

      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
570 571
    end
  end
572
end