1 2 3 4 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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
# 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
|