users_spec.rb 36.3 KB
Newer Older
Nihad Abbasov's avatar
Nihad Abbasov committed
1 2
require 'spec_helper'

3
describe API::Users, api: true  do
4 5
  include ApiHelpers

6 7 8
  let(:user)  { create(:user) }
  let(:admin) { create(:admin) }
  let(:key)   { create(:key, user: user) }
9
  let(:email)   { create(:email, user: user) }
10
  let(:omniauth_user) { create(:omniauth_user) }
11 12
  let(:ldap_user) { create(:omniauth_user, provider: 'ldapmain') }
  let(:ldap_blocked_user) { create(:omniauth_user, provider: 'ldapmain', state: 'ldap_blocked') }
Nihad Abbasov's avatar
Nihad Abbasov committed
13 14

  describe "GET /users" do
15
    context "when unauthenticated" do
16
      it "returns authentication error" do
17
        get api("/users")
18
        expect(response).to have_http_status(401)
19
      end
Nihad Abbasov's avatar
Nihad Abbasov committed
20 21
    end

22
    context "when authenticated" do
23
      # These specs are written just in case API authentication is not required anymore
Felipe Artur's avatar
Felipe Artur committed
24 25 26 27 28 29 30 31
      context "when public level is restricted" do
        before do
          stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
          allow_any_instance_of(API::Helpers).to receive(:authenticate!).and_return(true)
        end

        it "renders 403" do
          get api("/users")
32
          expect(response).to have_http_status(403)
Felipe Artur's avatar
Felipe Artur committed
33 34 35 36
        end

        it "renders 404" do
          get api("/users/#{user.id}")
37
          expect(response).to have_http_status(404)
Felipe Artur's avatar
Felipe Artur committed
38 39 40
        end
      end

41
      it "returns an array of users" do
Robert Speicher's avatar
Robert Speicher committed
42
        get api("/users", user)
43

44
        expect(response).to have_http_status(200)
45
        expect(response).to include_pagination_headers
46
        expect(json_response).to be_an Array
Marin Jankovski's avatar
Marin Jankovski committed
47
        username = user.username
48 49 50
        expect(json_response.detect do |user|
          user['username'] == username
        end['username']).to eq(username)
Nihad Abbasov's avatar
Nihad Abbasov committed
51
      end
52

53 54 55 56 57 58 59
      it "returns an array of blocked users" do
        ldap_blocked_user
        create(:user, state: 'blocked')

        get api("/users?blocked=true", user)

        expect(response).to have_http_status(200)
60
        expect(response).to include_pagination_headers
61 62 63 64
        expect(json_response).to be_an Array
        expect(json_response).to all(include('state' => /(blocked|ldap_blocked)/))
      end

65
      it "returns one user" do
66
        get api("/users?username=#{omniauth_user.username}", user)
67

68
        expect(response).to have_http_status(200)
69
        expect(response).to include_pagination_headers
70 71 72
        expect(json_response).to be_an Array
        expect(json_response.first['username']).to eq(omniauth_user.username)
      end
Nihad Abbasov's avatar
Nihad Abbasov committed
73
    end
74 75

    context "when admin" do
76
      it "returns an array of users" do
77
        get api("/users", admin)
78

79
        expect(response).to have_http_status(200)
80
        expect(response).to include_pagination_headers
81 82
        expect(json_response).to be_an Array
        expect(json_response.first.keys).to include 'email'
83
        expect(json_response.first.keys).to include 'organization'
84 85
        expect(json_response.first.keys).to include 'identities'
        expect(json_response.first.keys).to include 'can_create_project'
Stan Hu's avatar
Stan Hu committed
86
        expect(json_response.first.keys).to include 'two_factor_enabled'
87 88
        expect(json_response.first.keys).to include 'last_sign_in_at'
        expect(json_response.first.keys).to include 'confirmed_at'
89
      end
90 91 92 93 94 95 96

      it "returns an array of external users" do
        create(:user, external: true)

        get api("/users?external=true", admin)

        expect(response).to have_http_status(200)
97
        expect(response).to include_pagination_headers
98 99 100
        expect(json_response).to be_an Array
        expect(json_response).to all(include('external' => true))
      end
101
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
102 103 104
  end

  describe "GET /users/:id" do
105
    it "returns a user by id" do
Robert Speicher's avatar
Robert Speicher committed
106
      get api("/users/#{user.id}", user)
107
      expect(response).to have_http_status(200)
108
      expect(json_response['username']).to eq(user.username)
Nihad Abbasov's avatar
Nihad Abbasov committed
109 110
    end

111
    it "returns a 401 if unauthenticated" do
112
      get api("/users/9998")
113
      expect(response).to have_http_status(401)
114
    end
115

116
    it "returns a 404 error if user id not found" do
117
      get api("/users/9999", user)
118
      expect(response).to have_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
119
      expect(json_response['message']).to eq('404 User Not Found')
120
    end
121

122
    it "returns a 404 for invalid ID" do
123
      get api("/users/1ASDF", user)
124

125
      expect(response).to have_http_status(404)
126
    end
127 128 129 130
  end

  describe "POST /users" do
    before{ admin }
131

132
    it "creates user" do
133
      expect do
134
        post api("/users", admin), attributes_for(:user, projects_limit: 3)
135
      end.to change { User.count }.by(1)
136 137
    end

138
    it "creates user with correct attributes" do
139
      post api('/users', admin), attributes_for(:user, admin: true, can_create_group: true)
140
      expect(response).to have_http_status(201)
141 142
      user_id = json_response['id']
      new_user = User.find(user_id)
143 144 145
      expect(new_user).not_to eq(nil)
      expect(new_user.admin).to eq(true)
      expect(new_user.can_create_group).to eq(true)
146 147
    end

148 149 150 151 152 153 154 155 156
    it "creates user with optional attributes" do
      optional_attributes = { confirm: true }
      attributes = attributes_for(:user).merge(optional_attributes)

      post api('/users', admin), attributes

      expect(response).to have_http_status(201)
    end

157
    it "creates non-admin user" do
158
      post api('/users', admin), attributes_for(:user, admin: false, can_create_group: false)
159
      expect(response).to have_http_status(201)
160 161
      user_id = json_response['id']
      new_user = User.find(user_id)
162 163 164
      expect(new_user).not_to eq(nil)
      expect(new_user.admin).to eq(false)
      expect(new_user.can_create_group).to eq(false)
165 166
    end

167
    it "creates non-admin users by default" do
168
      post api('/users', admin), attributes_for(:user)
169
      expect(response).to have_http_status(201)
170 171
      user_id = json_response['id']
      new_user = User.find(user_id)
172 173
      expect(new_user).not_to eq(nil)
      expect(new_user.admin).to eq(false)
174 175
    end

176
    it "returns 201 Created on success" do
177
      post api("/users", admin), attributes_for(:user, projects_limit: 3)
178
      expect(response).to have_http_status(201)
179 180
    end

Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
181 182
    it 'creates non-external users by default' do
      post api("/users", admin), attributes_for(:user)
183
      expect(response).to have_http_status(201)
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
184 185 186 187 188 189 190

      user_id = json_response['id']
      new_user = User.find(user_id)
      expect(new_user).not_to eq nil
      expect(new_user.external).to be_falsy
    end

191
    it 'allows an external user to be created' do
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
192
      post api("/users", admin), attributes_for(:user, external: true)
193
      expect(response).to have_http_status(201)
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
194 195 196 197 198 199 200

      user_id = json_response['id']
      new_user = User.find(user_id)
      expect(new_user).not_to eq nil
      expect(new_user.external).to be_truthy
    end

201 202 203 204 205 206 207 208 209 210 211 212
    it "creates user with reset password" do
      post api('/users', admin), attributes_for(:user, reset_password: true).except(:password)

      expect(response).to have_http_status(201)

      user_id = json_response['id']
      new_user = User.find(user_id)

      expect(new_user).not_to eq(nil)
      expect(new_user.recently_sent_password_reset?).to eq(true)
    end

213
    it "does not create user with invalid email" do
214
      post api('/users', admin),
215 216 217
        email: 'invalid email',
        password: 'password',
        name: 'test'
218
      expect(response).to have_http_status(400)
219 220
    end

221
    it 'returns 400 error if name not given' do
222
      post api('/users', admin), attributes_for(:user).except(:name)
223
      expect(response).to have_http_status(400)
224 225
    end

226
    it 'returns 400 error if password not given' do
227
      post api('/users', admin), attributes_for(:user).except(:password)
228
      expect(response).to have_http_status(400)
229 230
    end

231
    it 'returns 400 error if email not given' do
232
      post api('/users', admin), attributes_for(:user).except(:email)
233
      expect(response).to have_http_status(400)
234 235
    end

236
    it 'returns 400 error if username not given' do
237
      post api('/users', admin), attributes_for(:user).except(:username)
238
      expect(response).to have_http_status(400)
239 240
    end

241
    it 'returns 400 error if user does not validate' do
242
      post api('/users', admin),
243 244 245 246 247 248
        password: 'pass',
        email: 'test@example.com',
        username: 'test!',
        name: 'test',
        bio: 'g' * 256,
        projects_limit: -1
249
      expect(response).to have_http_status(400)
250
      expect(json_response['message']['password']).
251
        to eq(['is too short (minimum is 8 characters)'])
252
      expect(json_response['message']['bio']).
253
        to eq(['is too long (maximum is 255 characters)'])
254
      expect(json_response['message']['projects_limit']).
255
        to eq(['must be greater than or equal to 0'])
256
      expect(json_response['message']['username']).
257
        to eq([Gitlab::Regex.namespace_regex_message])
258 259
    end

260
    it "is not available for non admin users" do
261
      post api("/users", user), attributes_for(:user)
262
      expect(response).to have_http_status(403)
263
    end
264

265 266 267
    context 'with existing user' do
      before do
        post api('/users', admin),
268 269 270 271
          email: 'test@example.com',
          password: 'password',
          username: 'test',
          name: 'foo'
272
      end
273

274
      it 'returns 409 conflict error if user with same email exists' do
275
        expect do
276
          post api('/users', admin),
277 278 279 280 281
            name: 'foo',
            email: 'test@example.com',
            password: 'password',
            username: 'foo'
        end.to change { User.count }.by(0)
282
        expect(response).to have_http_status(409)
283
        expect(json_response['message']).to eq('Email has already been taken')
284 285
      end

286
      it 'returns 409 conflict error if same username exists' do
287 288
        expect do
          post api('/users', admin),
289 290 291 292
            name: 'foo',
            email: 'foo@example.com',
            password: 'password',
            username: 'test'
293
        end.to change { User.count }.by(0)
294
        expect(response).to have_http_status(409)
295
        expect(json_response['message']).to eq('Username has already been taken')
296
      end
297 298 299 300 301 302 303 304

      it 'creates user with new identity' do
        post api("/users", admin), attributes_for(:user, provider: 'github', extern_uid: '67890')

        expect(response).to have_http_status(201)
        expect(json_response['identities'].first['extern_uid']).to eq('67890')
        expect(json_response['identities'].first['provider']).to eq('github')
      end
305
    end
306 307
  end

Marin Jankovski's avatar
Marin Jankovski committed
308
  describe "GET /users/sign_up" do
309
    it "redirects to sign in page" do
310
      get "/users/sign_up"
311
      expect(response).to have_http_status(302)
312
      expect(response).to redirect_to(new_user_session_path)
Marin Jankovski's avatar
Marin Jankovski committed
313 314 315
    end
  end

316
  describe "PUT /users/:id" do
317 318
    let!(:admin_user) { create(:admin) }

319 320
    before { admin }

321
    it "updates user with new bio" do
322
      put api("/users/#{user.id}", admin), { bio: 'new test bio' }
323
      expect(response).to have_http_status(200)
324 325
      expect(json_response['bio']).to eq('new test bio')
      expect(user.reload.bio).to eq('new test bio')
326 327
    end

328
    it "updates user with new password and forces reset on next login" do
329 330
      put api("/users/#{user.id}", admin), password: '12345678'

331
      expect(response).to have_http_status(200)
332
      expect(user.reload.password_expires_at).to be <= Time.now
333 334
    end

335 336
    it "updates user with organization" do
      put api("/users/#{user.id}", admin), { organization: 'GitLab' }
337

338 339 340 341 342
      expect(response).to have_http_status(200)
      expect(json_response['organization']).to eq('GitLab')
      expect(user.reload.organization).to eq('GitLab')
    end

343
    it 'updates user with his own email' do
344
      put api("/users/#{user.id}", admin), email: user.email
345
      expect(response).to have_http_status(200)
346 347
      expect(json_response['email']).to eq(user.email)
      expect(user.reload.email).to eq(user.email)
348 349
    end

350
    it 'updates user with his own username' do
351
      put api("/users/#{user.id}", admin), username: user.username
352
      expect(response).to have_http_status(200)
353 354
      expect(json_response['username']).to eq(user.username)
      expect(user.reload.username).to eq(user.username)
355 356
    end

357
    it "updates user's existing identity" do
358
      put api("/users/#{omniauth_user.id}", admin), provider: 'ldapmain', extern_uid: '654321'
359
      expect(response).to have_http_status(200)
360 361 362
      expect(omniauth_user.reload.identities.first.extern_uid).to eq('654321')
    end

363
    it 'updates user with new identity' do
364
      put api("/users/#{user.id}", admin), provider: 'github', extern_uid: 'john'
365
      expect(response).to have_http_status(200)
366
      expect(user.reload.identities.first.extern_uid).to eq('john')
367 368 369
      expect(user.reload.identities.first.provider).to eq('github')
    end

370
    it "updates admin status" do
371
      put api("/users/#{user.id}", admin), { admin: true }
372
      expect(response).to have_http_status(200)
373 374
      expect(json_response['is_admin']).to eq(true)
      expect(user.reload.admin).to eq(true)
375 376
    end

377
    it "updates external status" do
378 379 380 381 382 383
      put api("/users/#{user.id}", admin), { external: true }
      expect(response.status).to eq 200
      expect(json_response['external']).to eq(true)
      expect(user.reload.external?).to be_truthy
    end

384
    it "does not update admin status" do
385
      put api("/users/#{admin_user.id}", admin), { can_create_group: false }
386
      expect(response).to have_http_status(200)
387 388 389
      expect(json_response['is_admin']).to eq(true)
      expect(admin_user.reload.admin).to eq(true)
      expect(admin_user.can_create_group).to eq(false)
390 391
    end

392
    it "does not allow invalid update" do
393
      put api("/users/#{user.id}", admin), { email: 'invalid email' }
394
      expect(response).to have_http_status(400)
395
      expect(user.reload.email).not_to eq('invalid email')
396 397
    end

398
    it "is not available for non admin users" do
399
      put api("/users/#{user.id}", user), attributes_for(:user)
400
      expect(response).to have_http_status(403)
401 402
    end

403
    it "returns 404 for non-existing user" do
404
      put api("/users/999999", admin), { bio: 'update should fail' }
405
      expect(response).to have_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
406
      expect(json_response['message']).to eq('404 User Not Found')
407 408
    end

409
    it "returns a 404 if invalid ID" do
410 411
      put api("/users/ASDF", admin)

412
      expect(response).to have_http_status(404)
413 414
    end

415
    it 'returns 400 error if user does not validate' do
416
      put api("/users/#{user.id}", admin),
417 418 419 420 421 422
        password: 'pass',
        email: 'test@example.com',
        username: 'test!',
        name: 'test',
        bio: 'g' * 256,
        projects_limit: -1
423
      expect(response).to have_http_status(400)
424
      expect(json_response['message']['password']).
425
        to eq(['is too short (minimum is 8 characters)'])
426
      expect(json_response['message']['bio']).
427
        to eq(['is too long (maximum is 255 characters)'])
428
      expect(json_response['message']['projects_limit']).
429
        to eq(['must be greater than or equal to 0'])
430
      expect(json_response['message']['username']).
431
        to eq([Gitlab::Regex.namespace_regex_message])
432
    end
433

Robert Schilling's avatar
Robert Schilling committed
434 435 436 437 438 439 440 441 442 443 444 445
    it 'returns 400 if provider is missing for identity update' do
      put api("/users/#{omniauth_user.id}", admin), extern_uid: '654321'

      expect(response).to have_http_status(400)
    end

    it 'returns 400 if external UID is missing for identity update' do
      put api("/users/#{omniauth_user.id}", admin), provider: 'ldap'

      expect(response).to have_http_status(400)
    end

446
    context "with existing user" do
447
      before do
448 449
        post api("/users", admin), { email: 'test@example.com', password: 'password', username: 'test', name: 'test' }
        post api("/users", admin), { email: 'foo@bar.com', password: 'password', username: 'john', name: 'john' }
450
        @user = User.all.last
451
      end
452

453
      it 'returns 409 conflict error if email address exists' do
454
        put api("/users/#{@user.id}", admin), email: 'test@example.com'
455
        expect(response).to have_http_status(409)
456
        expect(@user.reload.email).to eq(@user.email)
457 458
      end

459
      it 'returns 409 conflict error if username taken' do
460 461
        @user_id = User.all.last.id
        put api("/users/#{@user.id}", admin), username: 'test'
462
        expect(response).to have_http_status(409)
463
        expect(@user.reload.username).to eq(@user.username)
464
      end
465
    end
466 467
  end

Angus MacArthur's avatar
Angus MacArthur committed
468 469 470
  describe "POST /users/:id/keys" do
    before { admin }

471
    it "does not create invalid ssh key" do
Angus MacArthur's avatar
Angus MacArthur committed
472
      post api("/users/#{user.id}/keys", admin), { title: "invalid key" }
Robert Schilling's avatar
Robert Schilling committed
473

474
      expect(response).to have_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
475
      expect(json_response['error']).to eq('key is missing')
476 477
    end

478
    it 'does not create key without title' do
479
      post api("/users/#{user.id}/keys", admin), key: 'some key'
Robert Schilling's avatar
Robert Schilling committed
480

481
      expect(response).to have_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
482
      expect(json_response['error']).to eq('title is missing')
Angus MacArthur's avatar
Angus MacArthur committed
483 484
    end

485
    it "creates ssh key" do
Angus MacArthur's avatar
Angus MacArthur committed
486
      key_attrs = attributes_for :key
487
      expect do
Angus MacArthur's avatar
Angus MacArthur committed
488
        post api("/users/#{user.id}/keys", admin), key_attrs
489
      end.to change{ user.keys.count }.by(1)
Angus MacArthur's avatar
Angus MacArthur committed
490
    end
491

492
    it "returns 400 for invalid ID" do
Connor Shea's avatar
Connor Shea committed
493
      post api("/users/999999/keys", admin)
494
      expect(response).to have_http_status(400)
495
    end
Angus MacArthur's avatar
Angus MacArthur committed
496 497
  end

Robert Schilling's avatar
Robert Schilling committed
498
  describe 'GET /user/:id/keys' do
499 500 501
    before { admin }

    context 'when unauthenticated' do
502
      it 'returns authentication error' do
503
        get api("/users/#{user.id}/keys")
504
        expect(response).to have_http_status(401)
505 506 507 508
      end
    end

    context 'when authenticated' do
509
      it 'returns 404 for non-existing user' do
510
        get api('/users/999999/keys', admin)
511
        expect(response).to have_http_status(404)
512
        expect(json_response['message']).to eq('404 User Not Found')
513 514
      end

515
      it 'returns array of ssh keys' do
516 517
        user.keys << key
        user.save
518

519
        get api("/users/#{user.id}/keys", admin)
520

521
        expect(response).to have_http_status(200)
522
        expect(response).to include_pagination_headers
523 524
        expect(json_response).to be_an Array
        expect(json_response.first['title']).to eq(key.title)
525 526 527 528
      end
    end
  end

Robert Schilling's avatar
Robert Schilling committed
529
  describe 'DELETE /user/:id/keys/:key_id' do
530 531 532
    before { admin }

    context 'when unauthenticated' do
533
      it 'returns authentication error' do
534
        delete api("/users/#{user.id}/keys/42")
535
        expect(response).to have_http_status(401)
536 537 538 539
      end
    end

    context 'when authenticated' do
540
      it 'deletes existing key' do
541 542
        user.keys << key
        user.save
543

544
        expect do
545
          delete api("/users/#{user.id}/keys/#{key.id}", admin)
546 547

          expect(response).to have_http_status(204)
548
        end.to change { user.keys.count }.by(-1)
549 550
      end

551
      it 'returns 404 error if user not found' do
552 553 554
        user.keys << key
        user.save
        delete api("/users/999999/keys/#{key.id}", admin)
555
        expect(response).to have_http_status(404)
556
        expect(json_response['message']).to eq('404 User Not Found')
557 558
      end

559
      it 'returns 404 error if key not foud' do
560
        delete api("/users/#{user.id}/keys/42", admin)
561
        expect(response).to have_http_status(404)
562
        expect(json_response['message']).to eq('404 Key Not Found')
563 564 565 566
      end
    end
  end

567 568 569
  describe "POST /users/:id/emails" do
    before { admin }

570
    it "does not create invalid email" do
Douwe Maan's avatar
Douwe Maan committed
571
      post api("/users/#{user.id}/emails", admin), {}
Robert Schilling's avatar
Robert Schilling committed
572

573
      expect(response).to have_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
574
      expect(json_response['error']).to eq('email is missing')
575 576
    end

577
    it "creates email" do
578 579 580 581 582
      email_attrs = attributes_for :email
      expect do
        post api("/users/#{user.id}/emails", admin), email_attrs
      end.to change{ user.emails.count }.by(1)
    end
583

584
    it "returns a 400 for invalid ID" do
Connor Shea's avatar
Connor Shea committed
585
      post api("/users/999999/emails", admin)
586

587
      expect(response).to have_http_status(400)
588
    end
589 590
  end

Robert Schilling's avatar
Robert Schilling committed
591
  describe 'GET /user/:id/emails' do
592 593 594
    before { admin }

    context 'when unauthenticated' do
595
      it 'returns authentication error' do
596
        get api("/users/#{user.id}/emails")
597
        expect(response).to have_http_status(401)
598 599 600 601
      end
    end

    context 'when authenticated' do
602
      it 'returns 404 for non-existing user' do
603
        get api('/users/999999/emails', admin)
604
        expect(response).to have_http_status(404)
605 606 607
        expect(json_response['message']).to eq('404 User Not Found')
      end

608
      it 'returns array of emails' do
609 610
        user.emails << email
        user.save
611

612
        get api("/users/#{user.id}/emails", admin)
613

614
        expect(response).to have_http_status(200)
615
        expect(response).to include_pagination_headers
616 617 618
        expect(json_response).to be_an Array
        expect(json_response.first['email']).to eq(email.email)
      end
619

620
      it "returns a 404 for invalid ID" do
621
        put api("/users/ASDF/emails", admin)
622

623
        expect(response).to have_http_status(404)
624
      end
625 626 627
    end
  end

Robert Schilling's avatar
Robert Schilling committed
628
  describe 'DELETE /user/:id/emails/:email_id' do
629 630 631
    before { admin }

    context 'when unauthenticated' do
632
      it 'returns authentication error' do
633
        delete api("/users/#{user.id}/emails/42")
634
        expect(response).to have_http_status(401)
635 636 637 638
      end
    end

    context 'when authenticated' do
639
      it 'deletes existing email' do
640 641
        user.emails << email
        user.save
642

643 644
        expect do
          delete api("/users/#{user.id}/emails/#{email.id}", admin)
645 646

          expect(response).to have_http_status(204)
647 648 649
        end.to change { user.emails.count }.by(-1)
      end

650
      it 'returns 404 error if user not found' do
651 652 653
        user.emails << email
        user.save
        delete api("/users/999999/emails/#{email.id}", admin)
654
        expect(response).to have_http_status(404)
655 656 657
        expect(json_response['message']).to eq('404 User Not Found')
      end

658
      it 'returns 404 error if email not foud' do
659
        delete api("/users/#{user.id}/emails/42", admin)
660
        expect(response).to have_http_status(404)
661 662
        expect(json_response['message']).to eq('404 Email Not Found')
      end
663

664
      it "returns a 404 for invalid ID" do
665 666
        delete api("/users/ASDF/emails/bar", admin)

667
        expect(response).to have_http_status(404)
668
      end
669 670 671
    end
  end

672
  describe "DELETE /users/:id" do
673
    let!(:namespace) { user.namespace }
674 675
    before { admin }

676
    it "deletes user" do
677
      delete api("/users/#{user.id}", admin)
678 679

      expect(response).to have_http_status(204)
680
      expect { User.find(user.id) }.to raise_error ActiveRecord::RecordNotFound
681
      expect { Namespace.find(namespace.id) }.to raise_error ActiveRecord::RecordNotFound
682 683
    end

684
    it "does not delete for unauthenticated user" do
685
      delete api("/users/#{user.id}")
686
      expect(response).to have_http_status(401)
687 688
    end

689
    it "is not available for non admin users" do
690
      delete api("/users/#{user.id}", user)
691
      expect(response).to have_http_status(403)
692 693
    end

694
    it "returns 404 for non-existing user" do
695
      delete api("/users/999999", admin)
696
      expect(response).to have_http_status(404)
697
      expect(json_response['message']).to eq('404 User Not Found')
698
    end
699

700
    it "returns a 404 for invalid ID" do
701 702
      delete api("/users/ASDF", admin)

703
      expect(response).to have_http_status(404)
704
    end
705 706
  end

Nihad Abbasov's avatar
Nihad Abbasov committed
707
  describe "GET /user" do
708
    let(:personal_access_token) { create(:personal_access_token, user: user).token }
709 710 711 712

    context 'with regular user' do
      context 'with personal access token' do
        it 'returns 403 without private token when sudo is defined' do
713
          get api("/user?private_token=#{personal_access_token}&sudo=123")
714 715 716 717 718 719 720

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

      context 'with private token' do
        it 'returns 403 without private token when sudo defined' do
721
          get api("/user?private_token=#{user.private_token}&sudo=123")
722 723 724 725 726 727 728 729 730 731

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

      it 'returns current user without private token when sudo not defined' do
        get api("/user", user)

        expect(response).to have_http_status(200)
        expect(response).to match_response_schema('user/public')
732
        expect(json_response['id']).to eq(user.id)
733
      end
Nihad Abbasov's avatar
Nihad Abbasov committed
734
    end
735

736
    context 'with admin' do
737
      let(:admin_personal_access_token) { create(:personal_access_token, user: admin).token }
738 739 740

      context 'with personal access token' do
        it 'returns 403 without private token when sudo defined' do
741
          get api("/user?private_token=#{admin_personal_access_token}&sudo=#{user.id}")
742 743 744 745

          expect(response).to have_http_status(403)
        end

746 747
        it 'returns initial current user without private token when sudo not defined' do
          get api("/user?private_token=#{admin_personal_access_token}")
748 749 750

          expect(response).to have_http_status(200)
          expect(response).to match_response_schema('user/public')
751
          expect(json_response['id']).to eq(admin.id)
752 753 754 755
        end
      end

      context 'with private token' do
756 757
        it 'returns sudoed user with private token when sudo defined' do
          get api("/user?private_token=#{admin.private_token}&sudo=#{user.id}")
758 759 760

          expect(response).to have_http_status(200)
          expect(response).to match_response_schema('user/login')
761
          expect(json_response['id']).to eq(user.id)
762 763
        end

764 765
        it 'returns initial current user without private token when sudo not defined' do
          get api("/user?private_token=#{admin.private_token}")
766 767 768

          expect(response).to have_http_status(200)
          expect(response).to match_response_schema('user/public')
769
          expect(json_response['id']).to eq(admin.id)
770 771 772 773 774 775 776 777 778 779
        end
      end
    end

    context 'with unauthenticated user' do
      it "returns 401 error if user is unauthenticated" do
        get api("/user")

        expect(response).to have_http_status(401)
      end
780
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
781
  end
782 783 784

  describe "GET /user/keys" do
    context "when unauthenticated" do
785
      it "returns authentication error" do
786
        get api("/user/keys")
787
        expect(response).to have_http_status(401)
788 789
      end
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
790

791
    context "when authenticated" do
792
      it "returns array of ssh keys" do
793 794
        user.keys << key
        user.save
795

796
        get api("/user/keys", user)
797

798
        expect(response).to have_http_status(200)
799
        expect(response).to include_pagination_headers
800 801
        expect(json_response).to be_an Array
        expect(json_response.first["title"]).to eq(key.title)
802 803 804 805
      end
    end
  end

Robert Schilling's avatar
Robert Schilling committed
806
  describe "GET /user/keys/:key_id" do
807
    it "returns single key" do
808 809 810
      user.keys << key
      user.save
      get api("/user/keys/#{key.id}", user)
811
      expect(response).to have_http_status(200)
812
      expect(json_response["title"]).to eq(key.title)
813
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
814

815
    it "returns 404 Not Found within invalid ID" do
816
      get api("/user/keys/42", user)
817

818
      expect(response).to have_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
819
      expect(json_response['message']).to eq('404 Key Not Found')
820 821
    end

822
    it "returns 404 error if admin accesses user's ssh key" do
823 824 825 826
      user.keys << key
      user.save
      admin
      get api("/user/keys/#{key.id}", admin)
827
      expect(response).to have_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
828
      expect(json_response['message']).to eq('404 Key Not Found')
829
    end
830

831
    it "returns 404 for invalid ID" do
832
      get api("/users/keys/ASDF", admin)
833

834
      expect(response).to have_http_status(404)
835
    end
836
  end
Nihad Abbasov's avatar
Nihad Abbasov committed
837

838
  describe "POST /user/keys" do
839
    it "creates ssh key" do
840
      key_attrs = attributes_for :key
841
      expect do
842
        post api("/user/keys", user), key_attrs
843
      end.to change{ user.keys.count }.by(1)
844
      expect(response).to have_http_status(201)
845 846
    end

847
    it "returns a 401 error if unauthorized" do
848
      post api("/user/keys"), title: 'some title', key: 'some key'
849
      expect(response).to have_http_status(401)
850 851
    end

852
    it "does not create ssh key without key" do
853
      post api("/user/keys", user), title: 'title'
Robert Schilling's avatar
Robert Schilling committed
854

855
      expect(response).to have_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
856
      expect(json_response['error']).to eq('key is missing')
857 858
    end

859
    it 'does not create ssh key without title' do
860
      post api('/user/keys', user), key: 'some key'
Robert Schilling's avatar
Robert Schilling committed
861

862
      expect(response).to have_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
863
      expect(json_response['error']).to eq('title is missing')
864 865
    end

866
    it "does not create ssh key without title" do
867
      post api("/user/keys", user), key: "somekey"
868
      expect(response).to have_http_status(400)
869 870 871
    end
  end

Robert Schilling's avatar
Robert Schilling committed
872
  describe "DELETE /user/keys/:key_id" do
873
    it "deletes existed key" do
874 875
      user.keys << key
      user.save
876

877
      expect do
878
        delete api("/user/keys/#{key.id}", user)
879 880

        expect(response).to have_http_status(204)
881
      end.to change{user.keys.count}.by(-1)
882
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
883

Robert Schilling's avatar
Robert Schilling committed
884
    it "returns 404 if key ID not found" do
885
      delete api("/user/keys/42", user)
Robert Schilling's avatar
Robert Schilling committed
886 887 888

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

891
    it "returns 401 error if unauthorized" do
892 893 894
      user.keys << key
      user.save
      delete api("/user/keys/#{key.id}")
895
      expect(response).to have_http_status(401)
896
    end
897

898
    it "returns a 404 for invalid ID" do
899 900
      delete api("/users/keys/ASDF", admin)

901
      expect(response).to have_http_status(404)
902
    end
903
  end
904

905 906
  describe "GET /user/emails" do
    context "when unauthenticated" do
907
      it "returns authentication error" do
908
        get api("/user/emails")
909
        expect(response).to have_http_status(401)
910 911 912 913
      end
    end

    context "when authenticated" do
914
      it "returns array of emails" do
915 916
        user.emails << email
        user.save
917

918
        get api("/user/emails", user)
919

920
        expect(response).to have_http_status(200)
921
        expect(response).to include_pagination_headers
922 923 924 925 926 927
        expect(json_response).to be_an Array
        expect(json_response.first["email"]).to eq(email.email)
      end
    end
  end

Robert Schilling's avatar
Robert Schilling committed
928
  describe "GET /user/emails/:email_id" do
929
    it "returns single email" do
930 931 932
      user.emails << email
      user.save
      get api("/user/emails/#{email.id}", user)
933
      expect(response).to have_http_status(200)
934 935 936
      expect(json_response["email"]).to eq(email.email)
    end

937
    it "returns 404 Not Found within invalid ID" do
938
      get api("/user/emails/42", user)
939
      expect(response).to have_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
940
      expect(json_response['message']).to eq('404 Email Not Found')
941 942
    end

943
    it "returns 404 error if admin accesses user's email" do
944 945 946 947
      user.emails << email
      user.save
      admin
      get api("/user/emails/#{email.id}", admin)
948
      expect(response).to have_http_status(404)
Robert Schilling's avatar
Robert Schilling committed
949
      expect(json_response['message']).to eq('404 Email Not Found')
950
    end
951

952
    it "returns 404 for invalid ID" do
953
      get api("/users/emails/ASDF", admin)
954

955
      expect(response).to have_http_status(404)
956
    end
957 958 959
  end

  describe "POST /user/emails" do
960
    it "creates email" do
961 962 963 964
      email_attrs = attributes_for :email
      expect do
        post api("/user/emails", user), email_attrs
      end.to change{ user.emails.count }.by(1)
965
      expect(response).to have_http_status(201)
966 967
    end

968
    it "returns a 401 error if unauthorized" do
969
      post api("/user/emails"), email: 'some email'
970
      expect(response).to have_http_status(401)
971 972
    end

973
    it "does not create email with invalid email" do
974
      post api("/user/emails", user), {}
Robert Schilling's avatar
Robert Schilling committed
975

976
      expect(response).to have_http_status(400)
Robert Schilling's avatar
Robert Schilling committed
977
      expect(json_response['error']).to eq('email is missing')
978 979 980
    end
  end

Robert Schilling's avatar
Robert Schilling committed
981
  describe "DELETE /user/emails/:email_id" do
982
    it "deletes existed email" do
983 984
      user.emails << email
      user.save
985

986 987
      expect do
        delete api("/user/emails/#{email.id}", user)
988 989

        expect(response).to have_http_status(204)
990 991 992
      end.to change{user.emails.count}.by(-1)
    end

Robert Schilling's avatar
Robert Schilling committed
993
    it "returns 404 if email ID not found" do
994
      delete api("/user/emails/42", user)
Robert Schilling's avatar
Robert Schilling committed
995 996 997

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

1000
    it "returns 401 error if unauthorized" do
1001 1002 1003
      user.emails << email
      user.save
      delete api("/user/emails/#{email.id}")
1004
      expect(response).to have_http_status(401)
1005
    end
1006

Robert Schilling's avatar
Robert Schilling committed
1007 1008
    it "returns 400 for invalid ID" do
      delete api("/user/emails/ASDF", admin)
1009

Robert Schilling's avatar
Robert Schilling committed
1010
      expect(response).to have_http_status(400)
1011
    end
1012 1013
  end

1014
  describe 'POST /users/:id/block' do
1015
    before { admin }
1016
    it 'blocks existing user' do
1017 1018
      post api("/users/#{user.id}/block", admin)
      expect(response).to have_http_status(201)
1019 1020 1021
      expect(user.reload.state).to eq('blocked')
    end

1022
    it 'does not re-block ldap blocked users' do
1023
      post api("/users/#{ldap_blocked_user.id}/block", admin)
1024
      expect(response).to have_http_status(403)
1025 1026 1027
      expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
    end

1028
    it 'does not be available for non admin users' do
1029
      post api("/users/#{user.id}/block", user)
1030
      expect(response).to have_http_status(403)
1031 1032 1033
      expect(user.reload.state).to eq('active')
    end

1034
    it 'returns a 404 error if user id not found' do
1035
      post api('/users/9999/block', admin)
1036
      expect(response).to have_http_status(404)
1037 1038 1039 1040
      expect(json_response['message']).to eq('404 User Not Found')
    end
  end

1041
  describe 'POST /users/:id/unblock' do
1042
    let(:blocked_user)  { create(:user, state: 'blocked') }
1043
    before { admin }
1044

1045
    it 'unblocks existing user' do
1046 1047
      post api("/users/#{user.id}/unblock", admin)
      expect(response).to have_http_status(201)
1048 1049 1050
      expect(user.reload.state).to eq('active')
    end

1051
    it 'unblocks a blocked user' do
1052 1053
      post api("/users/#{blocked_user.id}/unblock", admin)
      expect(response).to have_http_status(201)
1054 1055 1056
      expect(blocked_user.reload.state).to eq('active')
    end

1057
    it 'does not unblock ldap blocked users' do
1058
      post api("/users/#{ldap_blocked_user.id}/unblock", admin)
1059
      expect(response).to have_http_status(403)
1060
      expect(ldap_blocked_user.reload.state).to eq('ldap_blocked')
1061 1062
    end

1063
    it 'does not be available for non admin users' do
1064
      post api("/users/#{user.id}/unblock", user)
1065
      expect(response).to have_http_status(403)
1066 1067 1068
      expect(user.reload.state).to eq('active')
    end

1069
    it 'returns a 404 error if user id not found' do
1070
      post api('/users/9999/block', admin)
1071
      expect(response).to have_http_status(404)
1072 1073
      expect(json_response['message']).to eq('404 User Not Found')
    end
1074

1075
    it "returns a 404 for invalid ID" do
1076
      post api("/users/ASDF/block", admin)
1077

1078
      expect(response).to have_http_status(404)
1079
    end
1080
  end
1081

1082
  describe 'GET /users/:id/events' do
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
    let(:user) { create(:user) }
    let(:project) { create(:empty_project) }
    let(:note) { create(:note_on_issue, note: 'What an awesome day!', project: project) }

    before do
      project.add_user(user, :developer)
      EventCreateService.new.leave_note(note, user)
    end

    context "as a user than cannot see the event's project" do
      it 'returns no events' do
1094 1095 1096
        other_user = create(:user)

        get api("/users/#{user.id}/events", other_user)
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107

        expect(response).to have_http_status(200)
        expect(json_response).to be_empty
      end
    end

    context "as a user than can see the event's project" do
      context 'joined event' do
        it 'returns the "joined" event' do
          get api("/users/#{user.id}/events", user)

1108 1109 1110 1111
          expect(response).to have_http_status(200)
          expect(response).to include_pagination_headers
          expect(json_response).to be_an Array

Rémy Coutable's avatar
Rémy Coutable committed
1112
          comment_event = json_response.find { |e| e['action_name'] == 'commented on' }
1113

Rémy Coutable's avatar
Rémy Coutable committed
1114 1115 1116 1117
          expect(comment_event['project_id'].to_i).to eq(project.id)
          expect(comment_event['author_username']).to eq(user.username)
          expect(comment_event['note']['id']).to eq(note.id)
          expect(comment_event['note']['body']).to eq('What an awesome day!')
1118

Rémy Coutable's avatar
Rémy Coutable committed
1119
          joined_event = json_response.find { |e| e['action_name'] == 'joined' }
1120

Rémy Coutable's avatar
Rémy Coutable committed
1121 1122 1123
          expect(joined_event['project_id'].to_i).to eq(project.id)
          expect(joined_event['author_username']).to eq(user.username)
          expect(joined_event['author']['name']).to eq(user.name)
1124 1125
        end
      end
1126

1127
      context 'when there are multiple events from different projects' do
1128 1129
        let(:second_note) { create(:note_on_issue, project: create(:empty_project)) }
        let(:third_note) { create(:note_on_issue, project: project) }
1130 1131

        before do
1132
          second_note.project.add_user(user, :developer)
1133

1134 1135 1136
          [second_note, third_note].each do |note|
            EventCreateService.new.leave_note(note, user)
          end
1137 1138
        end

1139
        it 'returns events in the correct order (from newest to oldest)' do
1140 1141
          get api("/users/#{user.id}/events", user)

1142 1143
          comment_events = json_response.select { |e| e['action_name'] == 'commented on' }

1144 1145 1146
          expect(comment_events[0]['target_id']).to eq(third_note.id)
          expect(comment_events[1]['target_id']).to eq(second_note.id)
          expect(comment_events[2]['target_id']).to eq(note.id)
1147 1148
        end
      end
1149 1150 1151 1152 1153 1154 1155 1156 1157
    end

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

      expect(response).to have_http_status(404)
      expect(json_response['message']).to eq('404 User Not Found')
    end
  end
Nihad Abbasov's avatar
Nihad Abbasov committed
1158
end