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

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

describe User do
65 66
  include Gitlab::CurrentSettings

67 68 69 70 71 72 73 74 75 76 77
  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
78 79 80 81 82 83 84 85 86 87 88 89 90
    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) }
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 '#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

194 195 196
  describe '#generate_password' do
    it "should execute callback when force_random_password specified" do
      user = build(:user, force_random_password: true)
197
      expect(user).to receive(:generate_password)
198 199 200 201
      user.save
    end

    it "should not generate password by default" do
202
      user = create(:user, password: 'abcdefghe')
203
      expect(user.password).to eq('abcdefghe')
204
    end
205

206
    it "should generate password when forcing random password" do
207
      allow(Devise).to receive(:friendly_token).and_return('123456789')
208
      user = create(:user, password: 'abcdefg', force_random_password: true)
209
      expect(user.password).to eq('12345678')
210
    end
211 212
  end

213 214
  describe 'authentication token' do
    it "should have authentication token" do
215
      user = create(:user)
216
      expect(user.authentication_token).not_to be_blank
217
    end
N
Nihad Abbasov 已提交
218
  end
219 220 221 222 223

  describe 'projects' do
    before do
      @user = create :user
      @project = create :project, namespace: @user.namespace
D
Dmitriy Zaporozhets 已提交
224 225
      @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
226

227 228
      @project_2.team << [@user, :master]
      @project_3.team << [@user, :developer]
229 230
    end

231 232 233 234 235 236 237 238 239
    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) }
240 241 242 243 244
  end

  describe 'groups' do
    before do
      @user = create :user
245 246
      @group = create :group
      @group.add_owner(@user)
247 248
    end

249 250 251
    it { expect(@user.several_namespaces?).to be_truthy }
    it { expect(@user.authorized_groups).to eq([@group]) }
    it { expect(@user.owned_groups).to eq([@group]) }
252
    it { expect(@user.namespaces).to match_array([@user.namespace, @group]) }
253 254
  end

255 256 257 258
  describe 'group multiple owners' do
    before do
      @user = create :user
      @user2 = create :user
259 260
      @group = create :group
      @group.add_owner(@user)
261

262
      @group.add_user(@user2, GroupMember::OWNER)
263 264
    end

265
    it { expect(@user2.several_namespaces?).to be_truthy }
266 267
  end

268 269 270 271 272 273
  describe 'namespaced' do
    before do
      @user = create :user
      @project = create :project, namespace: @user.namespace
    end

274
    it { expect(@user.several_namespaces?).to be_falsey }
275
    it { expect(@user.namespaces).to eq([@user.namespace]) }
276 277 278 279 280 281 282
  end

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

    it "should block user" do
      user.block
283
      expect(user.blocked?).to be_truthy
284 285 286
    end
  end

287 288 289 290 291 292 293
  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
294 295
    end

296 297 298 299
    it 'filters by admins' do
      expect(User).to receive(:admins).and_return([user])

      expect(User.filter('admins')).to include user
300 301
    end

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
    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
325 326 327 328
  end

  describe :not_in_project do
    before do
329
      User.delete_all
330 331 332 333
      @user = create :user
      @project = create :project
    end

334
    it { expect(User.not_in_project(@project)).to include(@user, @project.owner) }
335
  end
D
Dmitriy Zaporozhets 已提交
336

337 338 339
  describe 'user creation' do
    describe 'normal user' do
      let(:user) { create(:user, name: 'John Smith') }
D
Dmitriy Zaporozhets 已提交
340

341 342 343 344 345
      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') }
346
    end
347

D
Dmitriy Zaporozhets 已提交
348
    describe 'with defaults' do
349
      let(:user) { User.new }
D
Dmitriy Zaporozhets 已提交
350

D
Dmitriy Zaporozhets 已提交
351
      it "should apply defaults to user" do
352 353 354
        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)
355 356 357
      end
    end

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

D
Dmitriy Zaporozhets 已提交
361
      it "should apply defaults to user" do
362 363
        expect(user.projects_limit).to eq(123)
        expect(user.can_create_group).to be_falsey
364
        expect(user.theme_id).to eq(1)
365
      end
366 367
    end
  end
368

369
  describe '.find_by_any_email' do
370 371 372
    it 'finds by primary email' do
      user = create(:user, email: 'foo@example.com')

373
      expect(User.find_by_any_email(user.email)).to eq user
374 375 376 377 378 379
    end

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

380
      expect(User.find_by_any_email(email.email)).to eq user
381 382 383
    end

    it 'returns nil when nothing found' do
384
      expect(User.find_by_any_email('')).to be_nil
385 386 387
    end
  end

M
Marin Jankovski 已提交
388 389 390 391 392
  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
393 394 395 396 397 398
      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 已提交
399 400 401
    end
  end

402
  describe 'by_username_or_id' do
D
Dmitriy Zaporozhets 已提交
403 404
    let(:user1) { create(:user, username: 'foo') }

405
    it "should get the correct user" do
406 407 408 409
      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
410 411
    end
  end
G
GitLab 已提交
412

413 414 415 416 417 418 419 420 421 422 423 424 425 426
  describe '.by_login' do
    let(:username) { 'John' }
    let!(:user) { create(:user, username: username) }

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

G
GitLab 已提交
427
  describe 'all_ssh_keys' do
428
    it { is_expected.to have_many(:keys).dependent(:destroy) }
G
GitLab 已提交
429 430 431 432 433

    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

434
      expect(user.all_ssh_keys).to include(key.key)
G
GitLab 已提交
435
    end
G
GitLab 已提交
436
  end
437

D
Dmitriy Zaporozhets 已提交
438 439 440 441 442
  describe :avatar_type do
    let(:user) { create(:user) }

    it "should be true if avatar is image" do
      user.update_attribute(:avatar, 'uploads/avatar.png')
443
      expect(user.avatar_type).to be_truthy
D
Dmitriy Zaporozhets 已提交
444 445 446 447
    end

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

452 453 454
  describe :requires_ldap_check? do
    let(:user) { User.new }

455 456
    it 'is false when LDAP is disabled' do
      # Create a condition which would otherwise cause 'true' to be returned
457
      allow(user).to receive(:ldap_user?).and_return(true)
458
      user.last_credential_check_at = nil
459
      expect(user.requires_ldap_check?).to be_falsey
460 461
    end

462
    context 'when LDAP is enabled' do
463 464 465
      before do
        allow(Gitlab.config.ldap).to receive(:enabled).and_return(true)
      end
466

467
      it 'is false for non-LDAP users' do
468
        allow(user).to receive(:ldap_user?).and_return(false)
469
        expect(user.requires_ldap_check?).to be_falsey
470 471
      end

472
      context 'and when the user is an LDAP user' do
473 474 475
        before do
          allow(user).to receive(:ldap_user?).and_return(true)
        end
476 477 478

        it 'is true when the user has never had an LDAP check before' do
          user.last_credential_check_at = nil
479
          expect(user.requires_ldap_check?).to be_truthy
480 481 482 483
        end

        it 'is true when the last LDAP check happened over 1 hour ago' do
          user.last_credential_check_at = 2.hours.ago
484
          expect(user.requires_ldap_check?).to be_truthy
485
        end
486 487 488 489
      end
    end
  end

490 491
  describe :ldap_user? do
    it "is true if provider name starts with ldap" do
492
      user = create(:omniauth_user, provider: 'ldapmain')
493
      expect( user.ldap_user? ).to be_truthy
494 495 496
    end

    it "is false for other providers" do
497
      user = create(:omniauth_user, provider: 'other-provider')
498
      expect( user.ldap_user? ).to be_falsey
499 500 501
    end

    it "is false if no extern_uid is provided" do
502
      user = create(:omniauth_user, extern_uid: nil)
503
      expect( user.ldap_user? ).to be_falsey
504 505 506
    end
  end

507 508 509
  describe :ldap_identity do
    it "returns ldap identity" do
      user = create :omniauth_user
510
      expect(user.ldap_identity.provider).not_to be_empty
511 512 513
    end
  end

J
Jerome Dalbert 已提交
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552
  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'
553

J
Jerome Dalbert 已提交
554 555
      expect(user.short_website_url).to eq 'test.com'
    end
G
GitLab 已提交
556
  end
C
Ciro Santilli 已提交
557

558 559 560 561 562 563
  describe "#starred?" do
    it "determines if user starred a project" do
      user = create :user
      project1 = create :project, :public
      project2 = create :project, :public

564 565
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_falsey
566 567

      star1 = UsersStarProject.create!(project: project1, user: user)
568 569
      expect(user.starred?(project1)).to be_truthy
      expect(user.starred?(project2)).to be_falsey
570 571

      star2 = UsersStarProject.create!(project: project2, user: user)
572 573
      expect(user.starred?(project1)).to be_truthy
      expect(user.starred?(project2)).to be_truthy
574 575

      star1.destroy
576 577
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_truthy
578 579

      star2.destroy
580 581
      expect(user.starred?(project1)).to be_falsey
      expect(user.starred?(project2)).to be_falsey
582 583 584
    end
  end

C
Ciro Santilli 已提交
585 586 587 588 589
  describe "#toggle_star" do
    it "toggles stars" do
      user = create :user
      project = create :project, :public

590
      expect(user.starred?(project)).to be_falsey
C
Ciro Santilli 已提交
591
      user.toggle_star(project)
592
      expect(user.starred?(project)).to be_truthy
C
Ciro Santilli 已提交
593
      user.toggle_star(project)
594
      expect(user.starred?(project)).to be_falsey
C
Ciro Santilli 已提交
595 596
    end
  end
V
Valery Sizov 已提交
597 598 599 600 601 602 603

  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
604

V
Valery Sizov 已提交
605
    it "sorts users as recently_signed_in" do
606
      expect(User.sort('recent_sign_in').first).to eq(@user)
V
Valery Sizov 已提交
607 608 609
    end

    it "sorts users as late_signed_in" do
610
      expect(User.sort('oldest_sign_in').first).to eq(@user1)
V
Valery Sizov 已提交
611 612 613
    end

    it "sorts users as recently_created" do
614
      expect(User.sort('created_desc').first).to eq(@user)
V
Valery Sizov 已提交
615 616 617
    end

    it "sorts users as late_created" do
618
      expect(User.sort('created_asc').first).to eq(@user1)
V
Valery Sizov 已提交
619 620 621
    end

    it "sorts users by name when nil is passed" do
622
      expect(User.sort(nil).first).to eq(@user)
V
Valery Sizov 已提交
623 624
    end
  end
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651

  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
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668

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