user_spec.rb 28.5 KB
Newer Older
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
1 2 3 4
# == Schema Information
#
# Table name: users
#
Stan Hu's avatar
Stan Hu committed
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 52 53 54 55 56 57 58 59 60 61
#  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
#  notification_email          :string(255)
#  hide_no_password            :boolean          default(FALSE)
#  password_automatically_set  :boolean          default(FALSE)
#  location                    :string(255)
#  encrypted_otp_secret        :string(255)
#  encrypted_otp_secret_iv     :string(255)
#  encrypted_otp_secret_salt   :string(255)
#  otp_required_for_login      :boolean          default(FALSE), not null
#  otp_backup_codes            :text
#  public_email                :string(255)      default(""), not null
#  dashboard                   :integer          default(0)
#  project_view                :integer          default(0)
#  consumed_timestep           :integer
#  layout                      :integer          default(0)
#  hide_project_limit          :boolean          default(FALSE)
#  unlock_token                :string
#  otp_grace_period_started_at :datetime
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
62 63
#

gitlabhq's avatar
gitlabhq committed
64 65
require 'spec_helper'

Douwe Maan's avatar
Douwe Maan committed
66
describe User, models: true do
67 68
  include Gitlab::CurrentSettings

69 70 71 72 73 74 75 76 77 78 79
  describe 'modules' do
    subject { described_class }

    it { is_expected.to include_module(Gitlab::ConfigHelper) }
    it { is_expected.to include_module(Gitlab::CurrentSettings) }
    it { is_expected.to include_module(Referable) }
    it { is_expected.to include_module(Sortable) }
    it { is_expected.to include_module(TokenAuthenticatable) }
  end

  describe 'associations' do
80 81 82 83 84 85 86 87 88 89 90 91 92
    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) }
93
    it { is_expected.to have_one(:abuse_report) }
94
    it { is_expected.to have_many(:spam_logs).dependent(:destroy) }
95
    it { is_expected.to have_many(:todos).dependent(:destroy) }
96 97 98
  end

  describe 'validations' do
99 100 101 102 103 104 105 106 107 108 109 110 111
    describe 'username' do
      it 'validates presence' do
        expect(subject).to validate_presence_of(:username)
      end

      it 'rejects blacklisted names' do
        user = build(:user, username: 'dashboard')

        expect(user).not_to be_valid
        expect(user.errors.values).to eq [['dashboard is a reserved name']]
      end

      it 'validates uniqueness' do
112
        expect(subject).to validate_uniqueness_of(:username).case_insensitive
113 114 115
      end
    end

116 117 118 119
    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) }
120

121
    it { is_expected.to validate_length_of(:bio).is_within(0..255) }
122

123 124 125
    it_behaves_like 'an object with email-formated attributes', :email do
      subject { build(:user) }
    end
126

127 128 129
    it_behaves_like 'an object with email-formated attributes', :public_email, :notification_email do
      subject { build(:user).tap { |user| user.emails << build(:email, email: email_value) } }
    end
130

131
    describe 'email' do
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
      context 'when no signup domains listed' do
        before { allow(current_application_settings).to receive(:restricted_signup_domains).and_return([]) }
        it 'accepts any email' do
          user = build(:user, email: "info@example.com")
          expect(user).to be_valid
        end
      end

      context 'when a signup domain is listed and subdomains are allowed' do
        before { allow(current_application_settings).to receive(:restricted_signup_domains).and_return(['example.com', '*.example.com']) }
        it 'accepts info@example.com' do
          user = build(:user, email: "info@example.com")
          expect(user).to be_valid
        end

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

        it 'rejects example@test.com' do
          user = build(:user, email: "example@test.com")
          expect(user).to be_invalid
        end
      end

      context 'when a signup domain is listed and subdomains are not allowed' do
        before { allow(current_application_settings).to receive(:restricted_signup_domains).and_return(['example.com']) }

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

        it 'rejects info@test.example.com' do
          user = build(:user, email: "info@test.example.com")
          expect(user).to be_invalid
        end

        it 'rejects example@test.com' do
          user = build(:user, email: "example@test.com")
          expect(user).to be_invalid
        end
      end
176
    end
gitlabhq's avatar
gitlabhq committed
177
  end
178

179 180 181 182 183 184 185 186
  describe "non_ldap" do
    it "retuns non-ldap user" do
      User.delete_all
      create :user
      ldap_user = create :omniauth_user, provider: "ldapmain"
      create :omniauth_user, provider: "gitlub"

      users = User.non_ldap
Robert Speicher's avatar
Robert Speicher committed
187 188
      expect(users.count).to eq 2
      expect(users.detect { |user| user.username == ldap_user.username }).to be_nil
189 190 191
    end
  end

gitlabhq's avatar
gitlabhq committed
192
  describe "Respond to" do
193 194 195
    it { is_expected.to respond_to(:is_admin?) }
    it { is_expected.to respond_to(:name) }
    it { is_expected.to respond_to(:private_token) }
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
196 197 198 199 200 201 202 203 204 205 206 207 208 209
    it { is_expected.to respond_to(:external?) }
  end

  describe 'before save hook' do
    context 'when saving an external user' do
      let(:user)          { create(:user) }
      let(:external_user) { create(:user, external: true) }

      it "sets other properties aswell" do
        expect(external_user.can_create_team).to be_falsey
        expect(external_user.can_create_group).to be_falsey
        expect(external_user.projects_limit).to be 0
      end
    end
gitlabhq's avatar
gitlabhq committed
210 211
  end

212 213 214 215 216 217 218 219
  describe '#confirm' do
    let(:user) { create(:user, confirmed_at: nil, unconfirmed_email: 'test@gitlab.com') }

    it 'returns unconfirmed' do
      expect(user.confirmed?).to be_falsey
    end

    it 'confirms a user' do
220
      user.confirm
221 222 223 224
      expect(user.confirmed?).to be_truthy
    end
  end

225 226 227 228 229 230 231 232
  describe '#to_reference' do
    let(:user) { create(:user) }

    it 'returns a String reference to the object' do
      expect(user.to_reference).to eq "@#{user.username}"
    end
  end

233 234 235
  describe '#generate_password' do
    it "should execute callback when force_random_password specified" do
      user = build(:user, force_random_password: true)
236
      expect(user).to receive(:generate_password)
237 238 239 240
      user.save
    end

    it "should not generate password by default" do
241
      user = create(:user, password: 'abcdefghe')
242
      expect(user.password).to eq('abcdefghe')
243
    end
244

245
    it "should generate password when forcing random password" do
246
      allow(Devise).to receive(:friendly_token).and_return('123456789')
247
      user = create(:user, password: 'abcdefg', force_random_password: true)
248
      expect(user.password).to eq('12345678')
249
    end
250 251
  end

252 253
  describe 'authentication token' do
    it "should have authentication token" do
254
      user = create(:user)
255
      expect(user.authentication_token).not_to be_blank
256
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
257
  end
258

259
  describe '#recently_sent_password_reset?' do
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
    it 'is false when reset_password_sent_at is nil' do
      user = build_stubbed(:user, reset_password_sent_at: nil)

      expect(user.recently_sent_password_reset?).to eq false
    end

    it 'is false when sent more than one minute ago' do
      user = build_stubbed(:user, reset_password_sent_at: 5.minutes.ago)

      expect(user.recently_sent_password_reset?).to eq false
    end

    it 'is true when sent less than one minute ago' do
      user = build_stubbed(:user, reset_password_sent_at: Time.now)

      expect(user.recently_sent_password_reset?).to eq true
    end
  end

279 280 281 282 283 284 285
  describe '#disable_two_factor!' do
    it 'clears all 2FA-related fields' do
      user = create(:user, :two_factor)

      expect(user).to be_two_factor_enabled
      expect(user.encrypted_otp_secret).not_to be_nil
      expect(user.otp_backup_codes).not_to be_nil
286
      expect(user.otp_grace_period_started_at).not_to be_nil
287 288 289 290 291 292 293 294

      user.disable_two_factor!

      expect(user).not_to be_two_factor_enabled
      expect(user.encrypted_otp_secret).to be_nil
      expect(user.encrypted_otp_secret_iv).to be_nil
      expect(user.encrypted_otp_secret_salt).to be_nil
      expect(user.otp_backup_codes).to be_nil
295
      expect(user.otp_grace_period_started_at).to be_nil
296 297 298
    end
  end

299 300 301 302
  describe 'projects' do
    before do
      @user = create :user
      @project = create :project, namespace: @user.namespace
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
303 304
      @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
305

306 307
      @project_2.team << [@user, :master]
      @project_3.team << [@user, :developer]
308 309
    end

310 311 312 313 314 315 316 317 318
    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) }
319 320 321 322 323
  end

  describe 'groups' do
    before do
      @user = create :user
324 325
      @group = create :group
      @group.add_owner(@user)
326 327
    end

328 329 330
    it { expect(@user.several_namespaces?).to be_truthy }
    it { expect(@user.authorized_groups).to eq([@group]) }
    it { expect(@user.owned_groups).to eq([@group]) }
331
    it { expect(@user.namespaces).to match_array([@user.namespace, @group]) }
332 333
  end

334 335 336 337
  describe 'group multiple owners' do
    before do
      @user = create :user
      @user2 = create :user
338 339
      @group = create :group
      @group.add_owner(@user)
340

341
      @group.add_user(@user2, GroupMember::OWNER)
342 343
    end

344
    it { expect(@user2.several_namespaces?).to be_truthy }
345 346
  end

347 348 349 350 351 352
  describe 'namespaced' do
    before do
      @user = create :user
      @project = create :project, namespace: @user.namespace
    end

353
    it { expect(@user.several_namespaces?).to be_falsey }
354
    it { expect(@user.namespaces).to eq([@user.namespace]) }
355 356 357 358 359 360 361
  end

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

    it "should block user" do
      user.block
362
      expect(user.blocked?).to be_truthy
363 364 365
    end
  end

366 367 368 369 370 371 372
  describe '.filter' do
    let(:user) { double }

    it 'filters by active users by default' do
      expect(User).to receive(:active).and_return([user])

      expect(User.filter(nil)).to include user
373 374
    end

375 376 377 378
    it 'filters by admins' do
      expect(User).to receive(:admins).and_return([user])

      expect(User.filter('admins')).to include user
379 380
    end

381 382 383 384 385 386 387 388 389 390
    it 'filters by blocked' do
      expect(User).to receive(:blocked).and_return([user])

      expect(User.filter('blocked')).to include user
    end

    it 'filters by two_factor_disabled' do
      expect(User).to receive(:without_two_factor).and_return([user])

      expect(User.filter('two_factor_disabled')).to include user
391 392
    end

393 394 395 396 397 398 399 400 401 402 403
    it 'filters by two_factor_enabled' do
      expect(User).to receive(:with_two_factor).and_return([user])

      expect(User.filter('two_factor_enabled')).to include user
    end

    it 'filters by wop' do
      expect(User).to receive(:without_projects).and_return([user])

      expect(User.filter('wop')).to include user
    end
404 405 406 407
  end

  describe :not_in_project do
    before do
408
      User.delete_all
409 410 411 412
      @user = create :user
      @project = create :project
    end

413
    it { expect(User.not_in_project(@project)).to include(@user, @project.owner) }
414
  end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
415

416 417 418
  describe 'user creation' do
    describe 'normal user' do
      let(:user) { create(:user, name: 'John Smith') }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
419

420 421 422 423 424
      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') }
425
    end
426

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
427
    describe 'with defaults' do
428
      let(:user) { User.new }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
429

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
430
      it "should apply defaults to user" do
431 432 433
        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)
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
434
        expect(user.external).to be_falsey
435 436 437
      end
    end

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
438
    describe 'with default overrides' do
439
      let(:user) { User.new(projects_limit: 123, can_create_group: false, can_create_team: true, theme_id: 1) }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
440

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
441
      it "should apply defaults to user" do
442 443
        expect(user.projects_limit).to eq(123)
        expect(user.can_create_group).to be_falsey
444
        expect(user.theme_id).to eq(1)
445
      end
446 447
    end
  end
448

449
  describe '.find_by_any_email' do
450 451 452
    it 'finds by primary email' do
      user = create(:user, email: 'foo@example.com')

453
      expect(User.find_by_any_email(user.email)).to eq user
454 455 456 457 458 459
    end

    it 'finds by secondary email' do
      email = create(:email, email: 'foo@example.com')
      user  = email.user

460
      expect(User.find_by_any_email(email.email)).to eq user
461 462 463
    end

    it 'returns nil when nothing found' do
464
      expect(User.find_by_any_email('')).to be_nil
465 466 467
    end
  end

468 469 470 471 472 473 474 475 476 477 478
  describe '.search' do
    let(:user) { create(:user) }

    it 'returns users with a matching name' do
      expect(described_class.search(user.name)).to eq([user])
    end

    it 'returns users with a partially matching name' do
      expect(described_class.search(user.name[0..2])).to eq([user])
    end

Yorick Peterse's avatar
Yorick Peterse committed
479
    it 'returns users with a matching name regardless of the casing' do
480 481 482 483 484 485 486 487 488 489 490
      expect(described_class.search(user.name.upcase)).to eq([user])
    end

    it 'returns users with a matching Email' do
      expect(described_class.search(user.email)).to eq([user])
    end

    it 'returns users with a partially matching Email' do
      expect(described_class.search(user.email[0..2])).to eq([user])
    end

Yorick Peterse's avatar
Yorick Peterse committed
491
    it 'returns users with a matching Email regardless of the casing' do
492 493 494 495 496 497 498 499 500 501 502
      expect(described_class.search(user.email.upcase)).to eq([user])
    end

    it 'returns users with a matching username' do
      expect(described_class.search(user.username)).to eq([user])
    end

    it 'returns users with a partially matching username' do
      expect(described_class.search(user.username[0..2])).to eq([user])
    end

Yorick Peterse's avatar
Yorick Peterse committed
503
    it 'returns users with a matching username regardless of the casing' do
504
      expect(described_class.search(user.username.upcase)).to eq([user])
505 506 507
    end
  end

508
  describe 'by_username_or_id' do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
509 510
    let(:user1) { create(:user, username: 'foo') }

511
    it "should get the correct user" do
512 513 514 515
      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
516 517
    end
  end
518

519 520 521 522 523 524 525 526 527 528 529 530 531 532
  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

533 534 535 536 537 538 539 540 541 542 543 544
  describe '.find_by_username!' do
    it 'raises RecordNotFound' do
      expect { described_class.find_by_username!('JohnDoe') }.
        to raise_error(ActiveRecord::RecordNotFound)
    end

    it 'is case-insensitive' do
      user = create(:user, username: 'JohnDoe')
      expect(described_class.find_by_username!('JOHNDOE')).to eq user
    end
  end

545
  describe 'all_ssh_keys' do
546
    it { is_expected.to have_many(:keys).dependent(:destroy) }
547 548 549 550 551

    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

552
      expect(user.all_ssh_keys).to include(key.key)
553
    end
554
  end
555

556 557 558 559 560
  describe :avatar_type do
    let(:user) { create(:user) }

    it "should be true if avatar is image" do
      user.update_attribute(:avatar, 'uploads/avatar.png')
561
      expect(user.avatar_type).to be_truthy
562 563 564 565
    end

    it "should be false if avatar is html page" do
      user.update_attribute(:avatar, 'uploads/avatar.html')
566
      expect(user.avatar_type).to eq(["only images allowed"])
567 568
    end
  end
Jerome Dalbert's avatar
Jerome Dalbert committed
569

570 571 572
  describe :requires_ldap_check? do
    let(:user) { User.new }

573 574
    it 'is false when LDAP is disabled' do
      # Create a condition which would otherwise cause 'true' to be returned
575
      allow(user).to receive(:ldap_user?).and_return(true)
576
      user.last_credential_check_at = nil
577
      expect(user.requires_ldap_check?).to be_falsey
578 579
    end

580
    context 'when LDAP is enabled' do
581 582 583
      before do
        allow(Gitlab.config.ldap).to receive(:enabled).and_return(true)
      end
584

585
      it 'is false for non-LDAP users' do
586
        allow(user).to receive(:ldap_user?).and_return(false)
587
        expect(user.requires_ldap_check?).to be_falsey
588 589
      end

590
      context 'and when the user is an LDAP user' do
591 592 593
        before do
          allow(user).to receive(:ldap_user?).and_return(true)
        end
594 595 596

        it 'is true when the user has never had an LDAP check before' do
          user.last_credential_check_at = nil
597
          expect(user.requires_ldap_check?).to be_truthy
598 599 600 601
        end

        it 'is true when the last LDAP check happened over 1 hour ago' do
          user.last_credential_check_at = 2.hours.ago
602
          expect(user.requires_ldap_check?).to be_truthy
603
        end
604 605 606 607
      end
    end
  end

608 609 610 611 612 613
  context 'ldap synchronized user' do
    describe :ldap_user? do
      it 'is true if provider name starts with ldap' do
        user = create(:omniauth_user, provider: 'ldapmain')
        expect(user.ldap_user?).to be_truthy
      end
614

615 616 617 618 619 620 621 622 623
      it 'is false for other providers' do
        user = create(:omniauth_user, provider: 'other-provider')
        expect(user.ldap_user?).to be_falsey
      end

      it 'is false if no extern_uid is provided' do
        user = create(:omniauth_user, extern_uid: nil)
        expect(user.ldap_user?).to be_falsey
      end
624 625
    end

626 627 628 629 630
    describe :ldap_identity do
      it 'returns ldap identity' do
        user = create :omniauth_user
        expect(user.ldap_identity.provider).not_to be_empty
      end
631 632
    end

633 634 635 636 637 638 639 640
    describe '#ldap_block' do
      let(:user) { create(:omniauth_user, provider: 'ldapmain', name: 'John Smith') }

      it 'blocks user flaging the action caming from ldap' do
        user.ldap_block
        expect(user.blocked?).to be_truthy
        expect(user.ldap_blocked?).to be_truthy
      end
641 642 643
    end
  end

Jerome Dalbert's avatar
Jerome Dalbert committed
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
  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'
683

Jerome Dalbert's avatar
Jerome Dalbert committed
684 685
      expect(user.short_website_url).to eq 'test.com'
    end
686
  end
Ciro Santilli's avatar
Ciro Santilli committed
687

688 689 690 691 692 693
  describe "#starred?" do
    it "determines if user starred a project" do
      user = create :user
      project1 = create :project, :public
      project2 = create :project, :public

694 695
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_falsey
696 697

      star1 = UsersStarProject.create!(project: project1, user: user)
698 699
      expect(user.starred?(project1)).to be_truthy
      expect(user.starred?(project2)).to be_falsey
700 701

      star2 = UsersStarProject.create!(project: project2, user: user)
702 703
      expect(user.starred?(project1)).to be_truthy
      expect(user.starred?(project2)).to be_truthy
704 705

      star1.destroy
706 707
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_truthy
708 709

      star2.destroy
710 711
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_falsey
712 713 714
    end
  end

Ciro Santilli's avatar
Ciro Santilli committed
715 716 717 718 719
  describe "#toggle_star" do
    it "toggles stars" do
      user = create :user
      project = create :project, :public

720
      expect(user.starred?(project)).to be_falsey
Ciro Santilli's avatar
Ciro Santilli committed
721
      user.toggle_star(project)
722
      expect(user.starred?(project)).to be_truthy
Ciro Santilli's avatar
Ciro Santilli committed
723
      user.toggle_star(project)
724
      expect(user.starred?(project)).to be_falsey
Ciro Santilli's avatar
Ciro Santilli committed
725 726
    end
  end
Valery Sizov's avatar
Valery Sizov committed
727

728 729 730 731
  describe "#existing_member?" do
    it "returns true for exisitng user" do
      create :user, email: "bruno@example.com"

732
      expect(User.existing_member?("bruno@example.com")).to be_truthy
733 734 735 736 737
    end

    it "returns false for unknown exisitng user" do
      create :user, email: "bruno@example.com"

738
      expect(User.existing_member?("rendom@example.com")).to be_falsey
739 740 741 742 743 744
    end

    it "returns true if additional email exists" do
      user = create :user
      user.emails.create(email: "bruno@example.com")

745
      expect(User.existing_member?("bruno@example.com")).to be_truthy
746 747 748
    end
  end

Valery Sizov's avatar
Valery Sizov committed
749 750 751 752 753 754
  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
755

Yorick Peterse's avatar
Yorick Peterse committed
756
    it "sorts users by the recent sign-in time" do
757
      expect(User.sort('recent_sign_in').first).to eq(@user)
Valery Sizov's avatar
Valery Sizov committed
758 759
    end

Yorick Peterse's avatar
Yorick Peterse committed
760
    it "sorts users by the oldest sign-in time" do
761
      expect(User.sort('oldest_sign_in').first).to eq(@user1)
Valery Sizov's avatar
Valery Sizov committed
762 763
    end

Yorick Peterse's avatar
Yorick Peterse committed
764
    it "sorts users in descending order by their creation time" do
765
      expect(User.sort('created_desc').first).to eq(@user)
Valery Sizov's avatar
Valery Sizov committed
766 767
    end

Yorick Peterse's avatar
Yorick Peterse committed
768
    it "sorts users in ascending order by their creation time" do
769
      expect(User.sort('created_asc').first).to eq(@user1)
Valery Sizov's avatar
Valery Sizov committed
770 771
    end

Yorick Peterse's avatar
Yorick Peterse committed
772 773
    it "sorts users by id in descending order when nil is passed" do
      expect(User.sort(nil).first).to eq(@user1)
Valery Sizov's avatar
Valery Sizov committed
774 775
    end
  end
776

777
  describe "#contributed_projects" do
778 779 780 781 782 783 784 785 786 787 788 789 790 791
    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
792
      expect(subject.contributed_projects).to include(project1)
793 794 795
    end

    it "includes IDs for projects the user has had merge requests merged into" do
796
      expect(subject.contributed_projects).to include(project3)
797 798 799
    end

    it "doesn't include IDs for unrelated projects" do
800
      expect(subject.contributed_projects).not_to include(project2)
801 802
    end
  end
803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819

  describe :can_be_removed? do
    subject { create(:user) }

    context 'no owned groups' do
      it { expect(subject.can_be_removed?).to be_truthy }
    end

    context 'has owned groups' do
      before do
        group = create(:group)
        group.add_owner(subject)
      end

      it { expect(subject.can_be_removed?).to be_falsey }
    end
  end
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848

  describe "#recent_push" do
    subject { create(:user) }
    let!(:project1) { create(:project) }
    let!(:project2) { create(:project, forked_from_project: project1) }
    let!(:push_data) { Gitlab::PushDataBuilder.build_sample(project2, subject) }
    let!(:push_event) { create(:event, action: Event::PUSHED, project: project2, target: project1, author: subject, data: push_data) }

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

    it "includes push event" do
      expect(subject.recent_push).to eq(push_event)
    end

    it "excludes push event if branch has been deleted" do
      allow_any_instance_of(Repository).to receive(:branch_names).and_return(['foo'])

      expect(subject.recent_push).to eq(nil)
    end

    it "excludes push event if MR is opened for it" do
      create(:merge_request, source_project: project2, target_project: project1, source_branch: project2.default_branch, target_branch: 'fix', author: subject)

      expect(subject.recent_push).to eq(nil)
    end
  end
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874

  describe '#authorized_groups' do
    let!(:user) { create(:user) }
    let!(:private_group) { create(:group) }

    before do
      private_group.add_user(user, Gitlab::Access::MASTER)
    end

    subject { user.authorized_groups }

    it { is_expected.to eq([private_group]) }
  end

  describe '#authorized_projects' do
    let!(:user) { create(:user) }
    let!(:private_project) { create(:project, :private) }

    before do
      private_project.team << [user, Gitlab::Access::MASTER]
    end

    subject { user.authorized_projects }

    it { is_expected.to eq([private_project]) }
  end
gitlabhq's avatar
gitlabhq committed
875
end