# frozen_string_literal: true

RSpec.shared_examples 'username and email pair is generated by Gitlab::Utils::UsernameAndEmailGenerator' do
  before do
    allow_next_instance_of(Gitlab::Utils::UsernameAndEmailGenerator) do |generator|
      allow(generator).to receive(:random_segment).and_return(random_segment)
    end
  end

  let(:random_segment) { 'randomhex' }

  it 'check email domain' do
    expect(subject.email).to end_with("@#{email_domain}")
  end

  it 'contains random segment part' do
    expect(subject.username).to include("_#{random_segment}")
    expect(subject.email).to include("_#{random_segment}@")
  end

  it 'email name is the same as username' do
    expect(subject.email).to include("#{subject.username}@")
  end

  context 'when conflicts' do
    let(:reserved_username) { "#{username_prefix}_#{random_segment}" }
    let(:reserved_email) { "#{reserved_username}@#{email_domain}" }

    shared_examples 'uniquifies username and email' do
      it 'uniquifies username and email' do
        expect(subject.username).to eq("#{reserved_username}1")
        expect(subject.email).to include("#{subject.username}@")
      end
    end

    context 'when username is reserved' do
      context 'when username is reserved by user' do
        before do
          create(:user, username: reserved_username)
        end

        include_examples 'uniquifies username and email'
      end

      context 'when it conflicts with top-level group namespace' do
        before do
          create(:group, path: reserved_username)
        end

        include_examples 'uniquifies username and email'
      end

      context 'when it conflicts with top-level group namespace that includes upcased characters' do
        before do
          create(:group, path: reserved_username.upcase)
        end

        include_examples 'uniquifies username and email'
      end
    end

    context 'when email is reserved' do
      context 'when it conflicts with confirmed primary email' do
        before do
          create(:user, email: reserved_email)
        end

        include_examples 'uniquifies username and email'
      end

      context 'when it conflicts with unconfirmed primary email' do
        before do
          create(:user, :unconfirmed, email: reserved_email)
        end

        include_examples 'uniquifies username and email'
      end

      context 'when it conflicts with confirmed secondary email' do
        before do
          create(:email, :confirmed, email: reserved_email)
        end

        include_examples 'uniquifies username and email'
      end

      context 'when it conflicts with unconfirmed secondary email' do
        before do
          create(:email, email: reserved_email)
        end

        include_examples 'uniquifies username and email'
      end
    end

    context 'when email and username is reserved' do
      before do
        create(:user, email: reserved_email)
        create(:user, username: "#{reserved_username}1")
      end

      it 'uniquifies username and email' do
        expect(subject.username).to eq("#{reserved_username}2")
        expect(subject.email).to include("#{subject.username}@")
      end
    end
  end
end
