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 }