summaryrefslogtreecommitdiff
path: root/spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2019-05-22 14:16:49 +0200
committerRémy Coutable <remy@rymai.me>2019-05-22 21:47:32 +0200
commit6145ddf515f93fcc7ed873b911b6369cc2bc0462 (patch)
treeabdf5336367a88aaa7af7e1a83c3c4fbba37e7ba /spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb
parentadd00b6986c78497c18a2f48bf83f0a23c7923f8 (diff)
downloadgitlab-ce-6145ddf515f93fcc7ed873b911b6369cc2bc0462.tar.gz
Revert "Merge branch 'revert-04c3c6dd' into 'master'"
This reverts commit 744f1f2e7037f5c70c3168d9e2e89b1c327465d2, reversing changes made to c4d930e5f54e7da07c80cc028dfc0f5c08719146.
Diffstat (limited to 'spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb')
-rw-r--r--spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb113
1 files changed, 113 insertions, 0 deletions
diff --git a/spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb b/spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb
new file mode 100644
index 00000000000..a248f60d23e
--- /dev/null
+++ b/spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb
@@ -0,0 +1,113 @@
+require 'spec_helper'
+
+shared_examples_for 'AtomicInternalId' do |validate_presence: true|
+ describe '.has_internal_id' do
+ describe 'Module inclusion' do
+ subject { described_class }
+
+ it { is_expected.to include_module(AtomicInternalId) }
+ end
+
+ describe 'Validation' do
+ before do
+ allow_any_instance_of(described_class).to receive(:"ensure_#{scope}_#{internal_id_attribute}!")
+
+ instance.valid?
+ end
+
+ context 'when presence validation is required' do
+ before do
+ skip unless validate_presence
+ end
+
+ it 'validates presence' do
+ expect(instance.errors[internal_id_attribute]).to include("can't be blank")
+ end
+ end
+
+ context 'when presence validation is not required' do
+ before do
+ skip if validate_presence
+ end
+
+ it 'does not validate presence' do
+ expect(instance.errors[internal_id_attribute]).to be_empty
+ end
+ end
+ end
+
+ describe 'Creating an instance' do
+ subject { instance.save! }
+
+ it 'saves a new instance properly' do
+ expect { subject }.not_to raise_error
+ end
+ end
+
+ describe 'internal id generation' do
+ subject { instance.save! }
+
+ it 'calls InternalId.generate_next and sets internal id attribute' do
+ iid = rand(1..1000)
+
+ expect(InternalId).to receive(:generate_next).with(instance, scope_attrs, usage, any_args).and_return(iid)
+ subject
+ expect(read_internal_id).to eq(iid)
+ end
+
+ it 'does not overwrite an existing internal id' do
+ write_internal_id(4711)
+
+ expect { subject }.not_to change { read_internal_id }
+ end
+
+ context 'when the instance has an internal ID set' do
+ let(:internal_id) { 9001 }
+
+ it 'calls InternalId.update_last_value and sets the `last_value` to that of the instance' do
+ write_internal_id(internal_id)
+
+ expect(InternalId)
+ .to receive(:track_greatest)
+ .with(instance, scope_attrs, usage, internal_id, any_args)
+ .and_return(internal_id)
+ subject
+ end
+ end
+ end
+
+ describe "#reset_scope_internal_id_attribute" do
+ it 'rewinds the allocated IID' do
+ expect { ensure_scope_attribute! }.not_to raise_error
+ expect(read_internal_id).not_to be_nil
+
+ expect(reset_scope_attribute).to be_nil
+ expect(read_internal_id).to be_nil
+ end
+
+ it 'allocates the same IID' do
+ internal_id = ensure_scope_attribute!
+ reset_scope_attribute
+ expect(read_internal_id).to be_nil
+
+ expect(ensure_scope_attribute!).to eq(internal_id)
+ end
+ end
+
+ def ensure_scope_attribute!
+ instance.public_send(:"ensure_#{scope}_#{internal_id_attribute}!")
+ end
+
+ def reset_scope_attribute
+ instance.public_send(:"reset_#{scope}_#{internal_id_attribute}")
+ end
+
+ def read_internal_id
+ instance.public_send(internal_id_attribute)
+ end
+
+ def write_internal_id(value)
+ instance.public_send(:"#{internal_id_attribute}=", value)
+ end
+ end
+end