k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/validation/strfmt/default_test.go (about) 1 // Copyright 2015 go-swagger maintainers 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package strfmt 16 17 import ( 18 "encoding" 19 "encoding/base64" 20 "encoding/json" 21 "fmt" 22 "reflect" 23 "strings" 24 "testing" 25 26 "github.com/google/uuid" 27 "github.com/stretchr/testify/assert" 28 ) 29 30 func TestFormatURI(t *testing.T) { 31 uri := URI("http://somewhere.com") 32 str := "http://somewhereelse.com" 33 testStringFormat(t, &uri, "uri", str, []string{}, []string{"somewhere.com"}) 34 } 35 36 func TestFormatEmail(t *testing.T) { 37 email := Email("somebody@somewhere.com") 38 str := string("somebodyelse@somewhere.com") 39 validEmails := []string{ 40 "blah@gmail.com", 41 "test@d.verylongtoplevel", 42 "email+tag@gmail.com", 43 `" "@example.com`, 44 `"Abc\@def"@example.com`, 45 `"Fred Bloggs"@example.com`, 46 `"Joe\\Blow"@example.com`, 47 `"Abc@def"@example.com`, 48 "customer/department=shipping@example.com", 49 "$A12345@example.com", 50 "!def!xyz%abc@example.com", 51 "_somename@example.com", 52 "!#$%&'*+-/=?^_`{}|~@example.com", 53 "Miles.O'Brian@example.com", 54 "postmaster@☁→❄→☃→☀→☺→☂→☹→✝.ws", 55 "root@localhost", 56 "john@com", 57 "api@piston.ninja", 58 } 59 60 testStringFormat(t, &email, "email", str, validEmails, []string{"somebody@somewhere@com"}) 61 } 62 63 func TestFormatHostname(t *testing.T) { 64 hostname := Hostname("somewhere.com") 65 str := string("somewhere.com") 66 veryLongStr := strings.Repeat("a", 256) 67 longStr := strings.Repeat("a", 64) 68 longAddrSegment := strings.Join([]string{"x", "y", longStr}, ".") 69 invalidHostnames := []string{ 70 "somewhere.com!", 71 "user@email.domain", 72 "1.1.1.1", 73 veryLongStr, 74 longAddrSegment, 75 // dashes 76 "www.example-.org", 77 "www.--example.org", 78 "-www.example.org", 79 "www-.example.org", 80 "www.d-.org", 81 "www.-d.org", 82 "www-", 83 "-www", 84 // other characters (not in symbols) 85 "www.ex ample.org", 86 "_www.example.org", 87 "www.ex;ample.org", 88 "www.example_underscored.org", 89 // short top-level domains 90 "www.詹姆斯.x", 91 "a.b.c.d", 92 "-xyz", 93 "xyz-", 94 "x.", 95 "a.b.c.dot-", 96 "a.b.c.é;ö", 97 } 98 validHostnames := []string{ 99 "somewhere.com", 100 "888.com", 101 "a.com", 102 "a.b.com", 103 "a.b.c.com", 104 "a.b.c.d.com", 105 "a.b.c.d.e.com", 106 "1.com", 107 "1.2.com", 108 "1.2.3.com", 109 "1.2.3.4.com", 110 "99.domain.com", 111 "99.99.domain.com", 112 "1wwworg.example.com", // valid, per RFC1123 113 "1000wwworg.example.com", 114 "xn--bcher-kva.example.com", // puny encoded 115 "xn-80ak6aa92e.co", 116 "xn-80ak6aa92e.com", 117 "xn--ls8h.la", 118 "☁→❄→☃→☀→☺→☂→☹→✝.ws", 119 "www.example.onion", 120 "www.example.ôlà", 121 "ôlà.ôlà", 122 "ôlà.ôlà.ôlà", 123 "ex$ample", 124 "localhost", 125 "example", 126 "x", 127 "x-y", 128 "a.b.c.dot", 129 "www.example.org", 130 "a.b.c.d.e.f.g.dot", 131 // extended symbol alphabet 132 "ex=ample.com", 133 "<foo>", 134 "www.example-hyphenated.org", 135 // localized hostnames 136 "www.詹姆斯.org", 137 "www.élégigôö.org", 138 // long top-level domains 139 "www.詹姆斯.london", 140 } 141 142 testStringFormat(t, &hostname, "hostname", str, []string{}, invalidHostnames) 143 testStringFormat(t, &hostname, "hostname", str, validHostnames, []string{}) 144 } 145 146 func TestFormatIPv4(t *testing.T) { 147 ipv4 := IPv4("192.168.254.1") 148 str := string("192.168.254.2") 149 testStringFormat(t, &ipv4, "ipv4", str, []string{ 150 "127.0.0.1", // local 151 "192.168.1.1", // normal 152 "192.168.1.01", // leading zeros (compatibility with go < 1.17) 153 }, []string{"198.168.254.2.2"}) 154 } 155 156 func TestFormatIPv6(t *testing.T) { 157 ipv6 := IPv6("::1") 158 str := string("::2") 159 // TODO: test ipv6 zones 160 testStringFormat(t, &ipv6, "ipv6", str, []string{}, []string{"127.0.0.1"}) 161 } 162 163 func TestFormatCIDR(t *testing.T) { 164 cidr := CIDR("192.168.254.1/24") 165 str := string("192.168.254.2/24") 166 testStringFormat(t, &cidr, "cidr", str, []string{ 167 "192.0.2.1/24", // normal 168 "192.0.02.1/24", // leading zeros (compatibility with go < 1.17) 169 "2001:db8:a0b:12f0::1/32", 170 }, []string{"198.168.254.2", "2001:db8:a0b:12f0::1"}) 171 } 172 173 func TestFormatMAC(t *testing.T) { 174 mac := MAC("01:02:03:04:05:06") 175 str := string("06:05:04:03:02:01") 176 testStringFormat(t, &mac, "mac", str, []string{}, []string{"01:02:03:04:05"}) 177 } 178 179 func TestFormatUUID3(t *testing.T) { 180 first3 := uuid.NewMD5(uuid.NameSpaceURL, []byte("somewhere.com")) 181 other3 := uuid.NewMD5(uuid.NameSpaceURL, []byte("somewhereelse.com")) 182 uuid3 := UUID3(first3.String()) 183 str := other3.String() 184 testStringFormat(t, &uuid3, "uuid3", str, []string{}, []string{"not-a-uuid"}) 185 186 // special case for zero UUID 187 var uuidZero UUID3 188 err := uuidZero.UnmarshalJSON([]byte(jsonNull)) 189 assert.NoError(t, err) 190 assert.EqualValues(t, UUID3(""), uuidZero) 191 } 192 193 func TestFormatUUID4(t *testing.T) { 194 first4 := uuid.Must(uuid.NewRandom()) 195 other4 := uuid.Must(uuid.NewRandom()) 196 uuid4 := UUID4(first4.String()) 197 str := other4.String() 198 testStringFormat(t, &uuid4, "uuid4", str, []string{}, []string{"not-a-uuid"}) 199 200 // special case for zero UUID 201 var uuidZero UUID4 202 err := uuidZero.UnmarshalJSON([]byte(jsonNull)) 203 assert.NoError(t, err) 204 assert.EqualValues(t, UUID4(""), uuidZero) 205 } 206 207 func TestFormatUUID5(t *testing.T) { 208 first5 := uuid.NewSHA1(uuid.NameSpaceURL, []byte("somewhere.com")) 209 other5 := uuid.NewSHA1(uuid.NameSpaceURL, []byte("somewhereelse.com")) 210 uuid5 := UUID5(first5.String()) 211 str := other5.String() 212 testStringFormat(t, &uuid5, "uuid5", str, []string{}, []string{"not-a-uuid"}) 213 214 // special case for zero UUID 215 var uuidZero UUID5 216 err := uuidZero.UnmarshalJSON([]byte(jsonNull)) 217 assert.NoError(t, err) 218 assert.EqualValues(t, UUID5(""), uuidZero) 219 } 220 221 func TestFormatUUID(t *testing.T) { 222 first5 := uuid.NewSHA1(uuid.NameSpaceURL, []byte("somewhere.com")) 223 other5 := uuid.NewSHA1(uuid.NameSpaceURL, []byte("somewhereelse.com")) 224 uuid := UUID(first5.String()) 225 str := other5.String() 226 testStringFormat(t, &uuid, "uuid", str, []string{}, []string{"not-a-uuid"}) 227 228 // special case for zero UUID 229 var uuidZero UUID 230 err := uuidZero.UnmarshalJSON([]byte(jsonNull)) 231 assert.NoError(t, err) 232 assert.EqualValues(t, UUID(""), uuidZero) 233 } 234 235 func TestFormatISBN(t *testing.T) { 236 isbn := ISBN("0321751043") 237 str := string("0321751043") 238 testStringFormat(t, &isbn, "isbn", str, []string{}, []string{"836217463"}) // bad checksum 239 } 240 241 func TestFormatISBN10(t *testing.T) { 242 isbn10 := ISBN10("0321751043") 243 str := string("0321751043") 244 testStringFormat(t, &isbn10, "isbn10", str, []string{}, []string{"836217463"}) // bad checksum 245 } 246 247 func TestFormatISBN13(t *testing.T) { 248 isbn13 := ISBN13("978-0321751041") 249 str := string("978-0321751041") 250 testStringFormat(t, &isbn13, "isbn13", str, []string{}, []string{"978-0321751042"}) // bad checksum 251 } 252 253 func TestFormatHexColor(t *testing.T) { 254 hexColor := HexColor("#FFFFFF") 255 str := string("#000000") 256 testStringFormat(t, &hexColor, "hexcolor", str, []string{}, []string{"#fffffffz"}) 257 } 258 259 func TestFormatRGBColor(t *testing.T) { 260 rgbColor := RGBColor("rgb(255,255,255)") 261 str := string("rgb(0,0,0)") 262 testStringFormat(t, &rgbColor, "rgbcolor", str, []string{}, []string{"rgb(300,0,0)"}) 263 } 264 265 func TestFormatSSN(t *testing.T) { 266 ssn := SSN("111-11-1111") 267 str := string("999 99 9999") 268 testStringFormat(t, &ssn, "ssn", str, []string{}, []string{"999 99 999"}) 269 } 270 271 func TestFormatCreditCard(t *testing.T) { 272 creditCard := CreditCard("4111-1111-1111-1111") 273 str := string("4012-8888-8888-1881") 274 testStringFormat(t, &creditCard, "creditcard", str, []string{}, []string{"9999-9999-9999-999"}) 275 } 276 277 func TestFormatPassword(t *testing.T) { 278 password := Password("super secret stuff here") 279 testStringFormat(t, &password, "password", "super secret!!!", []string{"even more secret"}, []string{}) 280 } 281 282 func TestFormatBase64(t *testing.T) { 283 const b64 string = "This is a byte array with unprintable chars, but it also isn" 284 str := base64.URLEncoding.EncodeToString([]byte(b64)) 285 b := []byte(b64) 286 expected := Base64(b) 287 bj := []byte("\"" + str + "\"") 288 289 var subj Base64 290 err := subj.UnmarshalText([]byte(str)) 291 assert.NoError(t, err) 292 assert.EqualValues(t, expected, subj) 293 294 b, err = subj.MarshalText() 295 assert.NoError(t, err) 296 assert.Equal(t, []byte(str), b) 297 298 var subj2 Base64 299 err = subj2.UnmarshalJSON(bj) 300 assert.NoError(t, err) 301 assert.EqualValues(t, expected, subj2) 302 303 b, err = subj2.MarshalJSON() 304 assert.NoError(t, err) 305 assert.Equal(t, bj, b) 306 307 testValid(t, "byte", str) 308 testInvalid(t, "byte", "ZWxpemFiZXRocG9zZXk") // missing pad char 309 } 310 311 type testableFormat interface { 312 encoding.TextMarshaler 313 encoding.TextUnmarshaler 314 json.Marshaler 315 json.Unmarshaler 316 fmt.Stringer 317 } 318 319 func testStringFormat(t *testing.T, what testableFormat, format, with string, validSamples, invalidSamples []string) { 320 // text encoding interface 321 b := []byte(with) 322 err := what.UnmarshalText(b) 323 assert.NoError(t, err) 324 325 val := reflect.Indirect(reflect.ValueOf(what)) 326 strVal := val.String() 327 assert.Equalf(t, with, strVal, "[%s]UnmarshalText: expected %v and %v to be value equal", format, strVal, with) 328 329 b, err = what.MarshalText() 330 assert.NoError(t, err) 331 assert.Equalf(t, []byte(with), b, "[%s]MarshalText: expected %v and %v to be value equal as []byte", format, string(b), with) 332 333 // Stringer 334 strVal = what.String() 335 assert.Equalf(t, []byte(with), b, "[%s]String: expected %v and %v to be equal", strVal, with) 336 337 // JSON encoding interface 338 bj := []byte("\"" + with + "\"") 339 err = what.UnmarshalJSON(bj) 340 assert.NoError(t, err) 341 val = reflect.Indirect(reflect.ValueOf(what)) 342 strVal = val.String() 343 assert.EqualValuesf(t, with, strVal, "[%s]UnmarshalJSON: expected %v and %v to be value equal", format, strVal, with) 344 345 b, err = what.MarshalJSON() 346 assert.NoError(t, err) 347 assert.Equalf(t, bj, b, "[%s]MarshalJSON: expected %v and %v to be value equal as []byte", format, string(b), with) 348 349 // validation with Registry 350 for _, valid := range append(validSamples, with) { 351 testValid(t, format, valid) 352 } 353 354 for _, invalid := range invalidSamples { 355 testInvalid(t, format, invalid) 356 } 357 } 358 359 func testValid(t *testing.T, name, value string) { 360 ok := Default.Validates(name, value) 361 if !ok { 362 t.Errorf("expected %q of type %s to be valid", value, name) 363 } 364 } 365 366 func testInvalid(t *testing.T, name, value string) { 367 ok := Default.Validates(name, value) 368 if ok { 369 t.Errorf("expected %q of type %s to be invalid", value, name) 370 } 371 } 372 373 func TestDeepCopyBase64(t *testing.T) { 374 b64 := Base64("ZWxpemFiZXRocG9zZXk=") 375 in := &b64 376 377 out := new(Base64) 378 in.DeepCopyInto(out) 379 assert.Equal(t, in, out) 380 381 out2 := in.DeepCopy() 382 assert.Equal(t, in, out2) 383 384 var inNil *Base64 385 out3 := inNil.DeepCopy() 386 assert.Nil(t, out3) 387 } 388 389 func TestDeepCopyURI(t *testing.T) { 390 uri := URI("http://somewhere.com") 391 in := &uri 392 393 out := new(URI) 394 in.DeepCopyInto(out) 395 assert.Equal(t, in, out) 396 397 out2 := in.DeepCopy() 398 assert.Equal(t, in, out2) 399 400 var inNil *URI 401 out3 := inNil.DeepCopy() 402 assert.Nil(t, out3) 403 } 404 405 func TestDeepCopyEmail(t *testing.T) { 406 email := Email("somebody@somewhere.com") 407 in := &email 408 409 out := new(Email) 410 in.DeepCopyInto(out) 411 assert.Equal(t, in, out) 412 413 out2 := in.DeepCopy() 414 assert.Equal(t, in, out2) 415 416 var inNil *Email 417 out3 := inNil.DeepCopy() 418 assert.Nil(t, out3) 419 } 420 421 func TestDeepCopyHostname(t *testing.T) { 422 hostname := Hostname("somewhere.com") 423 in := &hostname 424 425 out := new(Hostname) 426 in.DeepCopyInto(out) 427 assert.Equal(t, in, out) 428 429 out2 := in.DeepCopy() 430 assert.Equal(t, in, out2) 431 432 var inNil *Hostname 433 out3 := inNil.DeepCopy() 434 assert.Nil(t, out3) 435 } 436 437 func TestDeepCopyIPv4(t *testing.T) { 438 ipv4 := IPv4("192.168.254.1") 439 in := &ipv4 440 441 out := new(IPv4) 442 in.DeepCopyInto(out) 443 assert.Equal(t, in, out) 444 445 out2 := in.DeepCopy() 446 assert.Equal(t, in, out2) 447 448 var inNil *IPv4 449 out3 := inNil.DeepCopy() 450 assert.Nil(t, out3) 451 } 452 453 func TestDeepCopyIPv6(t *testing.T) { 454 ipv6 := IPv6("::1") 455 in := &ipv6 456 457 out := new(IPv6) 458 in.DeepCopyInto(out) 459 assert.Equal(t, in, out) 460 461 out2 := in.DeepCopy() 462 assert.Equal(t, in, out2) 463 464 var inNil *IPv6 465 out3 := inNil.DeepCopy() 466 assert.Nil(t, out3) 467 } 468 469 func TestDeepCopyCIDR(t *testing.T) { 470 cidr := CIDR("192.0.2.1/24") 471 in := &cidr 472 473 out := new(CIDR) 474 in.DeepCopyInto(out) 475 assert.Equal(t, in, out) 476 477 out2 := in.DeepCopy() 478 assert.Equal(t, in, out2) 479 480 var inNil *CIDR 481 out3 := inNil.DeepCopy() 482 assert.Nil(t, out3) 483 } 484 485 func TestDeepCopyMAC(t *testing.T) { 486 mac := MAC("01:02:03:04:05:06") 487 in := &mac 488 489 out := new(MAC) 490 in.DeepCopyInto(out) 491 assert.Equal(t, in, out) 492 493 out2 := in.DeepCopy() 494 assert.Equal(t, in, out2) 495 496 var inNil *MAC 497 out3 := inNil.DeepCopy() 498 assert.Nil(t, out3) 499 } 500 501 func TestDeepCopyUUID(t *testing.T) { 502 first5 := uuid.NewSHA1(uuid.NameSpaceURL, []byte("somewhere.com")) 503 uuid := UUID(first5.String()) 504 in := &uuid 505 506 out := new(UUID) 507 in.DeepCopyInto(out) 508 assert.Equal(t, in, out) 509 510 out2 := in.DeepCopy() 511 assert.Equal(t, in, out2) 512 513 var inNil *UUID 514 out3 := inNil.DeepCopy() 515 assert.Nil(t, out3) 516 } 517 518 func TestDeepCopyUUID3(t *testing.T) { 519 first3 := uuid.NewMD5(uuid.NameSpaceURL, []byte("somewhere.com")) 520 uuid3 := UUID3(first3.String()) 521 in := &uuid3 522 523 out := new(UUID3) 524 in.DeepCopyInto(out) 525 assert.Equal(t, in, out) 526 527 out2 := in.DeepCopy() 528 assert.Equal(t, in, out2) 529 530 var inNil *UUID3 531 out3 := inNil.DeepCopy() 532 assert.Nil(t, out3) 533 } 534 535 func TestDeepCopyUUID4(t *testing.T) { 536 first4 := uuid.Must(uuid.NewRandom()) 537 uuid4 := UUID4(first4.String()) 538 in := &uuid4 539 540 out := new(UUID4) 541 in.DeepCopyInto(out) 542 assert.Equal(t, in, out) 543 544 out2 := in.DeepCopy() 545 assert.Equal(t, in, out2) 546 547 var inNil *UUID4 548 out3 := inNil.DeepCopy() 549 assert.Nil(t, out3) 550 } 551 552 func TestDeepCopyUUID5(t *testing.T) { 553 first5 := uuid.NewSHA1(uuid.NameSpaceURL, []byte("somewhere.com")) 554 uuid5 := UUID5(first5.String()) 555 in := &uuid5 556 557 out := new(UUID5) 558 in.DeepCopyInto(out) 559 assert.Equal(t, in, out) 560 561 out2 := in.DeepCopy() 562 assert.Equal(t, in, out2) 563 564 var inNil *UUID5 565 out3 := inNil.DeepCopy() 566 assert.Nil(t, out3) 567 } 568 569 func TestDeepCopyISBN(t *testing.T) { 570 isbn := ISBN("0321751043") 571 in := &isbn 572 573 out := new(ISBN) 574 in.DeepCopyInto(out) 575 assert.Equal(t, in, out) 576 577 out2 := in.DeepCopy() 578 assert.Equal(t, in, out2) 579 580 var inNil *ISBN 581 out3 := inNil.DeepCopy() 582 assert.Nil(t, out3) 583 } 584 585 func TestDeepCopyISBN10(t *testing.T) { 586 isbn10 := ISBN10("0321751043") 587 in := &isbn10 588 589 out := new(ISBN10) 590 in.DeepCopyInto(out) 591 assert.Equal(t, in, out) 592 593 out2 := in.DeepCopy() 594 assert.Equal(t, in, out2) 595 596 var inNil *ISBN10 597 out3 := inNil.DeepCopy() 598 assert.Nil(t, out3) 599 } 600 601 func TestDeepCopyISBN13(t *testing.T) { 602 isbn13 := ISBN13("978-0321751041") 603 in := &isbn13 604 605 out := new(ISBN13) 606 in.DeepCopyInto(out) 607 assert.Equal(t, in, out) 608 609 out2 := in.DeepCopy() 610 assert.Equal(t, in, out2) 611 612 var inNil *ISBN13 613 out3 := inNil.DeepCopy() 614 assert.Nil(t, out3) 615 } 616 617 func TestDeepCopyCreditCard(t *testing.T) { 618 creditCard := CreditCard("4111-1111-1111-1111") 619 in := &creditCard 620 621 out := new(CreditCard) 622 in.DeepCopyInto(out) 623 assert.Equal(t, in, out) 624 625 out2 := in.DeepCopy() 626 assert.Equal(t, in, out2) 627 628 var inNil *CreditCard 629 out3 := inNil.DeepCopy() 630 assert.Nil(t, out3) 631 } 632 633 func TestDeepCopySSN(t *testing.T) { 634 ssn := SSN("111-11-1111") 635 in := &ssn 636 637 out := new(SSN) 638 in.DeepCopyInto(out) 639 assert.Equal(t, in, out) 640 641 out2 := in.DeepCopy() 642 assert.Equal(t, in, out2) 643 644 var inNil *SSN 645 out3 := inNil.DeepCopy() 646 assert.Nil(t, out3) 647 } 648 649 func TestDeepCopyHexColor(t *testing.T) { 650 hexColor := HexColor("#FFFFFF") 651 in := &hexColor 652 653 out := new(HexColor) 654 in.DeepCopyInto(out) 655 assert.Equal(t, in, out) 656 657 out2 := in.DeepCopy() 658 assert.Equal(t, in, out2) 659 660 var inNil *HexColor 661 out3 := inNil.DeepCopy() 662 assert.Nil(t, out3) 663 } 664 665 func TestDeepCopyRGBColor(t *testing.T) { 666 rgbColor := RGBColor("rgb(255,255,255)") 667 in := &rgbColor 668 669 out := new(RGBColor) 670 in.DeepCopyInto(out) 671 assert.Equal(t, in, out) 672 673 out2 := in.DeepCopy() 674 assert.Equal(t, in, out2) 675 676 var inNil *RGBColor 677 out3 := inNil.DeepCopy() 678 assert.Nil(t, out3) 679 } 680 681 func TestDeepCopyPassword(t *testing.T) { 682 password := Password("super secret stuff here") 683 in := &password 684 685 out := new(Password) 686 in.DeepCopyInto(out) 687 assert.Equal(t, in, out) 688 689 out2 := in.DeepCopy() 690 assert.Equal(t, in, out2) 691 692 var inNil *Password 693 out3 := inNil.DeepCopy() 694 assert.Nil(t, out3) 695 }