@@ -337,6 +337,9 @@ def around_destroy_callback
337337end
338338
339339describe 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
409485end
0 commit comments