user_spec.rb 25.2 KB
Newer Older
D
Dmitriy Zaporozhets 已提交
1 2 3 4
# == Schema Information
#
# Table name: users
#
S
Stan Hu 已提交
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
#  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)
D
Dmitriy Zaporozhets 已提交
57 58
#  consumed_timestep          :integer
#  layout                     :integer          default(0)
D
Dmitriy Zaporozhets 已提交
59 60
#

G
gitlabhq 已提交
61 62 63
require 'spec_helper'

describe User do
64 65
  include Gitlab::CurrentSettings

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

  describe 'validations' do
94 95 96 97 98
    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) }
99

100
    it { is_expected.to validate_length_of(:bio).is_within(0..255) }
101 102 103 104 105 106

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

108 109 110 111 112
      it 'accepts info+test@example.com' do
        user = build(:user, email: 'info+test@example.com')
        expect(user).to be_valid
      end

113 114 115 116 117
      it "accepts o'reilly@example.com" do
        user = build(:user, email: "o'reilly@example.com")
        expect(user).to be_valid
      end

118 119 120 121 122 123 124 125 126
      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
127 128 129 130 131

      it "rejects lol!'+=?><#$%^&*()@gmail.com" do
        user = build(:user, email: "lol!'+=?><#$%^&*()@gmail.com")
        expect(user).to be_invalid
      end
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 176

      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
177
    end
G
gitlabhq 已提交
178 179 180
  end

  describe "Respond to" do
181 182 183
    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 已提交
184 185
  end

186 187 188 189 190 191 192 193
  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
194
      user.confirm
195 196 197 198
      expect(user.confirmed?).to be_truthy
    end
  end

199 200 201 202 203 204 205 206
  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

207 208 209
  describe '#generate_password' do
    it "should execute callback when force_random_password specified" do
      user = build(:user, force_random_password: true)
210
      expect(user).to receive(:generate_password)
211 212 213 214
      user.save
    end

    it "should not generate password by default" do
215
      user = create(:user, password: 'abcdefghe')
216
      expect(user.password).to eq('abcdefghe')
217
    end
218

219
    it "should generate password when forcing random password" do
220
      allow(Devise).to receive(:friendly_token).and_return('123456789')
221
      user = create(:user, password: 'abcdefg', force_random_password: true)
222
      expect(user.password).to eq('12345678')
223
    end
224 225
  end

226 227
  describe 'authentication token' do
    it "should have authentication token" do
228
      user = create(:user)
229
      expect(user.authentication_token).not_to be_blank
230
    end
N
Nihad Abbasov 已提交
231
  end
232

233
  describe '#recently_sent_password_reset?' do
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
    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

R
Robert Speicher 已提交
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
  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

271 272 273 274
  describe 'projects' do
    before do
      @user = create :user
      @project = create :project, namespace: @user.namespace
D
Dmitriy Zaporozhets 已提交
275 276
      @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
277

278 279
      @project_2.team << [@user, :master]
      @project_3.team << [@user, :developer]
280 281
    end

282 283 284 285 286 287 288 289 290
    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) }
291 292 293 294 295
  end

  describe 'groups' do
    before do
      @user = create :user
296 297
      @group = create :group
      @group.add_owner(@user)
298 299
    end

300 301 302
    it { expect(@user.several_namespaces?).to be_truthy }
    it { expect(@user.authorized_groups).to eq([@group]) }
    it { expect(@user.owned_groups).to eq([@group]) }
303
    it { expect(@user.namespaces).to match_array([@user.namespace, @group]) }
304 305
  end

306 307 308 309
  describe 'group multiple owners' do
    before do
      @user = create :user
      @user2 = create :user
310 311
      @group = create :group
      @group.add_owner(@user)
312

313
      @group.add_user(@user2, GroupMember::OWNER)
314 315
    end

316
    it { expect(@user2.several_namespaces?).to be_truthy }
317 318
  end

319 320 321 322 323 324
  describe 'namespaced' do
    before do
      @user = create :user
      @project = create :project, namespace: @user.namespace
    end

325
    it { expect(@user.several_namespaces?).to be_falsey }
326
    it { expect(@user.namespaces).to eq([@user.namespace]) }
327 328 329 330 331 332 333
  end

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

    it "should block user" do
      user.block
334
      expect(user.blocked?).to be_truthy
335 336 337
    end
  end

338 339 340 341 342 343 344
  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
345 346
    end

347 348 349 350
    it 'filters by admins' do
      expect(User).to receive(:admins).and_return([user])

      expect(User.filter('admins')).to include user
351 352
    end

353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
    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
376 377 378 379
  end

  describe :not_in_project do
    before do
380
      User.delete_all
381 382 383 384
      @user = create :user
      @project = create :project
    end

385
    it { expect(User.not_in_project(@project)).to include(@user, @project.owner) }
386
  end
D
Dmitriy Zaporozhets 已提交
387

388 389 390
  describe 'user creation' do
    describe 'normal user' do
      let(:user) { create(:user, name: 'John Smith') }
D
Dmitriy Zaporozhets 已提交
391

392 393 394 395 396
      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') }
397
    end
398

D
Dmitriy Zaporozhets 已提交
399
    describe 'with defaults' do
400
      let(:user) { User.new }
D
Dmitriy Zaporozhets 已提交
401

D
Dmitriy Zaporozhets 已提交
402
      it "should apply defaults to user" do
403 404 405
        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)
406 407 408
      end
    end

D
Dmitriy Zaporozhets 已提交
409
    describe 'with default overrides' do
410
      let(:user) { User.new(projects_limit: 123, can_create_group: false, can_create_team: true, theme_id: 1) }
D
Dmitriy Zaporozhets 已提交
411

D
Dmitriy Zaporozhets 已提交
412
      it "should apply defaults to user" do
413 414
        expect(user.projects_limit).to eq(123)
        expect(user.can_create_group).to be_falsey
415
        expect(user.theme_id).to eq(1)
416
      end
417 418
    end
  end
419

420
  describe '.find_by_any_email' do
421 422 423
    it 'finds by primary email' do
      user = create(:user, email: 'foo@example.com')

424
      expect(User.find_by_any_email(user.email)).to eq user
425 426 427 428 429 430
    end

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

431
      expect(User.find_by_any_email(email.email)).to eq user
432 433 434
    end

    it 'returns nil when nothing found' do
435
      expect(User.find_by_any_email('')).to be_nil
436 437 438
    end
  end

M
Marin Jankovski 已提交
439 440 441 442 443
  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
444 445 446 447 448 449
      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 已提交
450 451 452
    end
  end

453
  describe 'by_username_or_id' do
D
Dmitriy Zaporozhets 已提交
454 455
    let(:user1) { create(:user, username: 'foo') }

456
    it "should get the correct user" do
457 458 459 460
      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
461 462
    end
  end
G
GitLab 已提交
463

464 465 466 467 468 469 470 471 472 473 474 475 476 477
  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

R
Robert Speicher 已提交
478 479 480 481 482 483 484 485 486 487 488 489
  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

G
GitLab 已提交
490
  describe 'all_ssh_keys' do
491
    it { is_expected.to have_many(:keys).dependent(:destroy) }
G
GitLab 已提交
492 493 494 495 496

    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

497
      expect(user.all_ssh_keys).to include(key.key)
G
GitLab 已提交
498
    end
G
GitLab 已提交
499
  end
500

D
Dmitriy Zaporozhets 已提交
501 502 503 504 505
  describe :avatar_type do
    let(:user) { create(:user) }

    it "should be true if avatar is image" do
      user.update_attribute(:avatar, 'uploads/avatar.png')
506
      expect(user.avatar_type).to be_truthy
D
Dmitriy Zaporozhets 已提交
507 508 509 510
    end

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

515 516 517
  describe :requires_ldap_check? do
    let(:user) { User.new }

518 519
    it 'is false when LDAP is disabled' do
      # Create a condition which would otherwise cause 'true' to be returned
520
      allow(user).to receive(:ldap_user?).and_return(true)
521
      user.last_credential_check_at = nil
522
      expect(user.requires_ldap_check?).to be_falsey
523 524
    end

525
    context 'when LDAP is enabled' do
526 527 528
      before do
        allow(Gitlab.config.ldap).to receive(:enabled).and_return(true)
      end
529

530
      it 'is false for non-LDAP users' do
531
        allow(user).to receive(:ldap_user?).and_return(false)
532
        expect(user.requires_ldap_check?).to be_falsey
533 534
      end

535
      context 'and when the user is an LDAP user' do
536 537 538
        before do
          allow(user).to receive(:ldap_user?).and_return(true)
        end
539 540 541

        it 'is true when the user has never had an LDAP check before' do
          user.last_credential_check_at = nil
542
          expect(user.requires_ldap_check?).to be_truthy
543 544 545 546
        end

        it 'is true when the last LDAP check happened over 1 hour ago' do
          user.last_credential_check_at = 2.hours.ago
547
          expect(user.requires_ldap_check?).to be_truthy
548
        end
549 550 551 552
      end
    end
  end

553 554
  describe :ldap_user? do
    it "is true if provider name starts with ldap" do
555
      user = create(:omniauth_user, provider: 'ldapmain')
556
      expect( user.ldap_user? ).to be_truthy
557 558 559
    end

    it "is false for other providers" do
560
      user = create(:omniauth_user, provider: 'other-provider')
561
      expect( user.ldap_user? ).to be_falsey
562 563 564
    end

    it "is false if no extern_uid is provided" do
565
      user = create(:omniauth_user, extern_uid: nil)
566
      expect( user.ldap_user? ).to be_falsey
567 568 569
    end
  end

570 571 572
  describe :ldap_identity do
    it "returns ldap identity" do
      user = create :omniauth_user
573
      expect(user.ldap_identity.provider).not_to be_empty
574 575 576
    end
  end

J
Jerome Dalbert 已提交
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
  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'
616

J
Jerome Dalbert 已提交
617 618
      expect(user.short_website_url).to eq 'test.com'
    end
G
GitLab 已提交
619
  end
C
Ciro Santilli 已提交
620

621 622 623 624 625 626
  describe "#starred?" do
    it "determines if user starred a project" do
      user = create :user
      project1 = create :project, :public
      project2 = create :project, :public

627 628
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_falsey
629 630

      star1 = UsersStarProject.create!(project: project1, user: user)
631 632
      expect(user.starred?(project1)).to be_truthy
      expect(user.starred?(project2)).to be_falsey
633 634

      star2 = UsersStarProject.create!(project: project2, user: user)
635 636
      expect(user.starred?(project1)).to be_truthy
      expect(user.starred?(project2)).to be_truthy
637 638

      star1.destroy
639 640
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_truthy
641 642

      star2.destroy
643 644
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_falsey
645 646 647
    end
  end

C
Ciro Santilli 已提交
648 649 650 651 652
  describe "#toggle_star" do
    it "toggles stars" do
      user = create :user
      project = create :project, :public

653
      expect(user.starred?(project)).to be_falsey
C
Ciro Santilli 已提交
654
      user.toggle_star(project)
655
      expect(user.starred?(project)).to be_truthy
C
Ciro Santilli 已提交
656
      user.toggle_star(project)
657
      expect(user.starred?(project)).to be_falsey
C
Ciro Santilli 已提交
658 659
    end
  end
V
Valery Sizov 已提交
660 661 662 663 664 665 666

  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
667

Y
Yorick Peterse 已提交
668
    it "sorts users by the recent sign-in time" do
669
      expect(User.sort('recent_sign_in').first).to eq(@user)
V
Valery Sizov 已提交
670 671
    end

Y
Yorick Peterse 已提交
672
    it "sorts users by the oldest sign-in time" do
673
      expect(User.sort('oldest_sign_in').first).to eq(@user1)
V
Valery Sizov 已提交
674 675
    end

Y
Yorick Peterse 已提交
676
    it "sorts users in descending order by their creation time" do
677
      expect(User.sort('created_desc').first).to eq(@user)
V
Valery Sizov 已提交
678 679
    end

Y
Yorick Peterse 已提交
680
    it "sorts users in ascending order by their creation time" do
681
      expect(User.sort('created_asc').first).to eq(@user1)
V
Valery Sizov 已提交
682 683
    end

Y
Yorick Peterse 已提交
684 685
    it "sorts users by id in descending order when nil is passed" do
      expect(User.sort(nil).first).to eq(@user1)
V
Valery Sizov 已提交
686 687
    end
  end
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714

  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
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731

  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
732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760

  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
G
gitlabhq 已提交
761
end