GitLab steht wegen Wartungsarbeiten am Montag, den 10. Mai, zwischen 17:00 und 19:00 Uhr nicht zur Verfügung.

user_spec.rb 26.3 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
#  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
Drew Blessing's avatar
Drew Blessing committed
29
#  unlock_token               :string(255)
Stan Hu's avatar
Stan Hu committed
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
#  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)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
58 59
#  consumed_timestep          :integer
#  layout                     :integer          default(0)
Stan Hu's avatar
Stan Hu committed
60
#  hide_project_limit         :boolean          default(FALSE)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
61 62
#

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

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

68 69 70 71 72 73 74 75 76 77 78
  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
79 80 81 82 83 84 85 86 87 88 89 90 91
    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) }
92
    it { is_expected.to have_one(:abuse_report) }
93 94 95
  end

  describe 'validations' do
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
    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
        expect(subject).to validate_uniqueness_of(:username)
      end
    end

113 114 115 116
    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) }
117

118
    it { is_expected.to validate_length_of(:bio).is_within(0..255) }
119 120 121 122 123 124

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

126 127 128 129 130
      it 'accepts info+test@example.com' do
        user = build(:user, email: 'info+test@example.com')
        expect(user).to be_valid
      end

131 132 133 134 135
      it "accepts o'reilly@example.com" do
        user = build(:user, email: "o'reilly@example.com")
        expect(user).to be_valid
      end

136 137 138 139 140 141 142 143 144
      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
145 146 147 148 149

      it "rejects lol!'+=?><#$%^&*()@gmail.com" do
        user = build(:user, email: "lol!'+=?><#$%^&*()@gmail.com")
        expect(user).to be_invalid
      end
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 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194

      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
195
    end
gitlabhq's avatar
gitlabhq committed
196 197 198
  end

  describe "Respond to" do
199 200 201
    it { is_expected.to respond_to(:is_admin?) }
    it { is_expected.to respond_to(:name) }
    it { is_expected.to respond_to(:private_token) }
gitlabhq's avatar
gitlabhq committed
202 203
  end

204 205 206 207 208 209 210 211
  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
212
      user.confirm
213 214 215 216
      expect(user.confirmed?).to be_truthy
    end
  end

217 218 219 220 221 222 223 224
  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

225 226 227
  describe '#generate_password' do
    it "should execute callback when force_random_password specified" do
      user = build(:user, force_random_password: true)
228
      expect(user).to receive(:generate_password)
229 230 231 232
      user.save
    end

    it "should not generate password by default" do
233
      user = create(:user, password: 'abcdefghe')
234
      expect(user.password).to eq('abcdefghe')
235
    end
236

237
    it "should generate password when forcing random password" do
238
      allow(Devise).to receive(:friendly_token).and_return('123456789')
239
      user = create(:user, password: 'abcdefg', force_random_password: true)
240
      expect(user.password).to eq('12345678')
241
    end
242 243
  end

244 245
  describe 'authentication token' do
    it "should have authentication token" do
246
      user = create(:user)
247
      expect(user.authentication_token).not_to be_blank
248
    end
Nihad Abbasov's avatar
Nihad Abbasov committed
249
  end
250

251
  describe '#recently_sent_password_reset?' do
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
    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

Robert Speicher's avatar
Robert Speicher committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
  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

      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
    end
  end

289 290 291 292
  describe 'projects' do
    before do
      @user = create :user
      @project = create :project, namespace: @user.namespace
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
293 294
      @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
295

296 297
      @project_2.team << [@user, :master]
      @project_3.team << [@user, :developer]
298 299
    end

300 301 302 303 304 305 306 307 308
    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) }
309 310 311 312 313
  end

  describe 'groups' do
    before do
      @user = create :user
314 315
      @group = create :group
      @group.add_owner(@user)
316 317
    end

318 319 320
    it { expect(@user.several_namespaces?).to be_truthy }
    it { expect(@user.authorized_groups).to eq([@group]) }
    it { expect(@user.owned_groups).to eq([@group]) }
321
    it { expect(@user.namespaces).to match_array([@user.namespace, @group]) }
322 323
  end

324 325 326 327
  describe 'group multiple owners' do
    before do
      @user = create :user
      @user2 = create :user
328 329
      @group = create :group
      @group.add_owner(@user)
330

331
      @group.add_user(@user2, GroupMember::OWNER)
332 333
    end

334
    it { expect(@user2.several_namespaces?).to be_truthy }
335 336
  end

337 338 339 340 341 342
  describe 'namespaced' do
    before do
      @user = create :user
      @project = create :project, namespace: @user.namespace
    end

343
    it { expect(@user.several_namespaces?).to be_falsey }
344
    it { expect(@user.namespaces).to eq([@user.namespace]) }
345 346 347 348 349 350 351
  end

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

    it "should block user" do
      user.block
352
      expect(user.blocked?).to be_truthy
353 354 355
    end
  end

356 357 358 359 360 361 362
  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
363 364
    end

365 366 367 368
    it 'filters by admins' do
      expect(User).to receive(:admins).and_return([user])

      expect(User.filter('admins')).to include user
369 370
    end

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
    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
    end

    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
394 395 396 397
  end

  describe :not_in_project do
    before do
398
      User.delete_all
399 400 401 402
      @user = create :user
      @project = create :project
    end

403
    it { expect(User.not_in_project(@project)).to include(@user, @project.owner) }
404
  end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
405

406 407 408
  describe 'user creation' do
    describe 'normal user' do
      let(:user) { create(:user, name: 'John Smith') }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
409

410 411 412 413 414
      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') }
415
    end
416

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
417
    describe 'with defaults' do
418
      let(:user) { User.new }
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
419

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
420
      it "should apply defaults to user" do
421 422 423
        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)
424 425 426
      end
    end

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
427
    describe 'with default overrides' do
428
      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
429

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
430
      it "should apply defaults to user" do
431 432
        expect(user.projects_limit).to eq(123)
        expect(user.can_create_group).to be_falsey
433
        expect(user.theme_id).to eq(1)
434
      end
435 436
    end
  end
437

438
  describe '.find_by_any_email' do
439 440 441
    it 'finds by primary email' do
      user = create(:user, email: 'foo@example.com')

442
      expect(User.find_by_any_email(user.email)).to eq user
443 444 445 446 447 448
    end

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

449
      expect(User.find_by_any_email(email.email)).to eq user
450 451 452
    end

    it 'returns nil when nothing found' do
453
      expect(User.find_by_any_email('')).to be_nil
454 455 456
    end
  end

457 458 459 460 461
  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
462 463 464 465 466 467
      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)
468 469 470
    end
  end

471
  describe 'by_username_or_id' do
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
472 473
    let(:user1) { create(:user, username: 'foo') }

474
    it "should get the correct user" do
475 476 477 478
      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
479 480
    end
  end
GitLab's avatar
GitLab committed
481

482 483 484 485 486 487 488 489 490 491 492 493 494 495
  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

Robert Speicher's avatar
Robert Speicher committed
496 497 498 499 500 501 502 503 504 505 506 507
  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

GitLab's avatar
GitLab committed
508
  describe 'all_ssh_keys' do
509
    it { is_expected.to have_many(:keys).dependent(:destroy) }
GitLab's avatar
GitLab committed
510 511 512 513 514

    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

515
      expect(user.all_ssh_keys).to include(key.key)
GitLab's avatar
GitLab committed
516
    end
GitLab's avatar
GitLab committed
517
  end
518

519 520 521 522 523
  describe :avatar_type do
    let(:user) { create(:user) }

    it "should be true if avatar is image" do
      user.update_attribute(:avatar, 'uploads/avatar.png')
524
      expect(user.avatar_type).to be_truthy
525 526 527 528
    end

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

533 534 535
  describe :requires_ldap_check? do
    let(:user) { User.new }

536 537
    it 'is false when LDAP is disabled' do
      # Create a condition which would otherwise cause 'true' to be returned
538
      allow(user).to receive(:ldap_user?).and_return(true)
539
      user.last_credential_check_at = nil
540
      expect(user.requires_ldap_check?).to be_falsey
541 542
    end

543
    context 'when LDAP is enabled' do
544 545 546
      before do
        allow(Gitlab.config.ldap).to receive(:enabled).and_return(true)
      end
547

548
      it 'is false for non-LDAP users' do
549
        allow(user).to receive(:ldap_user?).and_return(false)
550
        expect(user.requires_ldap_check?).to be_falsey
551 552
      end

553
      context 'and when the user is an LDAP user' do
554 555 556
        before do
          allow(user).to receive(:ldap_user?).and_return(true)
        end
557 558 559

        it 'is true when the user has never had an LDAP check before' do
          user.last_credential_check_at = nil
560
          expect(user.requires_ldap_check?).to be_truthy
561 562 563 564
        end

        it 'is true when the last LDAP check happened over 1 hour ago' do
          user.last_credential_check_at = 2.hours.ago
565
          expect(user.requires_ldap_check?).to be_truthy
566
        end
567 568 569 570
      end
    end
  end

571 572
  describe :ldap_user? do
    it "is true if provider name starts with ldap" do
573
      user = create(:omniauth_user, provider: 'ldapmain')
574
      expect( user.ldap_user? ).to be_truthy
575 576 577
    end

    it "is false for other providers" do
578
      user = create(:omniauth_user, provider: 'other-provider')
579
      expect( user.ldap_user? ).to be_falsey
580 581 582
    end

    it "is false if no extern_uid is provided" do
583
      user = create(:omniauth_user, extern_uid: nil)
584
      expect( user.ldap_user? ).to be_falsey
585 586 587
    end
  end

588 589 590
  describe :ldap_identity do
    it "returns ldap identity" do
      user = create :omniauth_user
591
      expect(user.ldap_identity.provider).not_to be_empty
592 593 594
    end
  end

Jerome Dalbert's avatar
Jerome Dalbert committed
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
  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'
634

Jerome Dalbert's avatar
Jerome Dalbert committed
635 636
      expect(user.short_website_url).to eq 'test.com'
    end
GitLab's avatar
GitLab committed
637
  end
Ciro Santilli's avatar
Ciro Santilli committed
638

639 640 641 642 643 644
  describe "#starred?" do
    it "determines if user starred a project" do
      user = create :user
      project1 = create :project, :public
      project2 = create :project, :public

645 646
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_falsey
647 648

      star1 = UsersStarProject.create!(project: project1, user: user)
649 650
      expect(user.starred?(project1)).to be_truthy
      expect(user.starred?(project2)).to be_falsey
651 652

      star2 = UsersStarProject.create!(project: project2, user: user)
653 654
      expect(user.starred?(project1)).to be_truthy
      expect(user.starred?(project2)).to be_truthy
655 656

      star1.destroy
657 658
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_truthy
659 660

      star2.destroy
661 662
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_falsey
663 664 665
    end
  end

Ciro Santilli's avatar
Ciro Santilli committed
666 667 668 669 670
  describe "#toggle_star" do
    it "toggles stars" do
      user = create :user
      project = create :project, :public

671
      expect(user.starred?(project)).to be_falsey
Ciro Santilli's avatar
Ciro Santilli committed
672
      user.toggle_star(project)
673
      expect(user.starred?(project)).to be_truthy
Ciro Santilli's avatar
Ciro Santilli committed
674
      user.toggle_star(project)
675
      expect(user.starred?(project)).to be_falsey
Ciro Santilli's avatar
Ciro Santilli committed
676 677
    end
  end
Valery Sizov's avatar
Valery Sizov committed
678 679 680 681 682 683 684

  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
685

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

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

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

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

Yorick Peterse's avatar
Yorick Peterse committed
702 703
    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
704 705
    end
  end
706

707
  describe "#contributed_projects" do
708 709 710 711 712 713 714 715 716 717 718 719 720 721
    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
722
      expect(subject.contributed_projects).to include(project1)
723 724 725
    end

    it "includes IDs for projects the user has had merge requests merged into" do
726
      expect(subject.contributed_projects).to include(project3)
727 728 729
    end

    it "doesn't include IDs for unrelated projects" do
730
      expect(subject.contributed_projects).not_to include(project2)
731 732
    end
  end
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749

  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
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778

  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
779 780 781 782 783 784 785 786 787

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

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

788
    subject { user.authorized_groups }
789

790
    it { is_expected.to eq([private_group]) }
791 792 793 794 795 796 797 798 799 800
  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

801
    subject { user.authorized_projects }
802

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