BigW Consortium Gitlab

groups_spec.rb 17.7 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 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 46 47 48

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

        expect(response).to have_http_status(200)
        expect(json_response).to be_an Array
        expect(json_response.first).not_to include 'statistics'
      end
49
    end
50

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

55
        expect(response).to have_http_status(200)
56 57
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(2)
58
      end
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73

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

        expect(response).to have_http_status(200)
        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,
74
        }.stringify_keys
75 76 77 78 79 80 81

        project1.statistics.update!(attributes)

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

        expect(response).to have_http_status(200)
        expect(json_response).to be_an Array
82 83
        expect(json_response)
          .to satisfy_one { |group| group['statistics'] == attributes }
84
      end
85
    end
barthc committed
86 87 88 89 90 91 92 93 94 95

    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)
        expect(json_response).to be_an Array
        expect(json_response.length).to eq(1)
      end
    end
96 97

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

100 101
      it "returns all groups you have access to" do
        public_group = create :group, :public
102

103 104 105 106
        get api("/groups", user1), all_available: true

        expect(response).to have_http_status(200)
        expect(json_response).to be_an Array
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
        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)
        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)
        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)
        expect(json_response).to be_an Array
        expect(response_groups).to eq([group1.name, group3.name])
141 142
      end
    end
143
  end
144

145 146 147 148
  describe 'GET /groups/owned' do
    context 'when unauthenticated' do
      it 'returns authentication error' do
        get api('/groups/owned')
149

150 151 152 153 154 155 156
        expect(response).to have_http_status(401)
      end
    end

    context 'when authenticated as group owner' do
      it 'returns an array of groups the user owns' do
        get api('/groups/owned', user2)
157

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

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

171
        get api("/groups/#{group1.id}", user1)
172

173
        expect(response).to have_http_status(200)
174 175 176 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)
        expect(json_response['visibility_level']).to eq(group1.visibility_level)
        expect(json_response['avatar_url']).to eq(group1.avatar_url)
        expect(json_response['web_url']).to eq(group1.web_url)
181 182 183
        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)
184
        expect(json_response['parent_id']).to eq(group1.parent_id)
185 186 187 188 189
        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)
190
      end
191

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

195
        expect(response).to have_http_status(404)
196
      end
197

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

201
        expect(response).to have_http_status(404)
202 203
      end
    end
204

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

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

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

216
        expect(response).to have_http_status(404)
217 218
      end
    end
219 220

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

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

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

231
        expect(response).to have_http_status(404)
232 233
      end

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

237
        expect(response).to have_http_status(404)
238 239
      end
    end
240
  end
241

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

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

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

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

257
        expect(response).to have_http_status(404)
258 259 260
      end
    end

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

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

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

274
        expect(response).to have_http_status(403)
275 276
      end
    end
277 278

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

282
        expect(response).to have_http_status(404)
283 284
      end
    end
285 286
  end

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

292
        expect(response).to have_http_status(200)
293 294 295
        expect(json_response.length).to eq(2)
        project_names = json_response.map { |proj| proj['name' ] }
        expect(project_names).to match_array([project1.name, project3.name])
296
        expect(json_response.first['visibility_level']).to be_present
297 298 299 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)
        expect(json_response.length).to eq(2)
        project_names = json_response.map { |proj| proj['name' ] }
        expect(project_names).to match_array([project1.name, project3.name])
306
        expect(json_response.first['visibility_level']).not_to be_present
307 308
      end

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

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

        expect(response).to have_http_status(200)
        expect(json_response).to be_an(Array)
        expect(json_response.length).to eq(1)
317
        expect(json_response.first['name']).to eq(public_project.name)
318 319
      end

320
      it "does not return a non existing group" do
321
        get api("/groups/1328/projects", user1)
322

323
        expect(response).to have_http_status(404)
324 325
      end

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

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

332
      it "only returns projects to which user has access" do
333 334 335 336
        project3.team << [user3, :developer]

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

337
        expect(response).to have_http_status(200)
338 339 340
        expect(json_response.length).to eq(1)
        expect(json_response.first['name']).to eq(project3.name)
      end
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360

      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
361 362 363
    end

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

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

372
      it "does not return a non existing group" do
373
        get api("/groups/1328/projects", admin)
374

375
        expect(response).to have_http_status(404)
376 377 378 379
      end
    end

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

383
        expect(response).to have_http_status(200)
384 385
        project_names = json_response.map { |proj| proj['name' ] }
        expect(project_names).to match_array([project1.name, project3.name])
386 387
      end

388
      it 'does not return a non existing group' do
389
        get api('/groups/unknown/projects', admin)
390

391
        expect(response).to have_http_status(404)
392 393
      end

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

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

402
  describe "POST /groups" do
403
    context "when authenticated as user without group permissions" do
404
      it "does not create group" do
405
        post api("/groups", user1), attributes_for(:group)
406

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

411
    context "when authenticated as user with group permissions" do
412
      it "creates group" do
413 414 415
        group = attributes_for(:group, { request_access_enabled: false })

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

417
        expect(response).to have_http_status(201)
418 419 420 421

        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])
422
      end
423

424 425 426 427 428 429 430 431 432 433 434 435 436
      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

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

440
        expect(response).to have_http_status(400)
441
        expect(response.message).to eq("Bad Request")
442
      end
443

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

447
        expect(response).to have_http_status(400)
448 449
      end

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

453
        expect(response).to have_http_status(400)
454
      end
455 456
    end
  end
Angus MacArthur committed
457

458 459
  describe "DELETE /groups/:id" do
    context "when authenticated as user" do
460
      it "removes group" do
461
        delete api("/groups/#{group1.id}", user1)
462

463
        expect(response).to have_http_status(200)
464 465
      end

466
      it "does not remove a group if not an owner" do
467
        user4 = create(:user)
468
        group1.add_master(user4)
469

470
        delete api("/groups/#{group1.id}", user3)
471

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

475
      it "does not remove a non existing group" do
476
        delete api("/groups/1328", user1)
477

478
        expect(response).to have_http_status(404)
479 480
      end

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

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

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

492
        expect(response).to have_http_status(200)
493 494
      end

495
      it "does not remove a non existing group" do
496
        delete api("/groups/1328", admin)
497

498
        expect(response).to have_http_status(404)
499 500 501 502
      end
    end
  end

Angus MacArthur committed
503
  describe "POST /groups/:id/projects/:project_id" do
504
    let(:project) { create(:empty_project) }
505 506
    let(:project_path) { "#{project.namespace.path}%2F#{project.path}" }

Angus MacArthur committed
507
    before(:each) do
508 509
      allow_any_instance_of(Projects::TransferService).
        to receive(:execute).and_return(true)
Angus MacArthur committed
510 511 512
    end

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

516
        expect(response).to have_http_status(403)
Angus MacArthur committed
517 518 519 520
      end
    end

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

524
        expect(response).to have_http_status(201)
Angus MacArthur committed
525
      end
526 527 528 529 530 531 532 533 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

      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
562 563
    end
  end
564
end