github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/graphql/app_template_validation_test.go (about) 1 package graphql_test 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/kyma-incubator/compass/components/director/pkg/inputvalidation/inputvalidationtest" 8 9 "github.com/kyma-incubator/compass/components/director/pkg/str" 10 11 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 12 "github.com/stretchr/testify/require" 13 ) 14 15 // ApplicationTemplateInput 16 17 func TestApplicationTemplateInput_Validate_Rule_ValidPlaceholders(t *testing.T) { 18 testPlaceholderName := "test" 19 20 testCases := []struct { 21 Name string 22 Value []*graphql.PlaceholderDefinitionInput 23 Valid bool 24 }{ 25 { 26 Name: "Valid", 27 Value: []*graphql.PlaceholderDefinitionInput{ 28 {Name: testPlaceholderName, Description: str.Ptr("Test description"), JSONPath: str.Ptr("displayName")}, 29 }, 30 Valid: true, 31 }, 32 { 33 Name: "Valid - no placeholders", 34 Value: []*graphql.PlaceholderDefinitionInput{}, 35 Valid: true, 36 }, 37 { 38 Name: "Invalid - not unique", 39 Value: []*graphql.PlaceholderDefinitionInput{ 40 {Name: testPlaceholderName, Description: str.Ptr("Test description"), JSONPath: str.Ptr("displayName")}, 41 {Name: testPlaceholderName, Description: str.Ptr("Different description"), JSONPath: str.Ptr("displayName2")}, 42 }, 43 Valid: false, 44 }, 45 { 46 Name: "Invalid - not used", 47 Value: []*graphql.PlaceholderDefinitionInput{ 48 {Name: "notused", Description: str.Ptr("Test description"), JSONPath: str.Ptr("displayName")}, 49 }, 50 Valid: false, 51 }, 52 } 53 54 for _, testCase := range testCases { 55 t.Run(testCase.Name, func(t *testing.T) { 56 //GIVEN 57 sut := fixValidApplicationTemplateInput() 58 sut.ApplicationInput.Description = str.Ptr(fmt.Sprintf("{{%s}}", testPlaceholderName)) 59 sut.Placeholders = testCase.Value 60 // WHEN 61 err := sut.Validate() 62 // THEN 63 if testCase.Valid { 64 require.NoError(t, err) 65 } else { 66 require.Error(t, err) 67 } 68 }) 69 } 70 } 71 72 func TestApplicationTemplateInput_Validate_Name(t *testing.T) { 73 testCases := []struct { 74 Name string 75 Value string 76 ExpectedValid bool 77 }{ 78 { 79 Name: "ExpectedValid", 80 Value: "name-123.com", 81 ExpectedValid: true, 82 }, 83 { 84 Name: "Valid Printable ASCII", 85 Value: "V1 +=_-)(*&^%$#@!?/>.<,|\\\"':;}{][", 86 ExpectedValid: true, 87 }, 88 { 89 Name: "Empty string", 90 Value: inputvalidationtest.EmptyString, 91 ExpectedValid: false, 92 }, 93 { 94 Name: "String longer than 100 chars", 95 Value: inputvalidationtest.String129Long, 96 ExpectedValid: false, 97 }, 98 { 99 Name: "String contains invalid ASCII", 100 Value: "ąćńłóęǖǘǚǜ", 101 ExpectedValid: false, 102 }, 103 } 104 105 for _, testCase := range testCases { 106 t.Run(testCase.Name, func(t *testing.T) { 107 //GIVEN 108 sut := fixValidApplicationTemplateInput() 109 sut.Name = testCase.Value 110 // WHEN 111 err := sut.Validate() 112 // THEN 113 if testCase.ExpectedValid { 114 require.NoError(t, err) 115 } else { 116 require.Error(t, err) 117 } 118 }) 119 } 120 } 121 122 func TestApplicationTemplateInput_Validate_Description(t *testing.T) { 123 testCases := []struct { 124 Name string 125 Value *string 126 Valid bool 127 }{ 128 { 129 Name: "Valid", 130 Value: str.Ptr("valid valid"), 131 Valid: true, 132 }, 133 { 134 Name: "Valid - Nil", 135 Value: (*string)(nil), 136 Valid: true, 137 }, 138 { 139 Name: "Valid - Empty", 140 Value: str.Ptr(inputvalidationtest.EmptyString), 141 Valid: true, 142 }, 143 { 144 Name: "Invalid - Too long", 145 Value: str.Ptr(inputvalidationtest.String2001Long), 146 Valid: false, 147 }, 148 } 149 150 for _, testCase := range testCases { 151 t.Run(testCase.Name, func(t *testing.T) { 152 //GIVEN 153 sut := fixValidApplicationTemplateInput() 154 sut.Description = testCase.Value 155 // WHEN 156 err := sut.Validate() 157 // THEN 158 if testCase.Valid { 159 require.NoError(t, err) 160 } else { 161 require.Error(t, err) 162 } 163 }) 164 } 165 } 166 167 func TestApplicationTemplateInput_Validate_ApplicationNamespace(t *testing.T) { 168 testCases := []struct { 169 Name string 170 Value *string 171 Valid bool 172 }{ 173 { 174 Name: "Valid", 175 Value: str.Ptr("valid"), 176 Valid: true, 177 }, 178 { 179 Name: "Valid - Nil", 180 Value: (*string)(nil), 181 Valid: true, 182 }, 183 { 184 Name: "Valid - Empty", 185 Value: str.Ptr(inputvalidationtest.EmptyString), 186 Valid: true, 187 }, 188 { 189 Name: "Invalid - Too long", 190 Value: str.Ptr(inputvalidationtest.String257Long), 191 Valid: false, 192 }, 193 } 194 195 for _, testCase := range testCases { 196 t.Run(testCase.Name, func(t *testing.T) { 197 //GIVEN 198 sut := fixValidApplicationTemplateInput() 199 sut.ApplicationNamespace = testCase.Value 200 // WHEN 201 err := sut.Validate() 202 // THEN 203 if testCase.Valid { 204 require.NoError(t, err) 205 } else { 206 require.Error(t, err) 207 } 208 }) 209 } 210 } 211 212 func TestApplicationTemplateInput_Validate_Placeholders(t *testing.T) { 213 testPlaceholderName := "test" 214 testCases := []struct { 215 Name string 216 Value []*graphql.PlaceholderDefinitionInput 217 Valid bool 218 }{ 219 { 220 Name: "Valid", 221 Value: []*graphql.PlaceholderDefinitionInput{ 222 {Name: testPlaceholderName, Description: str.Ptr("Test description"), JSONPath: str.Ptr("displayName")}, 223 }, 224 Valid: true, 225 }, 226 { 227 Name: "Valid - Empty", 228 Value: []*graphql.PlaceholderDefinitionInput{}, 229 Valid: true, 230 }, 231 { 232 Name: "Valid - Nil", 233 Value: nil, 234 Valid: true, 235 }, 236 { 237 Name: "Invalid - Nil in slice", 238 Value: []*graphql.PlaceholderDefinitionInput{ 239 nil, 240 }, 241 Valid: false, 242 }, 243 { 244 Name: "Invalid - Nested validation error", 245 Value: []*graphql.PlaceholderDefinitionInput{ 246 {}, 247 }, 248 Valid: false, 249 }, 250 } 251 252 for _, testCase := range testCases { 253 t.Run(testCase.Name, func(t *testing.T) { 254 //GIVEN 255 sut := fixValidApplicationTemplateInput() 256 sut.ApplicationInput.Description = str.Ptr(fmt.Sprintf("{{%s}}", testPlaceholderName)) 257 sut.Placeholders = testCase.Value 258 // WHEN 259 err := sut.Validate() 260 // THEN 261 if testCase.Valid { 262 require.NoError(t, err) 263 } else { 264 require.Error(t, err) 265 } 266 }) 267 } 268 } 269 270 func TestApplicationTemplateInput_Validate_AccessLevel(t *testing.T) { 271 testCases := []struct { 272 Name string 273 Value graphql.ApplicationTemplateAccessLevel 274 Valid bool 275 }{ 276 { 277 Name: "Valid", 278 Value: graphql.ApplicationTemplateAccessLevelGlobal, 279 Valid: true, 280 }, 281 { 282 Name: "Invalid - Empty", 283 Value: inputvalidationtest.EmptyString, 284 Valid: false, 285 }, 286 { 287 Name: "Invalid - Not in enum", 288 Value: "invalid", 289 Valid: false, 290 }, 291 } 292 293 for _, testCase := range testCases { 294 t.Run(testCase.Name, func(t *testing.T) { 295 //GIVEN 296 sut := fixValidApplicationTemplateInput() 297 sut.AccessLevel = testCase.Value 298 // WHEN 299 err := sut.Validate() 300 // THEN 301 if testCase.Valid { 302 require.NoError(t, err) 303 } else { 304 require.Error(t, err) 305 } 306 }) 307 } 308 } 309 310 func TestApplicationTemplateInput_Validate_Webhooks(t *testing.T) { 311 webhookInput := fixValidWebhookInput(inputvalidationtest.ValidURL) 312 webhookInputWithInvalidOutputTemplate := fixValidWebhookInput(inputvalidationtest.ValidURL) 313 webhookInputWithInvalidOutputTemplate.OutputTemplate = stringPtr(`{ "gone_status_code": 404, "success_status_code": 200}`) 314 webhookInputwithInvalidURL := fixValidWebhookInput(inputvalidationtest.ValidURL) 315 webhookInputwithInvalidURL.URL = nil 316 testCases := []struct { 317 Name string 318 Value []*graphql.WebhookInput 319 Valid bool 320 }{ 321 { 322 Name: "Valid", 323 Value: []*graphql.WebhookInput{&webhookInput}, 324 Valid: true, 325 }, 326 { 327 Name: "Valid - Empty", 328 Value: []*graphql.WebhookInput{}, 329 Valid: true, 330 }, 331 { 332 Name: "Valid - nil", 333 Value: nil, 334 Valid: true, 335 }, 336 { 337 Name: "Invalid - some of the webhooks are in invalid state - invalid output template", 338 Value: []*graphql.WebhookInput{&webhookInputWithInvalidOutputTemplate}, 339 Valid: false, 340 }, 341 { 342 Name: "Invalid - some of the webhooks are in invalid state - invalid URL", 343 Value: []*graphql.WebhookInput{&webhookInputwithInvalidURL}, 344 Valid: false, 345 }, 346 } 347 348 for _, testCase := range testCases { 349 t.Run(testCase.Name, func(t *testing.T) { 350 //GIVEN 351 sut := fixValidApplicationTemplateInput() 352 sut.Webhooks = testCase.Value 353 // WHEN 354 err := sut.Validate() 355 // THEN 356 if testCase.Valid { 357 require.NoError(t, err) 358 } else { 359 require.Error(t, err) 360 } 361 }) 362 } 363 } 364 365 // ApplicationTemplateUpdateInput 366 367 func TestApplicationTemplateUpdateInput_Validate_Rule_ValidPlaceholders(t *testing.T) { 368 testPlaceholderName := "test" 369 370 testCases := []struct { 371 Name string 372 Value []*graphql.PlaceholderDefinitionInput 373 Valid bool 374 }{ 375 { 376 Name: "Valid", 377 Value: []*graphql.PlaceholderDefinitionInput{ 378 {Name: testPlaceholderName, Description: str.Ptr("Test description"), JSONPath: str.Ptr("displayName")}, 379 }, 380 Valid: true, 381 }, 382 { 383 Name: "Valid - no placeholders", 384 Value: []*graphql.PlaceholderDefinitionInput{}, 385 Valid: true, 386 }, 387 { 388 Name: "Invalid - not unique", 389 Value: []*graphql.PlaceholderDefinitionInput{ 390 {Name: testPlaceholderName, Description: str.Ptr("Test description"), JSONPath: str.Ptr("displayName")}, 391 {Name: testPlaceholderName, Description: str.Ptr("Different description"), JSONPath: str.Ptr("displayName2")}, 392 }, 393 Valid: false, 394 }, 395 { 396 Name: "Invalid - not used", 397 Value: []*graphql.PlaceholderDefinitionInput{ 398 {Name: "notused", Description: str.Ptr("Test description"), JSONPath: str.Ptr("displayName")}, 399 }, 400 Valid: false, 401 }, 402 } 403 404 for _, testCase := range testCases { 405 t.Run(testCase.Name, func(t *testing.T) { 406 //GIVEN 407 sut := fixValidApplicationTemplateUpdateInput() 408 sut.ApplicationInput.Description = str.Ptr(fmt.Sprintf("{{%s}}", testPlaceholderName)) 409 sut.Placeholders = testCase.Value 410 // WHEN 411 err := sut.Validate() 412 // THEN 413 if testCase.Valid { 414 require.NoError(t, err) 415 } else { 416 require.Error(t, err) 417 } 418 }) 419 } 420 } 421 422 func TestApplicationTemplateUpdateInput_Validate_Name(t *testing.T) { 423 testCases := []struct { 424 Name string 425 Value string 426 ExpectedValid bool 427 }{ 428 { 429 Name: "ExpectedValid", 430 Value: "name-123.com", 431 ExpectedValid: true, 432 }, 433 { 434 Name: "Valid Printable ASCII", 435 Value: "V1 +=_-)(*&^%$#@!?/>.<,|\\\"':;}{][", 436 ExpectedValid: true, 437 }, 438 { 439 Name: "Empty string", 440 Value: inputvalidationtest.EmptyString, 441 ExpectedValid: false, 442 }, 443 { 444 Name: "String longer than 100 chars", 445 Value: inputvalidationtest.String129Long, 446 ExpectedValid: false, 447 }, 448 { 449 Name: "String contains invalid ASCII", 450 Value: "ąćńłóęǖǘǚǜ", 451 ExpectedValid: false, 452 }, 453 } 454 455 for _, testCase := range testCases { 456 t.Run(testCase.Name, func(t *testing.T) { 457 //GIVEN 458 sut := fixValidApplicationTemplateUpdateInput() 459 sut.Name = testCase.Value 460 // WHEN 461 err := sut.Validate() 462 // THEN 463 if testCase.ExpectedValid { 464 require.NoError(t, err) 465 } else { 466 require.Error(t, err) 467 } 468 }) 469 } 470 } 471 472 func TestApplicationTemplateUpdateInput_Validate_Description(t *testing.T) { 473 testCases := []struct { 474 Name string 475 Value *string 476 Valid bool 477 }{ 478 { 479 Name: "Valid", 480 Value: str.Ptr("valid valid"), 481 Valid: true, 482 }, 483 { 484 Name: "Valid - Nil", 485 Value: (*string)(nil), 486 Valid: true, 487 }, 488 { 489 Name: "Valid - Empty", 490 Value: str.Ptr(inputvalidationtest.EmptyString), 491 Valid: true, 492 }, 493 { 494 Name: "Invalid - Too long", 495 Value: str.Ptr(inputvalidationtest.String2001Long), 496 Valid: false, 497 }, 498 } 499 500 for _, testCase := range testCases { 501 t.Run(testCase.Name, func(t *testing.T) { 502 //GIVEN 503 sut := fixValidApplicationTemplateUpdateInput() 504 sut.Description = testCase.Value 505 // WHEN 506 err := sut.Validate() 507 // THEN 508 if testCase.Valid { 509 require.NoError(t, err) 510 } else { 511 require.Error(t, err) 512 } 513 }) 514 } 515 } 516 517 func TestApplicationTemplateUpdateInput_Validate_Placeholders(t *testing.T) { 518 testPlaceholderName := "test" 519 testCases := []struct { 520 Name string 521 Value []*graphql.PlaceholderDefinitionInput 522 Valid bool 523 }{ 524 { 525 Name: "Valid", 526 Value: []*graphql.PlaceholderDefinitionInput{ 527 {Name: testPlaceholderName, Description: str.Ptr("Test description"), JSONPath: str.Ptr("displayName")}, 528 }, 529 Valid: true, 530 }, 531 { 532 Name: "Valid - Empty", 533 Value: []*graphql.PlaceholderDefinitionInput{}, 534 Valid: true, 535 }, 536 { 537 Name: "Valid - Nil", 538 Value: nil, 539 Valid: true, 540 }, 541 { 542 Name: "Invalid - Nil in slice", 543 Value: []*graphql.PlaceholderDefinitionInput{ 544 nil, 545 }, 546 Valid: false, 547 }, 548 { 549 Name: "Invalid - Nested validation error", 550 Value: []*graphql.PlaceholderDefinitionInput{ 551 {}, 552 }, 553 Valid: false, 554 }, 555 } 556 557 for _, testCase := range testCases { 558 t.Run(testCase.Name, func(t *testing.T) { 559 //GIVEN 560 sut := fixValidApplicationTemplateUpdateInput() 561 sut.ApplicationInput.Description = str.Ptr(fmt.Sprintf("{{%s}}", testPlaceholderName)) 562 sut.Placeholders = testCase.Value 563 // WHEN 564 err := sut.Validate() 565 // THEN 566 if testCase.Valid { 567 require.NoError(t, err) 568 } else { 569 require.Error(t, err) 570 } 571 }) 572 } 573 } 574 575 func TestApplicationTemplateUpdateInput_Validate_AccessLevel(t *testing.T) { 576 testCases := []struct { 577 Name string 578 Value graphql.ApplicationTemplateAccessLevel 579 Valid bool 580 }{ 581 { 582 Name: "Valid", 583 Value: graphql.ApplicationTemplateAccessLevelGlobal, 584 Valid: true, 585 }, 586 { 587 Name: "Invalid - Empty", 588 Value: inputvalidationtest.EmptyString, 589 Valid: false, 590 }, 591 { 592 Name: "Invalid - Not in enum", 593 Value: "invalid", 594 Valid: false, 595 }, 596 } 597 598 for _, testCase := range testCases { 599 t.Run(testCase.Name, func(t *testing.T) { 600 //GIVEN 601 sut := fixValidApplicationTemplateUpdateInput() 602 sut.AccessLevel = testCase.Value 603 // WHEN 604 err := sut.Validate() 605 // THEN 606 if testCase.Valid { 607 require.NoError(t, err) 608 } else { 609 require.Error(t, err) 610 } 611 }) 612 } 613 } 614 615 func TestApplicationTemplateUpdateInput_Validate_Webhooks(t *testing.T) { 616 webhookInput := fixValidWebhookInput(inputvalidationtest.ValidURL) 617 webhookInputWithInvalidOutputTemplate := fixValidWebhookInput(inputvalidationtest.ValidURL) 618 webhookInputWithInvalidOutputTemplate.OutputTemplate = stringPtr(`{ "gone_status_code": 404, "success_status_code": 200}`) 619 webhookInputWithInvalidURL := fixValidWebhookInput(inputvalidationtest.ValidURL) 620 webhookInputWithInvalidURL.URL = nil 621 testCases := []struct { 622 Name string 623 Value []*graphql.WebhookInput 624 Valid bool 625 }{ 626 { 627 Name: "Valid", 628 Value: []*graphql.WebhookInput{&webhookInput}, 629 Valid: true, 630 }, 631 { 632 Name: "Valid - Empty", 633 Value: []*graphql.WebhookInput{}, 634 Valid: true, 635 }, 636 { 637 Name: "Valid - nil", 638 Value: nil, 639 Valid: true, 640 }, 641 { 642 Name: "Invalid - some of the webhooks are in invalid state - invalid output template", 643 Value: []*graphql.WebhookInput{&webhookInputWithInvalidOutputTemplate}, 644 Valid: false, 645 }, 646 { 647 Name: "Invalid - some of the webhooks are in invalid state - invalid URL", 648 Value: []*graphql.WebhookInput{&webhookInputWithInvalidURL}, 649 Valid: false, 650 }, 651 } 652 653 for _, testCase := range testCases { 654 t.Run(testCase.Name, func(t *testing.T) { 655 //GIVEN 656 sut := fixValidApplicationTemplateUpdateInput() 657 sut.ApplicationInput.Webhooks = testCase.Value 658 // WHEN 659 err := sut.Validate() 660 // THEN 661 if testCase.Valid { 662 require.NoError(t, err) 663 } else { 664 require.Error(t, err) 665 } 666 }) 667 } 668 } 669 670 // PlaceholderDefinitionInput 671 672 func TestPlaceholderDefinitionInput_Validate_Name(t *testing.T) { 673 testCases := []struct { 674 Name string 675 Value string 676 Valid bool 677 }{ 678 { 679 Name: "Valid", 680 Value: inputvalidationtest.ValidName, 681 Valid: true, 682 }, 683 { 684 Name: "Invalid - Empty", 685 Value: inputvalidationtest.EmptyString, 686 Valid: false, 687 }, 688 { 689 Name: "Invalid - Invalid Name", 690 Value: inputvalidationtest.InvalidName, 691 Valid: false, 692 }, 693 } 694 695 for _, testCase := range testCases { 696 t.Run(testCase.Name, func(t *testing.T) { 697 //GIVEN 698 sut := fixValidPlaceholderDefintionInput() 699 sut.Name = testCase.Value 700 // WHEN 701 err := sut.Validate() 702 // THEN 703 if testCase.Valid { 704 require.NoError(t, err) 705 } else { 706 require.Error(t, err) 707 } 708 }) 709 } 710 } 711 712 func TestPlaceholderDefinitionInput_Validate_Description(t *testing.T) { 713 testCases := []struct { 714 Name string 715 Value *string 716 Valid bool 717 }{ 718 { 719 Name: "Valid", 720 Value: str.Ptr("valid valid"), 721 Valid: true, 722 }, 723 { 724 Name: "Valid - Nil", 725 Value: (*string)(nil), 726 Valid: true, 727 }, 728 { 729 Name: "Valid - Empty", 730 Value: str.Ptr(inputvalidationtest.EmptyString), 731 Valid: true, 732 }, 733 { 734 Name: "Invalid - Too long", 735 Value: str.Ptr(inputvalidationtest.String2001Long), 736 Valid: false, 737 }, 738 } 739 740 for _, testCase := range testCases { 741 t.Run(testCase.Name, func(t *testing.T) { 742 //GIVEN 743 sut := fixValidPlaceholderDefintionInput() 744 sut.Description = testCase.Value 745 // WHEN 746 err := sut.Validate() 747 // THEN 748 if testCase.Valid { 749 require.NoError(t, err) 750 } else { 751 require.Error(t, err) 752 } 753 }) 754 } 755 } 756 757 func TestApplicationFromTemplateInput_Validate_Rule_EitherPlaceholdersOrPlaceholdersPayloadExists(t *testing.T) { 758 testPlaceholderName := "test" 759 testPlacehoderPayload := "{\"a\":\"b\"}" 760 761 testCases := []struct { 762 Name string 763 Value []*graphql.TemplateValueInput 764 PlaceholdersPayload *string 765 Valid bool 766 }{ 767 { 768 Name: "Valid - only Value", 769 Value: []*graphql.TemplateValueInput{ 770 {Placeholder: testPlaceholderName, Value: "abc"}, 771 }, 772 Valid: true, 773 }, 774 { 775 Name: "Valid - only PlaceholdersPayload", 776 PlaceholdersPayload: &testPlacehoderPayload, 777 Valid: true, 778 }, 779 { 780 Name: "Invalid - both Value and PlaceholdersPayload", 781 Value: []*graphql.TemplateValueInput{ 782 {Placeholder: testPlaceholderName, Value: "abc"}, 783 }, 784 PlaceholdersPayload: &testPlacehoderPayload, 785 Valid: false, 786 }, 787 { 788 Name: "Invalid - neither Value nor PlaceholdersPayload", 789 Valid: false, 790 }, 791 } 792 793 for _, testCase := range testCases { 794 t.Run(testCase.Name, func(t *testing.T) { 795 //GIVEN 796 sut := fixValidApplicationFromTemplateInput() 797 sut.Values = testCase.Value 798 sut.PlaceholdersPayload = testCase.PlaceholdersPayload 799 // WHEN 800 err := sut.Validate() 801 // THEN 802 if testCase.Valid { 803 require.NoError(t, err) 804 } else { 805 require.Error(t, err) 806 } 807 }) 808 } 809 } 810 811 // ApplicationFromTemplateInput 812 813 func TestApplicationFromTemplateInput_Validate_Rule_UniquePlaceholders(t *testing.T) { 814 testPlaceholderName := "test" 815 816 testCases := []struct { 817 Name string 818 Value []*graphql.TemplateValueInput 819 Valid bool 820 }{ 821 { 822 Name: "Valid", 823 Value: []*graphql.TemplateValueInput{ 824 {Placeholder: testPlaceholderName, Value: ""}, 825 }, 826 Valid: true, 827 }, 828 { 829 Name: "Invalid - not unique", 830 Value: []*graphql.TemplateValueInput{ 831 {Placeholder: testPlaceholderName, Value: "one"}, 832 {Placeholder: testPlaceholderName, Value: "two"}, 833 }, 834 Valid: false, 835 }, 836 } 837 838 for _, testCase := range testCases { 839 t.Run(testCase.Name, func(t *testing.T) { 840 //GIVEN 841 sut := fixValidApplicationFromTemplateInput() 842 sut.Values = testCase.Value 843 // WHEN 844 err := sut.Validate() 845 // THEN 846 if testCase.Valid { 847 require.NoError(t, err) 848 } else { 849 require.Error(t, err) 850 } 851 }) 852 } 853 } 854 855 func TestApplicationFromTemplateInput_Validate_TemplateName(t *testing.T) { 856 testPlacehoderPayload := "{\"a\":\"b\"}" 857 testCases := []struct { 858 Name string 859 Value string 860 ExpectedValid bool 861 }{ 862 { 863 Name: "ExpectedValid", 864 Value: "name-123.com", 865 ExpectedValid: true, 866 }, 867 { 868 Name: "Valid Printable ASCII", 869 Value: "V1 +=_-)(*&^%$#@!?/>.<,|\\\"':;}{][", 870 ExpectedValid: true, 871 }, 872 { 873 Name: "Empty string", 874 Value: inputvalidationtest.EmptyString, 875 ExpectedValid: false, 876 }, 877 { 878 Name: "String longer than 100 chars", 879 Value: inputvalidationtest.String129Long, 880 ExpectedValid: false, 881 }, 882 { 883 Name: "String contains invalid ASCII", 884 Value: "ąćńłóęǖǘǚǜ", 885 ExpectedValid: false, 886 }, 887 } 888 889 for _, testCase := range testCases { 890 t.Run(testCase.Name, func(t *testing.T) { 891 //GIVEN 892 sut := fixValidApplicationFromTemplateInput() 893 sut.TemplateName = testCase.Value 894 sut.PlaceholdersPayload = &testPlacehoderPayload 895 // WHEN 896 err := sut.Validate() 897 // THEN 898 if testCase.ExpectedValid { 899 require.NoError(t, err) 900 } else { 901 require.Error(t, err) 902 } 903 }) 904 } 905 } 906 907 func TestApplicationTemplateInput_Validate_Value(t *testing.T) { 908 testPlaceholderName := "test" 909 testCases := []struct { 910 Name string 911 Value []*graphql.TemplateValueInput 912 Valid bool 913 }{ 914 { 915 Name: "Valid", 916 Value: []*graphql.TemplateValueInput{ 917 {Placeholder: testPlaceholderName, Value: "valid"}, 918 }, 919 Valid: true, 920 }, 921 { 922 Name: "Invalid - Nil in slice", 923 Value: []*graphql.TemplateValueInput{ 924 nil, 925 }, 926 Valid: false, 927 }, 928 { 929 Name: "Invalid - Nested validation error", 930 Value: []*graphql.TemplateValueInput{ 931 {}, 932 }, 933 Valid: false, 934 }, 935 } 936 937 for _, testCase := range testCases { 938 t.Run(testCase.Name, func(t *testing.T) { 939 //GIVEN 940 sut := fixValidApplicationFromTemplateInput() 941 sut.Values = testCase.Value 942 // WHEN 943 err := sut.Validate() 944 // THEN 945 if testCase.Valid { 946 require.NoError(t, err) 947 } else { 948 require.Error(t, err) 949 } 950 }) 951 } 952 } 953 954 // TemplateValueInput 955 956 func TestTemplateValueInput_Validate_Name(t *testing.T) { 957 testCases := []struct { 958 Name string 959 Value string 960 Valid bool 961 }{ 962 { 963 Name: "Valid", 964 Value: inputvalidationtest.ValidName, 965 Valid: true, 966 }, 967 { 968 Name: "Invalid - Empty", 969 Value: inputvalidationtest.EmptyString, 970 Valid: false, 971 }, 972 { 973 Name: "Invalid - Invalid Name", 974 Value: inputvalidationtest.InvalidName, 975 Valid: false, 976 }, 977 } 978 979 for _, testCase := range testCases { 980 t.Run(testCase.Name, func(t *testing.T) { 981 //GIVEN 982 sut := fixValidTemplateValueInput() 983 sut.Placeholder = testCase.Value 984 // WHEN 985 err := sut.Validate() 986 // THEN 987 if testCase.Valid { 988 require.NoError(t, err) 989 } else { 990 require.Error(t, err) 991 } 992 }) 993 } 994 } 995 996 func TestTemplateValueInput_Validate_Description(t *testing.T) { 997 testCases := []struct { 998 Name string 999 Value string 1000 Valid bool 1001 }{ 1002 { 1003 Name: "Valid", 1004 Value: "valid", 1005 Valid: true, 1006 }, 1007 { 1008 Name: "Valid - Empty", 1009 Value: inputvalidationtest.EmptyString, 1010 Valid: true, 1011 }, 1012 { 1013 Name: "Invalid - Too long", 1014 Value: inputvalidationtest.String129Long, 1015 Valid: false, 1016 }, 1017 } 1018 1019 for _, testCase := range testCases { 1020 t.Run(testCase.Name, func(t *testing.T) { 1021 //GIVEN 1022 sut := fixValidTemplateValueInput() 1023 sut.Value = testCase.Value 1024 // WHEN 1025 err := sut.Validate() 1026 // THEN 1027 if testCase.Valid { 1028 require.NoError(t, err) 1029 } else { 1030 require.Error(t, err) 1031 } 1032 }) 1033 } 1034 } 1035 1036 // fixtures 1037 1038 func fixValidApplicationTemplateInput() graphql.ApplicationTemplateInput { 1039 return graphql.ApplicationTemplateInput{ 1040 Name: "valid", 1041 ApplicationInput: &graphql.ApplicationJSONInput{ 1042 Name: "valid", 1043 }, 1044 AccessLevel: graphql.ApplicationTemplateAccessLevelGlobal, 1045 Webhooks: []*graphql.WebhookInput{}, 1046 } 1047 } 1048 func fixValidApplicationTemplateUpdateInput() graphql.ApplicationTemplateUpdateInput { 1049 return graphql.ApplicationTemplateUpdateInput{ 1050 Name: "valid", 1051 ApplicationInput: &graphql.ApplicationJSONInput{ 1052 Name: "valid", 1053 }, 1054 AccessLevel: graphql.ApplicationTemplateAccessLevelGlobal, 1055 } 1056 } 1057 1058 func fixValidPlaceholderDefintionInput() graphql.PlaceholderDefinitionInput { 1059 return graphql.PlaceholderDefinitionInput{ 1060 Name: "valid", 1061 } 1062 } 1063 1064 func fixValidApplicationFromTemplateInput() graphql.ApplicationFromTemplateInput { 1065 return graphql.ApplicationFromTemplateInput{ 1066 TemplateName: "valid", 1067 } 1068 } 1069 1070 func fixValidTemplateValueInput() graphql.TemplateValueInput { 1071 return graphql.TemplateValueInput{ 1072 Placeholder: "test", 1073 Value: "", 1074 } 1075 }