user_spec.rb 18.2 KB
Newer Older
D
Dmitriy Zaporozhets 已提交
1 2 3 4
# == Schema Information
#
# Table name: users
#
D
Dmitriy Zaporozhets 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
#  id                            :integer          not null, primary key
#  email                         :string(255)      default(""), not null
#  encrypted_password            :string(255)      default(""), not null
#  reset_password_token          :string(255)
#  reset_password_sent_at        :datetime
#  remember_created_at           :datetime
#  sign_in_count                 :integer          default(0)
#  current_sign_in_at            :datetime
#  last_sign_in_at               :datetime
#  current_sign_in_ip            :string(255)
#  last_sign_in_ip               :string(255)
#  created_at                    :datetime
#  updated_at                    :datetime
#  name                          :string(255)
#  admin                         :boolean          default(FALSE), not null
#  projects_limit                :integer          default(10)
#  skype                         :string(255)      default(""), not null
#  linkedin                      :string(255)      default(""), not null
#  twitter                       :string(255)      default(""), not null
#  authentication_token          :string(255)
#  theme_id                      :integer          default(1), not null
#  bio                           :string(255)
#  failed_attempts               :integer          default(0)
#  locked_at                     :datetime
#  username                      :string(255)
#  can_create_group              :boolean          default(TRUE), not null
#  can_create_team               :boolean          default(TRUE), not null
#  state                         :string(255)
#  color_scheme_id               :integer          default(1), not null
#  notification_level            :integer          default(1), not null
#  password_expires_at           :datetime
#  created_by_id                 :integer
#  last_credential_check_at      :datetime
#  avatar                        :string(255)
#  confirmation_token            :string(255)
#  confirmed_at                  :datetime
#  confirmation_sent_at          :datetime
#  unconfirmed_email             :string(255)
#  hide_no_ssh_key               :boolean          default(FALSE)
#  website_url                   :string(255)      default(""), not null
#  github_access_token           :string(255)
#  gitlab_access_token           :string(255)
#  notification_email            :string(255)
#  hide_no_password              :boolean          default(FALSE)
#  password_automatically_set    :boolean          default(FALSE)
#  bitbucket_access_token        :string(255)
#  bitbucket_access_token_secret :string(255)
D
Dmitriy Zaporozhets 已提交
52 53
#

G
gitlabhq 已提交
54 55 56 57
require 'spec_helper'

describe User do
  describe "Associations" do
58 59 60 61 62 63 64 65 66 67 68 69 70
    it { is_expected.to have_one(:namespace) }
    it { is_expected.to have_many(:snippets).class_name('Snippet').dependent(:destroy) }
    it { is_expected.to have_many(:project_members).dependent(:destroy) }
    it { is_expected.to have_many(:groups) }
    it { is_expected.to have_many(:keys).dependent(:destroy) }
    it { is_expected.to have_many(:events).class_name('Event').dependent(:destroy) }
    it { is_expected.to have_many(:recent_events).class_name('Event') }
    it { is_expected.to have_many(:issues).dependent(:destroy) }
    it { is_expected.to have_many(:notes).dependent(:destroy) }
    it { is_expected.to have_many(:assigned_issues).dependent(:destroy) }
    it { is_expected.to have_many(:merge_requests).dependent(:destroy) }
    it { is_expected.to have_many(:assigned_merge_requests).dependent(:destroy) }
    it { is_expected.to have_many(:identities).dependent(:destroy) }
71 72
  end

73 74 75
  describe "Mass assignment" do
  end

76
  describe 'validations' do
77 78 79 80 81
    it { is_expected.to validate_presence_of(:username) }
    it { is_expected.to validate_presence_of(:projects_limit) }
    it { is_expected.to validate_numericality_of(:projects_limit) }
    it { is_expected.to allow_value(0).for(:projects_limit) }
    it { is_expected.not_to allow_value(-1).for(:projects_limit) }
82

83
    it { is_expected.to ensure_length_of(:bio).is_within(0..255) }
84 85 86 87 88 89

    describe 'email' do
      it 'accepts info@example.com' do
        user = build(:user, email: 'info@example.com')
        expect(user).to be_valid
      end
90

91 92 93 94 95
      it 'accepts info+test@example.com' do
        user = build(:user, email: 'info+test@example.com')
        expect(user).to be_valid
      end

96 97 98 99 100
      it "accepts o'reilly@example.com" do
        user = build(:user, email: "o'reilly@example.com")
        expect(user).to be_valid
      end

101 102 103 104 105 106 107 108 109
      it 'rejects test@test@example.com' do
        user = build(:user, email: 'test@test@example.com')
        expect(user).to be_invalid
      end

      it 'rejects mailto:test@example.com' do
        user = build(:user, email: 'mailto:test@example.com')
        expect(user).to be_invalid
      end
110 111 112 113 114

      it "rejects lol!'+=?><#$%^&*()@gmail.com" do
        user = build(:user, email: "lol!'+=?><#$%^&*()@gmail.com")
        expect(user).to be_invalid
      end
115
    end
G
gitlabhq 已提交
116 117 118
  end

  describe "Respond to" do
119 120 121
    it { is_expected.to respond_to(:is_admin?) }
    it { is_expected.to respond_to(:name) }
    it { is_expected.to respond_to(:private_token) }
G
gitlabhq 已提交
122 123
  end

124 125 126
  describe '#generate_password' do
    it "should execute callback when force_random_password specified" do
      user = build(:user, force_random_password: true)
127
      expect(user).to receive(:generate_password)
128 129 130 131
      user.save
    end

    it "should not generate password by default" do
132
      user = create(:user, password: 'abcdefghe')
133
      expect(user.password).to eq('abcdefghe')
134
    end
135

136
    it "should generate password when forcing random password" do
137
      allow(Devise).to receive(:friendly_token).and_return('123456789')
138
      user = create(:user, password: 'abcdefg', force_random_password: true)
139
      expect(user.password).to eq('12345678')
140
    end
141 142
  end

143 144
  describe 'authentication token' do
    it "should have authentication token" do
145
      user = create(:user)
146
      expect(user.authentication_token).not_to be_blank
147
    end
N
Nihad Abbasov 已提交
148
  end
149 150 151 152 153

  describe 'projects' do
    before do
      @user = create :user
      @project = create :project, namespace: @user.namespace
D
Dmitriy Zaporozhets 已提交
154 155
      @project_2 = create :project, group: create(:group) # Grant MASTER access to the user
      @project_3 = create :project, group: create(:group) # Grant DEVELOPER access to the user
156

157 158
      @project_2.team << [@user, :master]
      @project_3.team << [@user, :developer]
159 160
    end

161 162 163 164 165 166 167 168 169
    it { expect(@user.authorized_projects).to include(@project) }
    it { expect(@user.authorized_projects).to include(@project_2) }
    it { expect(@user.authorized_projects).to include(@project_3) }
    it { expect(@user.owned_projects).to include(@project) }
    it { expect(@user.owned_projects).not_to include(@project_2) }
    it { expect(@user.owned_projects).not_to include(@project_3) }
    it { expect(@user.personal_projects).to include(@project) }
    it { expect(@user.personal_projects).not_to include(@project_2) }
    it { expect(@user.personal_projects).not_to include(@project_3) }
170 171 172 173 174
  end

  describe 'groups' do
    before do
      @user = create :user
175 176
      @group = create :group
      @group.add_owner(@user)
177 178
    end

179 180 181
    it { expect(@user.several_namespaces?).to be_truthy }
    it { expect(@user.authorized_groups).to eq([@group]) }
    it { expect(@user.owned_groups).to eq([@group]) }
182 183
  end

184 185 186 187
  describe 'group multiple owners' do
    before do
      @user = create :user
      @user2 = create :user
188 189
      @group = create :group
      @group.add_owner(@user)
190

191
      @group.add_user(@user2, GroupMember::OWNER)
192 193
    end

194
    it { expect(@user2.several_namespaces?).to be_truthy }
195 196
  end

197 198 199 200 201 202
  describe 'namespaced' do
    before do
      @user = create :user
      @project = create :project, namespace: @user.namespace
    end

203
    it { expect(@user.several_namespaces?).to be_falsey }
204 205 206 207 208 209 210
  end

  describe 'blocking user' do
    let(:user) { create(:user, name: 'John Smith') }

    it "should block user" do
      user.block
211
      expect(user.blocked?).to be_truthy
212 213 214 215 216
    end
  end

  describe 'filter' do
    before do
217
      User.delete_all
218 219
      @user = create :user
      @admin = create :user, admin: true
220
      @blocked = create :user, state: :blocked
221 222
    end

223 224 225 226
    it { expect(User.filter("admins")).to eq([@admin]) }
    it { expect(User.filter("blocked")).to eq([@blocked]) }
    it { expect(User.filter("wop")).to include(@user, @admin, @blocked) }
    it { expect(User.filter(nil)).to include(@user, @admin) }
227 228 229 230
  end

  describe :not_in_project do
    before do
231
      User.delete_all
232 233 234 235
      @user = create :user
      @project = create :project
    end

236
    it { expect(User.not_in_project(@project)).to include(@user, @project.owner) }
237
  end
D
Dmitriy Zaporozhets 已提交
238

239 240 241
  describe 'user creation' do
    describe 'normal user' do
      let(:user) { create(:user, name: 'John Smith') }
D
Dmitriy Zaporozhets 已提交
242

243 244 245 246 247
      it { expect(user.is_admin?).to be_falsey }
      it { expect(user.require_ssh_key?).to be_truthy }
      it { expect(user.can_create_group?).to be_truthy }
      it { expect(user.can_create_project?).to be_truthy }
      it { expect(user.first_name).to eq('John') }
248
    end
249

D
Dmitriy Zaporozhets 已提交
250
    describe 'with defaults' do
251
      let(:user) { User.new }
D
Dmitriy Zaporozhets 已提交
252

D
Dmitriy Zaporozhets 已提交
253
      it "should apply defaults to user" do
254 255 256
        expect(user.projects_limit).to eq(Gitlab.config.gitlab.default_projects_limit)
        expect(user.can_create_group).to eq(Gitlab.config.gitlab.default_can_create_group)
        expect(user.theme_id).to eq(Gitlab.config.gitlab.default_theme)
257 258 259
      end
    end

D
Dmitriy Zaporozhets 已提交
260 261
    describe 'with default overrides' do
      let(:user) { User.new(projects_limit: 123, can_create_group: false, can_create_team: true, theme_id: Gitlab::Theme::BASIC) }
D
Dmitriy Zaporozhets 已提交
262

D
Dmitriy Zaporozhets 已提交
263
      it "should apply defaults to user" do
264 265 266
        expect(user.projects_limit).to eq(123)
        expect(user.can_create_group).to be_falsey
        expect(user.theme_id).to eq(Gitlab::Theme::BASIC)
267
      end
268 269
    end
  end
270

M
Marin Jankovski 已提交
271 272 273 274 275
  describe 'search' do
    let(:user1) { create(:user, username: 'James', email: 'james@testing.com') }
    let(:user2) { create(:user, username: 'jameson', email: 'jameson@example.com') }

    it "should be case insensitive" do
276 277 278 279 280 281
      expect(User.search(user1.username.upcase).to_a).to eq([user1])
      expect(User.search(user1.username.downcase).to_a).to eq([user1])
      expect(User.search(user2.username.upcase).to_a).to eq([user2])
      expect(User.search(user2.username.downcase).to_a).to eq([user2])
      expect(User.search(user1.username.downcase).to_a.count).to eq(2)
      expect(User.search(user2.username.downcase).to_a.count).to eq(1)
M
Marin Jankovski 已提交
282 283 284
    end
  end

285
  describe 'by_username_or_id' do
D
Dmitriy Zaporozhets 已提交
286 287
    let(:user1) { create(:user, username: 'foo') }

288
    it "should get the correct user" do
289 290 291 292
      expect(User.by_username_or_id(user1.id)).to eq(user1)
      expect(User.by_username_or_id('foo')).to eq(user1)
      expect(User.by_username_or_id(-1)).to be_nil
      expect(User.by_username_or_id('bar')).to be_nil
293 294
    end
  end
G
GitLab 已提交
295

296 297 298 299 300 301 302 303 304 305 306 307 308 309
  describe '.by_login' do
    let(:username) { 'John' }
    let!(:user) { create(:user, username: username) }

    it 'should get the correct user' do
      expect(User.by_login(user.email.upcase)).to eq user
      expect(User.by_login(user.email)).to eq user
      expect(User.by_login(username.downcase)).to eq user
      expect(User.by_login(username)).to eq user
      expect(User.by_login(nil)).to be_nil
      expect(User.by_login('')).to be_nil
    end
  end

G
GitLab 已提交
310
  describe 'all_ssh_keys' do
311
    it { is_expected.to have_many(:keys).dependent(:destroy) }
G
GitLab 已提交
312 313 314 315 316

    it "should have all ssh keys" do
      user = create :user
      key = create :key, key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD33bWLBxu48Sev9Fert1yzEO4WGcWglWF7K/AwblIUFselOt/QdOL9DSjpQGxLagO1s9wl53STIO8qGS4Ms0EJZyIXOEFMjFJ5xmjSy+S37By4sG7SsltQEHMxtbtFOaW5LV2wCrX+rUsRNqLMamZjgjcPO0/EgGCXIGMAYW4O7cwGZdXWYIhQ1Vwy+CsVMDdPkPgBXqK7nR/ey8KMs8ho5fMNgB5hBw/AL9fNGhRw3QTD6Q12Nkhl4VZES2EsZqlpNnJttnPdp847DUsT6yuLRlfiQfz5Cn9ysHFdXObMN5VYIiPFwHeYCZp1X2S4fDZooRE8uOLTfxWHPXwrhqSH", user_id: user.id

317
      expect(user.all_ssh_keys).to include(key.key)
G
GitLab 已提交
318
    end
G
GitLab 已提交
319
  end
320

D
Dmitriy Zaporozhets 已提交
321 322 323 324 325
  describe :avatar_type do
    let(:user) { create(:user) }

    it "should be true if avatar is image" do
      user.update_attribute(:avatar, 'uploads/avatar.png')
326
      expect(user.avatar_type).to be_truthy
D
Dmitriy Zaporozhets 已提交
327 328 329 330
    end

    it "should be false if avatar is html page" do
      user.update_attribute(:avatar, 'uploads/avatar.html')
331
      expect(user.avatar_type).to eq(["only images allowed"])
D
Dmitriy Zaporozhets 已提交
332 333
    end
  end
J
Jerome Dalbert 已提交
334

335 336 337
  describe :requires_ldap_check? do
    let(:user) { User.new }

338 339 340 341
    it 'is false when LDAP is disabled' do
      # Create a condition which would otherwise cause 'true' to be returned
      user.stub(ldap_user?: true)
      user.last_credential_check_at = nil
342
      expect(user.requires_ldap_check?).to be_falsey
343 344
    end

345 346
    context 'when LDAP is enabled' do
      before { Gitlab.config.ldap.stub(enabled: true) }
347

348 349
      it 'is false for non-LDAP users' do
        user.stub(ldap_user?: false)
350
        expect(user.requires_ldap_check?).to be_falsey
351 352
      end

353 354 355 356 357
      context 'and when the user is an LDAP user' do
        before { user.stub(ldap_user?: true) }

        it 'is true when the user has never had an LDAP check before' do
          user.last_credential_check_at = nil
358
          expect(user.requires_ldap_check?).to be_truthy
359 360 361 362
        end

        it 'is true when the last LDAP check happened over 1 hour ago' do
          user.last_credential_check_at = 2.hours.ago
363
          expect(user.requires_ldap_check?).to be_truthy
364
        end
365 366 367 368
      end
    end
  end

369 370
  describe :ldap_user? do
    it "is true if provider name starts with ldap" do
371
      user = create(:omniauth_user, provider: 'ldapmain')
372
      expect( user.ldap_user? ).to be_truthy
373 374 375
    end

    it "is false for other providers" do
376
      user = create(:omniauth_user, provider: 'other-provider')
377
      expect( user.ldap_user? ).to be_falsey
378 379 380
    end

    it "is false if no extern_uid is provided" do
381
      user = create(:omniauth_user, extern_uid: nil)
382
      expect( user.ldap_user? ).to be_falsey
383 384 385
    end
  end

386 387 388
  describe :ldap_identity do
    it "returns ldap identity" do
      user = create :omniauth_user
389
      expect(user.ldap_identity.provider).not_to be_empty
390 391 392
    end
  end

J
Jerome Dalbert 已提交
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431
  describe '#full_website_url' do
    let(:user) { create(:user) }

    it 'begins with http if website url omits it' do
      user.website_url = 'test.com'

      expect(user.full_website_url).to eq 'http://test.com'
    end

    it 'begins with http if website url begins with http' do
      user.website_url = 'http://test.com'

      expect(user.full_website_url).to eq 'http://test.com'
    end

    it 'begins with https if website url begins with https' do
      user.website_url = 'https://test.com'

      expect(user.full_website_url).to eq 'https://test.com'
    end
  end

  describe '#short_website_url' do
    let(:user) { create(:user) }

    it 'does not begin with http if website url omits it' do
      user.website_url = 'test.com'

      expect(user.short_website_url).to eq 'test.com'
    end

    it 'does not begin with http if website url begins with http' do
      user.website_url = 'http://test.com'

      expect(user.short_website_url).to eq 'test.com'
    end

    it 'does not begin with https if website url begins with https' do
      user.website_url = 'https://test.com'
432

J
Jerome Dalbert 已提交
433 434
      expect(user.short_website_url).to eq 'test.com'
    end
G
GitLab 已提交
435
  end
C
Ciro Santilli 已提交
436

437 438 439 440 441 442
  describe "#starred?" do
    it "determines if user starred a project" do
      user = create :user
      project1 = create :project, :public
      project2 = create :project, :public

443 444
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_falsey
445 446

      star1 = UsersStarProject.create!(project: project1, user: user)
447 448
      expect(user.starred?(project1)).to be_truthy
      expect(user.starred?(project2)).to be_falsey
449 450

      star2 = UsersStarProject.create!(project: project2, user: user)
451 452
      expect(user.starred?(project1)).to be_truthy
      expect(user.starred?(project2)).to be_truthy
453 454

      star1.destroy
455 456
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_truthy
457 458

      star2.destroy
459 460
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_falsey
461 462 463
    end
  end

C
Ciro Santilli 已提交
464 465 466 467 468
  describe "#toggle_star" do
    it "toggles stars" do
      user = create :user
      project = create :project, :public

469
      expect(user.starred?(project)).to be_falsey
C
Ciro Santilli 已提交
470
      user.toggle_star(project)
471
      expect(user.starred?(project)).to be_truthy
C
Ciro Santilli 已提交
472
      user.toggle_star(project)
473
      expect(user.starred?(project)).to be_falsey
C
Ciro Santilli 已提交
474 475
    end
  end
V
Valery Sizov 已提交
476 477 478 479 480 481 482

  describe "#sort" do
    before do
      User.delete_all
      @user = create :user, created_at: Date.today, last_sign_in_at: Date.today, name: 'Alpha'
      @user1 = create :user, created_at: Date.today - 1, last_sign_in_at: Date.today - 1, name: 'Omega'
    end
483

V
Valery Sizov 已提交
484
    it "sorts users as recently_signed_in" do
485
      expect(User.sort('recent_sign_in').first).to eq(@user)
V
Valery Sizov 已提交
486 487 488
    end

    it "sorts users as late_signed_in" do
489
      expect(User.sort('oldest_sign_in').first).to eq(@user1)
V
Valery Sizov 已提交
490 491 492
    end

    it "sorts users as recently_created" do
493
      expect(User.sort('created_desc').first).to eq(@user)
V
Valery Sizov 已提交
494 495 496
    end

    it "sorts users as late_created" do
497
      expect(User.sort('created_asc').first).to eq(@user1)
V
Valery Sizov 已提交
498 499 500
    end

    it "sorts users by name when nil is passed" do
501
      expect(User.sort(nil).first).to eq(@user)
V
Valery Sizov 已提交
502 503
    end
  end
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531

  describe "#contributed_projects_ids" do

    subject { create(:user) }
    let!(:project1) { create(:project) }
    let!(:project2) { create(:project, forked_from_project: project3) }
    let!(:project3) { create(:project) }
    let!(:merge_request) { create(:merge_request, source_project: project2, target_project: project3, author: subject) }
    let!(:push_event) { create(:event, action: Event::PUSHED, project: project1, target: project1, author: subject) }
    let!(:merge_event) { create(:event, action: Event::CREATED, project: project3, target: merge_request, author: subject) }

    before do
      project1.team << [subject, :master]
      project2.team << [subject, :master]
    end

    it "includes IDs for projects the user has pushed to" do
      expect(subject.contributed_projects_ids).to include(project1.id)
    end

    it "includes IDs for projects the user has had merge requests merged into" do
      expect(subject.contributed_projects_ids).to include(project3.id)
    end

    it "doesn't include IDs for unrelated projects" do
      expect(subject.contributed_projects_ids).not_to include(project2.id)
    end
  end
G
gitlabhq 已提交
532
end