128 lines
3.5 KiB
Ruby
128 lines
3.5 KiB
Ruby
![]() |
# frozen_string_literal: true
|
||
|
|
||
|
require 'spec_helper'
|
||
|
|
||
|
RSpec.describe MergeRequest::DiffCommitUser do
|
||
|
describe 'validations' do
|
||
|
it 'requires that names are less than 512 characters long' do
|
||
|
expect(described_class.new(name: 'a' * 1000)).not_to be_valid
|
||
|
end
|
||
|
|
||
|
it 'requires that Emails are less than 512 characters long' do
|
||
|
expect(described_class.new(email: 'a' * 1000)).not_to be_valid
|
||
|
end
|
||
|
|
||
|
it 'requires either a name or Email' do
|
||
|
expect(described_class.new).not_to be_valid
|
||
|
end
|
||
|
|
||
|
it 'allows setting of just a name' do
|
||
|
expect(described_class.new(name: 'Alice')).to be_valid
|
||
|
end
|
||
|
|
||
|
it 'allows setting of just an Email' do
|
||
|
expect(described_class.new(email: 'alice@example.com')).to be_valid
|
||
|
end
|
||
|
|
||
|
it 'allows setting of both a name and Email' do
|
||
|
expect(described_class.new(name: 'Alice', email: 'alice@example.com'))
|
||
|
.to be_valid
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '.prepare' do
|
||
|
it 'trims a value to at most 512 characters' do
|
||
|
expect(described_class.prepare('€' * 1_000)).to eq('€' * 512)
|
||
|
end
|
||
|
|
||
|
it 'returns nil if the value is an empty string' do
|
||
|
expect(described_class.prepare('')).to be_nil
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '.find_or_create' do
|
||
|
it 'creates a new row if none exist' do
|
||
|
alice = described_class.find_or_create('Alice', 'alice@example.com')
|
||
|
|
||
|
expect(alice.name).to eq('Alice')
|
||
|
expect(alice.email).to eq('alice@example.com')
|
||
|
end
|
||
|
|
||
|
it 'returns an existing row if one exists' do
|
||
|
user1 = create(:merge_request_diff_commit_user)
|
||
|
user2 = described_class.find_or_create(user1.name, user1.email)
|
||
|
|
||
|
expect(user1).to eq(user2)
|
||
|
end
|
||
|
|
||
|
it 'handles concurrent inserts' do
|
||
|
user = create(:merge_request_diff_commit_user)
|
||
|
|
||
|
expect(described_class)
|
||
|
.to receive(:find_or_create_by!)
|
||
|
.ordered
|
||
|
.with(name: user.name, email: user.email)
|
||
|
.and_raise(ActiveRecord::RecordNotUnique)
|
||
|
|
||
|
expect(described_class)
|
||
|
.to receive(:find_or_create_by!)
|
||
|
.ordered
|
||
|
.with(name: user.name, email: user.email)
|
||
|
.and_return(user)
|
||
|
|
||
|
expect(described_class.find_or_create(user.name, user.email)).to eq(user)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '.bulk_find_or_create' do
|
||
|
it 'bulk creates missing rows and reuses existing rows' do
|
||
|
bob = create(
|
||
|
:merge_request_diff_commit_user,
|
||
|
name: 'Bob',
|
||
|
email: 'bob@example.com'
|
||
|
)
|
||
|
|
||
|
users = described_class.bulk_find_or_create(
|
||
|
[%w[Alice alice@example.com], %w[Bob bob@example.com]]
|
||
|
)
|
||
|
alice = described_class.find_by(name: 'Alice')
|
||
|
|
||
|
expect(users[%w[Alice alice@example.com]]).to eq(alice)
|
||
|
expect(users[%w[Bob bob@example.com]]).to eq(bob)
|
||
|
end
|
||
|
|
||
|
it 'does not insert any data when all users exist' do
|
||
|
bob = create(
|
||
|
:merge_request_diff_commit_user,
|
||
|
name: 'Bob',
|
||
|
email: 'bob@example.com'
|
||
|
)
|
||
|
|
||
|
users = described_class.bulk_find_or_create([%w[Bob bob@example.com]])
|
||
|
|
||
|
expect(described_class).not_to receive(:insert_all)
|
||
|
expect(users[%w[Bob bob@example.com]]).to eq(bob)
|
||
|
end
|
||
|
|
||
|
it 'handles concurrently inserted rows' do
|
||
|
bob = create(
|
||
|
:merge_request_diff_commit_user,
|
||
|
name: 'Bob',
|
||
|
email: 'bob@example.com'
|
||
|
)
|
||
|
|
||
|
input = [%w[Bob bob@example.com]]
|
||
|
|
||
|
expect(described_class)
|
||
|
.to receive(:bulk_find)
|
||
|
.twice
|
||
|
.with(input)
|
||
|
.and_return([], [bob])
|
||
|
|
||
|
users = described_class.bulk_find_or_create(input)
|
||
|
|
||
|
expect(users[%w[Bob bob@example.com]]).to eq(bob)
|
||
|
end
|
||
|
end
|
||
|
end
|