@@ -563,6 +563,13 @@ def around_save_callback
563
563
end
564
564
end
565
565
566
+ let ( :klass_with_composite_key ) do
567
+ new_class do
568
+ range :age , :integer
569
+ field :name
570
+ end
571
+ end
572
+
566
573
let ( :klass_with_validation ) do
567
574
new_class do
568
575
field :name
@@ -641,6 +648,96 @@ def around_save_callback
641
648
end
642
649
end
643
650
651
+ describe 'primary key schema' do
652
+ context 'simple primary key' do
653
+ it 'persists a model' do
654
+ klass . create_table
655
+
656
+ expect {
657
+ described_class . execute do |txn |
658
+ txn . create! klass , name : 'Alex'
659
+ end
660
+ } . to change ( klass , :count ) . by ( 1 )
661
+ end
662
+ end
663
+
664
+ context 'composite key' do
665
+ it 'persists a model' do
666
+ klass_with_composite_key . create_table
667
+
668
+ expect {
669
+ described_class . execute do |txn |
670
+ txn . create! klass_with_composite_key , name : 'Alex' , age : 3
671
+ end
672
+ } . to change ( klass_with_composite_key , :count ) . by ( 1 )
673
+ end
674
+ end
675
+ end
676
+
677
+ describe 'primary key validation' do
678
+ context 'composite key' do
679
+ it 'requires sort key to be specified' do
680
+ klass_with_composite_key . create_table
681
+
682
+ expect {
683
+ described_class . execute do |txn |
684
+ txn . create! klass_with_composite_key , name : 'Alex' , age : nil
685
+ end
686
+ } . to raise_exception ( Dynamoid ::Errors ::MissingRangeKey )
687
+ end
688
+ end
689
+ end
690
+
691
+ describe 'timestamps' do
692
+ before do
693
+ klass . create_table
694
+ end
695
+
696
+ it 'sets created_at and updated_at if Config.timestamps=true' , config : { timestamps : true } do
697
+ travel 1 . hour do
698
+ time_now = Time . now
699
+
700
+ obj = nil
701
+ described_class . execute do |txn |
702
+ obj = txn . create! klass , name : 'Alex'
703
+ end
704
+
705
+ expect ( obj . created_at . to_i ) . to eql time_now . to_i
706
+ expect ( obj . updated_at . to_i ) . to eql time_now . to_i
707
+ end
708
+ end
709
+
710
+ it 'uses provided values of created_at and updated_at if Config.timestamps=true' , config : { timestamps : true } do
711
+ travel 1 . hour do
712
+ created_at = updated_at = Time . now
713
+
714
+ obj = nil
715
+ described_class . execute do |txn |
716
+ obj = txn . create! klass , created_at : created_at , updated_at : updated_at
717
+ end
718
+
719
+ expect ( obj . created_at . to_i ) . to eql created_at . to_i
720
+ expect ( obj . updated_at . to_i ) . to eql updated_at . to_i
721
+ end
722
+ end
723
+
724
+ it 'does not raise error if Config.timestamps=false' , config : { timestamps : false } do
725
+ expect {
726
+ described_class . execute do |txn |
727
+ txn . create! klass , name : 'Alex'
728
+ end
729
+ } . not_to raise_error
730
+ end
731
+
732
+ it 'does not raise error if no changes and Config.timestamps=false' , config : { timestamps : false } do
733
+ expect {
734
+ described_class . execute do |txn |
735
+ txn . create! klass , { }
736
+ end
737
+ } . not_to raise_error
738
+ end
739
+ end
740
+
644
741
describe 'validation' do
645
742
before do
646
743
klass_with_validation . create_table
@@ -729,6 +826,34 @@ def around_save_callback
729
826
expect ( obj_to_save ) . to be_changed
730
827
end
731
828
829
+ it 'rolls back the transaction when id is not unique' do
830
+ existing = klass . create! ( name : 'Alex' )
831
+
832
+ expect {
833
+ described_class . execute do |txn |
834
+ txn . create! klass , name : 'Alex' , id : existing . id
835
+ txn . create klass , name : 'Michael'
836
+ end
837
+ } . to raise_error ( Aws ::DynamoDB ::Errors ::TransactionCanceledException )
838
+
839
+ expect ( klass . count ) . to eql 1
840
+ expect ( klass . all . to_a ) . to eql [ existing ]
841
+ end
842
+
843
+ it 'is not marked as persisted and is marked as changed when the transaction rolled back' do
844
+ obj = nil
845
+
846
+ expect {
847
+ described_class . execute do |txn |
848
+ obj = txn . create! klass , name : 'Alex'
849
+ raise 'trigger rollback'
850
+ end
851
+ } . to raise_error ( 'trigger rollback' )
852
+
853
+ expect ( obj ) . not_to be_persisted
854
+ expect ( obj ) . to be_changed
855
+ end
856
+
732
857
it 'uses dumped value of partition key to create item' do
733
858
klass = new_class ( partition_key : { name : :published_on , type : :date } ) do
734
859
field :name
0 commit comments