github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/validate/blockvalidate_test.go (about)

     1  // Copyright 2021 The TrueBlocks Authors. All rights reserved.
     2  // Use of this source code is governed by a license that can
     3  // be found in the LICENSE file.
     4  
     5  package validate
     6  
     7  import (
     8  	"reflect"
     9  	"testing"
    10  
    11  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/tslib"
    12  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/utils"
    13  )
    14  
    15  func TestIsBlockHash(t *testing.T) {
    16  	if IsBlockHash("fe611cbee814a8e84c3339186b6dc973947c2dc058cd41a5e3669f3b7f4c980d") {
    17  		t.Error("Passes even if 0x is missing")
    18  	}
    19  
    20  	if IsBlockHash("0xfe611cbee814a8e84c3339186b6dc973947c2dc058") {
    21  		t.Error("Passes for too short strings")
    22  	}
    23  
    24  	if IsBlockHash("0xgg611cbee814a8e84c3339186b6dc973947c2dc058cd41a5e3669f3b7f4c980d") {
    25  		t.Error("Passes for non-hex strings")
    26  	}
    27  
    28  	if !IsBlockHash("0xfe611cbee814a8e84c3339186b6dc973947c2dc058cd41a5e3669f3b7f4c980d") {
    29  		t.Error("Fails for a valid block hash")
    30  	}
    31  }
    32  
    33  func TestIsBlockNumber(t *testing.T) {
    34  	if check, _ := IsBlockNumber("notanumber"); check {
    35  		t.Error("Passes for strings")
    36  	}
    37  
    38  	if check, _ := IsBlockNumber(""); check {
    39  		t.Error("Passes for empty string")
    40  	}
    41  
    42  	// We only support decimal numbers for block numbers
    43  	if check, _ := IsBlockNumber("0xff"); !check {
    44  		t.Error("Fails for hex")
    45  	}
    46  
    47  	if check, _ := IsBlockNumber("0"); !check {
    48  		t.Error("Fails for 0")
    49  	}
    50  
    51  	if check, _ := IsBlockNumber("1000"); !check {
    52  		t.Error("Fails for numbers")
    53  	}
    54  
    55  	check, value := IsBlockNumber("12147043")
    56  	if !check || value != uint32(12147043) {
    57  		t.Fatal("Failed for correct input:", check, value)
    58  	}
    59  }
    60  
    61  func TestIsBlockNumberList(t *testing.T) {
    62  	type args struct {
    63  		strs []string
    64  	}
    65  	tests := []struct {
    66  		name  string
    67  		args  args
    68  		want  bool
    69  		want1 []blknum_t
    70  	}{
    71  		{
    72  			name: "list of valid blocknumbers",
    73  			args: args{
    74  				strs: []string{"12147043", "12147042", "12147041"},
    75  			},
    76  			want:  true,
    77  			want1: []blknum_t{12147043, 12147042, 12147041},
    78  		},
    79  		{
    80  			name: "list of invalid blocknumbers",
    81  			args: args{
    82  				strs: []string{"0xfff", "latest", "newest"},
    83  			},
    84  			want:  false,
    85  			want1: nil,
    86  		},
    87  		{
    88  			name: "list of mixed blocknumbers",
    89  			args: args{
    90  				strs: []string{"12147043", "latest", "newest"},
    91  			},
    92  			want:  false,
    93  			want1: nil,
    94  		},
    95  	}
    96  	for _, tt := range tests {
    97  		t.Run(tt.name, func(t *testing.T) {
    98  			got, got1 := IsBlockNumberList(tt.args.strs)
    99  			if got != tt.want {
   100  				t.Errorf("IsBlockNumberList() got = %v, want %v", got, tt.want)
   101  			}
   102  			if !reflect.DeepEqual(got1, tt.want1) {
   103  				t.Errorf("IsBlockNumberList() got1 = %v, want %v", got1, tt.want1)
   104  			}
   105  		})
   106  	}
   107  }
   108  
   109  func TestIsSpecialBlock(t *testing.T) {
   110  	if tslib.IsSpecialBlock(utils.GetTestChain(), "london byzantium") {
   111  		t.Error("Passes for invalid string (space)")
   112  	}
   113  
   114  	if tslib.IsSpecialBlock(utils.GetTestChain(), "lÄ…don") {
   115  		t.Error("Passes for string with invalid characters")
   116  	}
   117  
   118  	if tslib.IsSpecialBlock(utils.GetTestChain(), "123") {
   119  		t.Error("Passes for number")
   120  	}
   121  
   122  	if tslib.IsSpecialBlock(utils.GetTestChain(), "ab") {
   123  		t.Error("Passes for too short strings")
   124  	}
   125  
   126  	if !tslib.IsSpecialBlock(utils.GetTestChain(), "london") {
   127  		t.Error("Fails for valid block name")
   128  	}
   129  
   130  	if !tslib.IsSpecialBlock(utils.GetTestChain(), "devcon1") {
   131  		t.Error("Fails for valid block name with a number")
   132  	}
   133  }
   134  
   135  func TestIsDateTimeString(t *testing.T) {
   136  	if !IsDateTimeString("2021-09-28") {
   137  		t.Error("Fails for date without time")
   138  	}
   139  
   140  	if !IsDateTimeString("2021-09-28T16") {
   141  		t.Error("Fails for date without minutes")
   142  	}
   143  
   144  	if !IsDateTimeString("2021-09-28T16:42") {
   145  		t.Error("Fails for date without seconds")
   146  	}
   147  
   148  	if !IsDateTimeString("2021-09-28T16:42:15") {
   149  		t.Error("Fails for date with time")
   150  	}
   151  
   152  	if !IsDateTimeString("2021-09-28T16:42:15UTC") {
   153  		t.Error("Fails for date with time and timezone")
   154  	}
   155  
   156  	if isBeforeFirstBlock(utils.GetTestChain(), "2015-07-30T15:26:15") {
   157  		t.Error("Fails for exact first block date")
   158  	}
   159  
   160  	if IsDateTimeString("hello") {
   161  		t.Error("Passes for invalid date #1")
   162  	}
   163  
   164  	if IsDateTimeString("2020-08") {
   165  		t.Error("Passes for invalid date #2")
   166  	}
   167  }
   168  
   169  func TestIsRange(t *testing.T) {
   170  	if r, _ := IsRange(utils.GetTestChain(), "100"); r {
   171  		t.Error("Passes for non-range")
   172  	}
   173  
   174  	if r, _ := IsRange(utils.GetTestChain(), "-0100"); r {
   175  		t.Error("Passes for malformed string (1)")
   176  	}
   177  
   178  	if r, _ := IsRange(utils.GetTestChain(), "100-"); r {
   179  		t.Error("Passes for malformed string (2)")
   180  	}
   181  
   182  	if r, _ := IsRange(utils.GetTestChain(), "0-100:"); r {
   183  		t.Error("Passes for malformed string (3)")
   184  	}
   185  
   186  	if r, _ := IsRange(utils.GetTestChain(), "0-100"); !r {
   187  		t.Error("Fails for range without step")
   188  	}
   189  
   190  	if r, _ := IsRange(utils.GetTestChain(), "100-100000:20"); !r {
   191  		t.Error("Fails for range with step")
   192  	}
   193  
   194  	if r, _ := IsRange(utils.GetTestChain(), "london-100"); !r {
   195  		t.Error("Fails for special")
   196  	}
   197  
   198  	if r, _ := IsRange(utils.GetTestChain(), "100-2021-04-20"); !r {
   199  		t.Error("Fails for number and a date")
   200  	}
   201  }
   202  
   203  func TestIsRangeLatestAsStart(t *testing.T) {
   204  	expected := "cannot start range with 'latest'"
   205  	_, err := IsRange(utils.GetTestChain(), "latest-10")
   206  
   207  	if err.Error() != expected {
   208  		t.Errorf("Error mismatch: %s", err)
   209  	}
   210  }
   211  
   212  func TestIsRangeEndGreaterThanStart(t *testing.T) {
   213  	expected := "'stop' must be strictly larger than 'start'"
   214  	_, err := IsRange(utils.GetTestChain(), "1000-10")
   215  
   216  	if err == nil {
   217  		t.Error("No error")
   218  	}
   219  
   220  	if err.Error() != expected {
   221  		t.Errorf("Error mismatch: %s", err)
   222  	}
   223  }
   224  
   225  func TestIsRangeModifierError(t *testing.T) {
   226  	expected := "Input argument appears to be invalid. No such skip marker: biweekly"
   227  	_, err := IsRange(utils.GetTestChain(), "0-1000:biweekly")
   228  
   229  	if err.Error() != expected {
   230  		t.Errorf("Error mismatch: %s", err)
   231  	}
   232  }
   233  
   234  func TestIsRangeInvalidSpecialStart(t *testing.T) {
   235  	valid, err := IsRange(utils.GetTestChain(), "notexisting-1000:10")
   236  
   237  	if valid {
   238  		t.Error("Invalid special passing")
   239  	}
   240  
   241  	if literalErr, ok := err.(*InvalidIdentifierLiteralError); !ok {
   242  		t.Errorf("Wrong error returned: %s", literalErr)
   243  	}
   244  }
   245  
   246  func TestIsRangeInvalidSpecialStop(t *testing.T) {
   247  	valid, err := IsRange(utils.GetTestChain(), "1000-notexisting:10")
   248  
   249  	if valid {
   250  		t.Error("Invalid special passing")
   251  	}
   252  
   253  	if literalErr, ok := err.(*InvalidIdentifierLiteralError); !ok {
   254  		t.Errorf("Wrong error returned: %s", literalErr)
   255  	}
   256  }
   257  
   258  func TestValidateBlockIdentifiers(t *testing.T) {
   259  	type args struct {
   260  		identifiers []string
   261  		validTypes  ValidArgumentType
   262  		maxRanges   int
   263  	}
   264  
   265  	tests := []struct {
   266  		name    string
   267  		args    args
   268  		wantErr bool
   269  	}{
   270  		{
   271  			name: "correct block numbers",
   272  			args: args{
   273  				identifiers: []string{"10", "100", "1000", "2542852800"},
   274  				validTypes:  ValidArgumentBlockNumber | ValidArgumentTimestamp,
   275  				maxRanges:   1,
   276  			},
   277  			wantErr: false,
   278  		},
   279  		{
   280  			name: "correct block hashes",
   281  			args: args{
   282  				identifiers: []string{
   283  					"0xd3b9663a5f2367cb1ebeff5eab7d45cc24931678a1e96348291db13057ad438f",
   284  					"0x98862798ac03f688cba584931e0fe42bf17f37a7c48f905c6fc4e9f2a0ec7cb4",
   285  				},
   286  				validTypes: ValidArgumentBlockHash,
   287  				maxRanges:  1,
   288  			},
   289  			wantErr: false,
   290  		},
   291  		{
   292  			name: "correct datetime",
   293  			args: args{
   294  				identifiers: []string{
   295  					"2021-06-28",
   296  					"2021-07-15T10:25:30",
   297  				},
   298  				validTypes: ValidArgumentDate,
   299  				maxRanges:  1,
   300  			},
   301  			wantErr: false,
   302  		},
   303  		{
   304  			name: "correct special",
   305  			args: args{
   306  				identifiers: []string{
   307  					"london",
   308  					"devcon1",
   309  				},
   310  				validTypes: ValidArgumentSpecialBlock,
   311  				maxRanges:  1,
   312  			},
   313  			wantErr: false,
   314  		},
   315  		{
   316  			name: "correct range",
   317  			args: args{
   318  				identifiers: []string{
   319  					"10-1000:50",
   320  				},
   321  				validTypes: ValidArgumentRange,
   322  				maxRanges:  1,
   323  			},
   324  			wantErr: false,
   325  		},
   326  		{
   327  			name: "correct misc types",
   328  			args: args{
   329  				identifiers: []string{
   330  					"london",
   331  				},
   332  				validTypes: ValidArgumentBlockHash | ValidArgumentSpecialBlock,
   333  				maxRanges:  1,
   334  			},
   335  			wantErr: false,
   336  		},
   337  		{
   338  			name: "correct misc identifiers",
   339  			args: args{
   340  				identifiers: []string{
   341  					"london",
   342  					"10-1000:weekly",
   343  					"1000",
   344  				},
   345  				validTypes: ValidArgumentBlockNumber | ValidArgumentSpecialBlock | ValidArgumentRange,
   346  				maxRanges:  1,
   347  			},
   348  			wantErr: false,
   349  		},
   350  		{
   351  			name: "incorrect range number",
   352  			args: args{
   353  				identifiers: []string{
   354  					"10-1000:50",
   355  					"10-1000:50",
   356  					"10-1000:50",
   357  				},
   358  				validTypes: ValidArgumentRange,
   359  				maxRanges:  2,
   360  			},
   361  			wantErr: true,
   362  		},
   363  		{
   364  			name: "incorrect misc identifiers",
   365  			args: args{
   366  				identifiers: []string{
   367  					"london",
   368  					"10-1000:weekly",
   369  					"1000",
   370  				},
   371  				validTypes: ValidArgumentBlockNumber | ValidArgumentSpecialBlock,
   372  				maxRanges:  1,
   373  			},
   374  			wantErr: true,
   375  		},
   376  	}
   377  	for _, tt := range tests {
   378  		t.Run(tt.name, func(t *testing.T) {
   379  			if err := ValidateIdentifiers(
   380  				utils.GetTestChain(),
   381  				tt.args.identifiers,
   382  				tt.args.validTypes,
   383  				tt.args.maxRanges,
   384  				nil,
   385  			); (err != nil) != tt.wantErr {
   386  				t.Errorf("ValidateIdentifiers() error = %v, wantErr %v", err, tt.wantErr)
   387  			}
   388  		})
   389  	}
   390  }