diff options
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.rb | 113 |
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 |