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  }