summaryrefslogtreecommitdiff
path: root/spec/models/merge_request/diff_commit_user_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/merge_request/diff_commit_user_spec.rb')
-rw-r--r--spec/models/merge_request/diff_commit_user_spec.rb127
1 files changed, 127 insertions, 0 deletions
diff --git a/spec/models/merge_request/diff_commit_user_spec.rb b/spec/models/merge_request/diff_commit_user_spec.rb
new file mode 100644
index 00000000000..08e073568f9
--- /dev/null
+++ b/spec/models/merge_request/diff_commit_user_spec.rb
@@ -0,0 +1,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