Skip to content

Commit d28121b

Browse files
committed
Sync specs for transactional destroy/destroy!
1 parent 9f1a9d3 commit d28121b

File tree

1 file changed

+86
-10
lines changed

1 file changed

+86
-10
lines changed

spec/dynamoid/transaction_write/destroy_spec.rb

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,9 @@ def around_destroy_callback
337337
end
338338

339339
describe Dynamoid::TransactionWrite, '.destroy!' do
340+
# The only difference in specs structure between #destroy and #destroy! is missing
341+
# a section for callbacks here
342+
340343
let(:klass) do
341344
new_class do
342345
field :name
@@ -368,6 +371,25 @@ def around_destroy_callback
368371
expect(result).to be_destroyed
369372
end
370373

374+
context 'when an issue detected on the DynamoDB side' do
375+
it 'does not raise exception and does not roll back the transaction when a model to destroy does not exist' do
376+
obj_to_destroy = klass.create!(name: 'one', id: '1')
377+
obj_to_destroy.id = 'not-existing'
378+
obj_to_save = klass.new(name: 'two', id: '2')
379+
380+
expect {
381+
described_class.execute do |txn|
382+
txn.destroy! obj_to_destroy
383+
txn.save obj_to_save
384+
end
385+
}.to change(klass, :count).by(1)
386+
387+
expect(obj_to_destroy).to be_destroyed
388+
expect(obj_to_save).to be_persisted
389+
expect(klass.all.to_a.map(&:id)).to contain_exactly('1', obj_to_save.id)
390+
end
391+
end
392+
371393
it 'aborts destroying and raises RecordNotDestroyed if callback throws :abort' do
372394
if ActiveSupport.version < Gem::Version.new('5.0')
373395
skip "Rails 4.x and below don't support aborting with `throw :abort`"
@@ -389,21 +411,75 @@ def around_destroy_callback
389411
expect(obj.destroyed?).to eql nil
390412
end
391413

392-
it 'does not raise exception and does not roll back the transaction when a model to destroy does not exist' do
393-
obj_to_destroy = klass.create!(name: 'one', id: '1')
394-
obj_to_destroy.id = 'not-existing'
395-
obj_to_save = klass.new(name: 'two', id: '2')
414+
it 'rolls back the transaction when a destroying of some model aborted by a before_destroy callback' do
415+
if ActiveSupport.version < Gem::Version.new('5.0')
416+
skip "Rails 4.x and below don't support aborting with `throw :abort`"
417+
end
418+
419+
klass = new_class do
420+
before_destroy { throw :abort }
421+
end
422+
423+
obj_to_destroy = klass.create!
424+
obj_to_save = klass.new
425+
426+
expect {
427+
expect {
428+
described_class.execute do |txn|
429+
txn.save obj_to_save
430+
txn.destroy! obj_to_destroy
431+
end
432+
}.to raise_error(Dynamoid::Errors::RecordNotDestroyed)
433+
}.not_to change { klass.count }
434+
435+
expect(obj_to_save).not_to be_persisted
436+
expect(obj_to_destroy).not_to be_destroyed
437+
438+
expect(klass.exists?(obj_to_destroy.id)).to eql true
439+
expect(klass.exists?(obj_to_save.id)).to eql false
440+
end
441+
442+
it 'is not marked as destroyed when the transaction rolled back' do
443+
obj = klass.create!
396444

397445
expect {
398446
described_class.execute do |txn|
399-
txn.destroy! obj_to_destroy
400-
txn.save obj_to_save
447+
txn.destroy! obj
448+
raise 'trigger rollback'
401449
end
402-
}.to change(klass, :count).by(1)
450+
}.to raise_error('trigger rollback')
403451

404-
expect(obj_to_destroy).to be_destroyed
405-
expect(obj_to_save).to be_persisted
452+
expect(obj).not_to be_destroyed
453+
end
454+
455+
it 'uses dumped value of partition key to destroy item' do
456+
klass = new_class(partition_key: { name: :published_on, type: :date }) do
457+
field :name
458+
end
459+
obj = klass.create!(published_on: '2018-10-07'.to_date, name: 'Alex')
460+
461+
expect(klass.exists?(obj.published_on)).to eql true
406462

407-
expect(klass.all.to_a.map(&:id)).to contain_exactly('1', obj_to_save.id)
463+
described_class.execute do |txn|
464+
txn.destroy! obj
465+
end
466+
467+
expect(klass.exists?(obj.published_on)).to eql false
468+
end
469+
470+
it 'uses dumped value of sort key to destroy item' do
471+
klass = new_class do
472+
range :activated_on, :date
473+
field :name
474+
end
475+
obj = klass.create!(activated_on: Date.today, name: 'Alex')
476+
477+
expect(klass.exists?([[obj.id, obj.activated_on]])).to eql true
478+
479+
described_class.execute do |txn|
480+
txn.destroy! obj
481+
end
482+
483+
expect(klass.exists?([[obj.id, obj.activated_on]])).to eql false
408484
end
409485
end

0 commit comments

Comments
 (0)