github.com/condensat/bank-core@v0.1.0/database/query/batch_test.go (about) 1 // Copyright 2020 Condensat Tech. All rights reserved. 2 // Use of this source code is governed by a MIT 3 // license that can be found in the LICENSE file. 4 5 package query 6 7 import ( 8 "reflect" 9 "testing" 10 "time" 11 12 "github.com/condensat/bank-core/database" 13 "github.com/condensat/bank-core/database/model" 14 "github.com/condensat/bank-core/database/query/tests" 15 16 "github.com/jinzhu/gorm" 17 ) 18 19 func TestAddBatch(t *testing.T) { 20 const databaseName = "TestAddBatch" 21 t.Parallel() 22 23 db := tests.Setup(databaseName, WithdrawModel()) 24 defer tests.Teardown(db, databaseName) 25 26 type args struct { 27 network model.BatchNetwork 28 data model.BatchData 29 } 30 tests := []struct { 31 name string 32 args args 33 want model.Batch 34 wantErr bool 35 }{ 36 {"default", args{}, createBatch("", ""), true}, 37 38 {"default_data", args{model.BatchNetworkBitcoin, ""}, createBatch(model.BatchNetworkBitcoin, "{}"), false}, 39 {"valid", args{model.BatchNetworkBitcoin, `{"foo": "bar"}`}, createBatch(model.BatchNetworkBitcoin, `{"foo": "bar"}`), false}, 40 } 41 for _, tt := range tests { 42 tt := tt // capture range variable 43 t.Run(tt.name, func(t *testing.T) { 44 got, err := AddBatch(db, tt.args.network, tt.args.data) 45 if (err != nil) != tt.wantErr { 46 t.Errorf("AddBatch() error = %v, wantErr %v", err, tt.wantErr) 47 return 48 } 49 50 if !tt.wantErr { 51 if got.Timestamp.IsZero() || got.Timestamp.After(time.Now()) { 52 t.Errorf("AddBatch() wrong Timestamp %v", got.Timestamp) 53 } 54 } 55 56 tt.want.ID = got.ID 57 tt.want.Timestamp = got.Timestamp 58 tt.want.ExecuteAfter = got.ExecuteAfter 59 tt.want.Capacity = got.Capacity 60 if !reflect.DeepEqual(got, tt.want) { 61 t.Errorf("AddBatch() = %v, want %v", got, tt.want) 62 } 63 }) 64 } 65 } 66 67 func TestGetBatch(t *testing.T) { 68 const databaseName = "TestGetBatch" 69 t.Parallel() 70 71 db := tests.Setup(databaseName, WithdrawModel()) 72 defer tests.Teardown(db, databaseName) 73 74 ref, _ := AddBatch(db, "bitcoin", "") 75 76 type args struct { 77 ID model.BatchID 78 } 79 tests := []struct { 80 name string 81 args args 82 want model.Batch 83 wantErr bool 84 }{ 85 {"default", args{}, model.Batch{}, true}, 86 {"ref", args{ref.ID}, ref, false}, 87 } 88 for _, tt := range tests { 89 tt := tt // capture range variable 90 t.Run(tt.name, func(t *testing.T) { 91 got, err := GetBatch(db, tt.args.ID) 92 93 if !tt.wantErr { 94 if got.Timestamp.IsZero() || got.Timestamp.After(time.Now()) { 95 t.Errorf("GetBatch() wrong Timestamp %v", got.Timestamp) 96 } 97 98 if got.Capacity != DefaultBatchCapacity { 99 t.Errorf("GetBatch() wrong default capacity = %v, want %v", got.Capacity, DefaultBatchCapacity) 100 } 101 if !got.ExecuteAfter.After(got.Timestamp.Add(DefaultBatchExecutionDelay).Add(-30 * time.Second)) { 102 t.Errorf("GetBatch() wrong default execute after = %v", got.ExecuteAfter) 103 } 104 } 105 106 if (err != nil) != tt.wantErr { 107 t.Errorf("GetBatch() error = %v, wantErr %v", err, tt.wantErr) 108 return 109 } 110 111 if !reflect.DeepEqual(got, tt.want) { 112 t.Errorf("GetBatch() = %v, want %v", got, tt.want) 113 } 114 }) 115 } 116 } 117 118 func TestFetchBatchReady(t *testing.T) { 119 const databaseName = "TestFetchBatchReady" 120 t.Parallel() 121 122 db := tests.Setup(databaseName, WithdrawModel()) 123 defer tests.Teardown(db, databaseName) 124 125 // add not ready 126 ref, _ := AddBatch(db, "bitcoin", "") 127 _, _ = AddBatchInfo(db, ref.ID, model.BatchStatusCreated, model.BatchInfoCrypto, "") 128 129 // add ready 130 ready, _ := AddBatch(db, "bitcoin", "") 131 ready = updateExecuteAfter(db, ready, ready.Timestamp.Add(-time.Minute), ready.Timestamp.Add(-10*time.Second)) 132 _, _ = AddBatchInfo(db, ready.ID, model.BatchStatusCreated, model.BatchInfoCrypto, "") 133 134 tests := []struct { 135 name string 136 want []model.Batch 137 wantErr bool 138 }{ 139 {"ready", []model.Batch{ready}, false}, 140 } 141 for _, tt := range tests { 142 tt := tt // capture range variable 143 t.Run(tt.name, func(t *testing.T) { 144 got, err := FetchBatchReady(db) 145 if (err != nil) != tt.wantErr { 146 t.Errorf("FetchBatchReady() error = %v, wantErr %v", err, tt.wantErr) 147 return 148 } 149 if !reflect.DeepEqual(got, tt.want) { 150 t.Errorf("FetchBatchReady() = %v, want %v", got, tt.want) 151 } 152 }) 153 } 154 } 155 156 func TestFetchBatchByLastStatus(t *testing.T) { 157 const databaseName = "TestFetchBatchByLastStatus" 158 t.Parallel() 159 160 db := tests.Setup(databaseName, WithdrawModel()) 161 defer tests.Teardown(db, databaseName) 162 163 // add created 164 created, _ := AddBatch(db, "bitcoin", "") 165 _, _ = AddBatchInfo(db, created.ID, model.BatchStatusCreated, model.BatchInfoCrypto, "") 166 // add ready 167 ready, _ := AddBatch(db, "bitcoin", "") 168 _, _ = AddBatchInfo(db, ready.ID, model.BatchStatusCreated, model.BatchInfoCrypto, "") 169 _, _ = AddBatchInfo(db, ready.ID, model.BatchStatusReady, model.BatchInfoCrypto, "") 170 // add processing 171 processing, _ := AddBatch(db, "bitcoin", "") 172 _, _ = AddBatchInfo(db, processing.ID, model.BatchStatusCreated, model.BatchInfoCrypto, "") 173 _, _ = AddBatchInfo(db, processing.ID, model.BatchStatusReady, model.BatchInfoCrypto, "") 174 _, _ = AddBatchInfo(db, processing.ID, model.BatchStatusProcessing, model.BatchInfoCrypto, "") 175 176 type args struct { 177 status model.BatchStatus 178 } 179 tests := []struct { 180 name string 181 args args 182 want []model.Batch 183 wantErr bool 184 }{ 185 {"created", args{model.BatchStatusCreated}, []model.Batch{created}, false}, 186 {"ready", args{model.BatchStatusReady}, []model.Batch{ready}, false}, 187 {"processing", args{model.BatchStatusProcessing}, []model.Batch{processing}, false}, 188 } 189 for _, tt := range tests { 190 tt := tt // capture range variable 191 t.Run(tt.name, func(t *testing.T) { 192 got, err := FetchBatchByLastStatus(db, tt.args.status) 193 if (err != nil) != tt.wantErr { 194 t.Errorf("FetchBatchByLastStatus() error = %v, wantErr %v", err, tt.wantErr) 195 return 196 } 197 if !reflect.DeepEqual(got, tt.want) { 198 t.Errorf("FetchBatchByLastStatus() = %v, want %v", got, tt.want) 199 } 200 }) 201 } 202 } 203 func TestListBatchNetworksByStatus(t *testing.T) { 204 const databaseName = "TestListBatchNetworksByStatus" 205 t.Parallel() 206 207 db := tests.Setup(databaseName, WithdrawModel()) 208 defer tests.Teardown(db, databaseName) 209 210 ref1, _ := AddBatch(db, model.BatchNetworkBitcoin, "") 211 ref2, _ := AddBatch(db, model.BatchNetworkBitcoinTestnet, "") 212 ref3, _ := AddBatch(db, model.BatchNetworkBitcoinLiquid, "") 213 ref4, _ := AddBatch(db, model.BatchNetworkBitcoinLightning, "") 214 215 _, _ = AddBatchInfo(db, ref1.ID, model.BatchStatusCreated, model.BatchInfoCrypto, "") 216 _, _ = AddBatchInfo(db, ref2.ID, model.BatchStatusCreated, model.BatchInfoCrypto, "") 217 _, _ = AddBatchInfo(db, ref3.ID, model.BatchStatusCreated, model.BatchInfoCrypto, "") 218 _, _ = AddBatchInfo(db, ref4.ID, model.BatchStatusCreated, model.BatchInfoCrypto, "") 219 220 type args struct { 221 status model.BatchStatus 222 } 223 tests := []struct { 224 name string 225 args args 226 want []model.BatchNetwork 227 wantErr bool 228 }{ 229 {"default", args{}, nil, true}, 230 231 {"empty", args{model.BatchStatusSettled}, nil, false}, 232 {"valid", args{model.BatchStatusCreated}, []model.BatchNetwork{ref1.Network, ref2.Network, ref3.Network, ref4.Network}, false}, 233 } 234 for _, tt := range tests { 235 tt := tt // capture range variable 236 t.Run(tt.name, func(t *testing.T) { 237 got, err := ListBatchNetworksByStatus(db, tt.args.status) 238 if (err != nil) != tt.wantErr { 239 t.Errorf("ListBatchNetworksByStatus() error = %v, wantErr %v", err, tt.wantErr) 240 return 241 } 242 if !reflect.DeepEqual(got, tt.want) { 243 t.Errorf("ListBatchNetworksByStatus() = %v, want %v", got, tt.want) 244 } 245 }) 246 } 247 } 248 249 func createBatch(network model.BatchNetwork, data model.BatchData) model.Batch { 250 return model.Batch{ 251 Network: network, 252 Data: data, 253 } 254 } 255 256 func updateExecuteAfter(db database.Context, ready model.Batch, newTimestamp, newExecuteAfter time.Time) model.Batch { 257 gdb := db.DB().(*gorm.DB) 258 259 ready.Timestamp = newTimestamp 260 ready.ExecuteAfter = newExecuteAfter 261 262 // update 263 _ = gdb.Model(&model.Batch{}). 264 Where(model.Batch{ID: ready.ID}). 265 Update(&ready).Error 266 267 // get from db 268 _ = gdb.Model(&model.Batch{}). 269 Where(model.Batch{ID: ready.ID}). 270 First(&ready).Error 271 272 return ready 273 }