github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/graphql/formation_template_validation_test.go (about) 1 package graphql_test 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/kyma-incubator/compass/components/director/pkg/inputvalidation/inputvalidationtest" 8 9 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 10 11 "github.com/stretchr/testify/require" 12 ) 13 14 const ( 15 runtimeArtifactKindField = "RuntimeArtifactKind" 16 runtimeTypeDisplayNameField = "RuntimeTypeDisplayName" 17 runtimeTypesField = "RuntimeTypes" 18 ) 19 20 func TestFormationTemplateInput_ValidateName(t *testing.T) { 21 testCases := []struct { 22 Name string 23 Value string 24 ExpectedValid bool 25 }{ 26 { 27 Name: "Success", 28 Value: "a normal name for once", 29 ExpectedValid: true, 30 }, 31 { 32 Name: "Name longer than 256", 33 Value: strings.Repeat("some-name", 50), 34 ExpectedValid: false, 35 }, 36 { 37 Name: "Invalid", 38 Value: "", 39 ExpectedValid: false, 40 }, 41 } 42 43 for _, testCase := range testCases { 44 t.Run(testCase.Name, func(t *testing.T) { 45 //GIVEN 46 formationTemplateInput := fixValidFormationTemplateInput() 47 formationTemplateInput.Name = testCase.Value 48 // WHEN 49 err := formationTemplateInput.Validate() 50 // THEN 51 if testCase.ExpectedValid { 52 require.NoError(t, err) 53 } else { 54 require.Error(t, err) 55 } 56 }) 57 } 58 } 59 60 func TestFormationTemplateInput_ValidateRuntimeDisplayName(t *testing.T) { 61 testCases := []struct { 62 Name string 63 Value string 64 ExpectedValid bool 65 }{ 66 { 67 Name: "Success", 68 Value: "a normal name for once", 69 ExpectedValid: true, 70 }, 71 { 72 Name: "Name longer than 512", 73 Value: strings.Repeat("some-name", 100), 74 ExpectedValid: false, 75 }, 76 { 77 Name: "Invalid", 78 Value: "", 79 ExpectedValid: false, 80 }, 81 } 82 83 for _, testCase := range testCases { 84 t.Run(testCase.Name, func(t *testing.T) { 85 //GIVEN 86 formationTemplateInput := fixValidFormationTemplateInput() 87 formationTemplateInput.RuntimeTypeDisplayName = &testCase.Value 88 // WHEN 89 err := formationTemplateInput.Validate() 90 // THEN 91 if testCase.ExpectedValid { 92 require.NoError(t, err) 93 } else { 94 require.Error(t, err) 95 } 96 }) 97 } 98 } 99 100 func TestFormationTemplateInput_ValidateRuntimeArtifactKind(t *testing.T) { 101 testCases := []struct { 102 Name string 103 Value graphql.ArtifactType 104 ExpectedValid bool 105 }{ 106 { 107 Name: "Success - Service Instance", 108 Value: graphql.ArtifactTypeServiceInstance, 109 ExpectedValid: true, 110 }, 111 { 112 Name: "Success - Subscription", 113 Value: graphql.ArtifactTypeSubscription, 114 ExpectedValid: true, 115 }, 116 { 117 Name: "Success - Environment Instance", 118 Value: graphql.ArtifactTypeEnvironmentInstance, 119 ExpectedValid: true, 120 }, 121 { 122 Name: "Invalid type", 123 Value: graphql.ArtifactType("Invalid type"), 124 ExpectedValid: false, 125 }, 126 { 127 Name: "Invalid", 128 Value: "", 129 ExpectedValid: false, 130 }, 131 } 132 133 for _, testCase := range testCases { 134 t.Run(testCase.Name, func(t *testing.T) { 135 //GIVEN 136 formationTemplateInput := fixValidFormationTemplateInput() 137 formationTemplateInput.RuntimeArtifactKind = &testCase.Value 138 // WHEN 139 err := formationTemplateInput.Validate() 140 // THEN 141 if testCase.ExpectedValid { 142 require.NoError(t, err) 143 } else { 144 require.Error(t, err) 145 } 146 }) 147 } 148 } 149 150 func TestFormationTemplateInput_ValidateApplicationTypes(t *testing.T) { 151 testCases := []struct { 152 Name string 153 Value []string 154 ExpectedValid bool 155 }{ 156 { 157 Name: "Success", 158 Value: []string{"normal-type", "another-normal-type"}, 159 ExpectedValid: true, 160 }, 161 { 162 Name: "Empty slice", 163 Value: []string{}, 164 ExpectedValid: false, 165 }, 166 { 167 Name: "Nil slice", 168 Value: nil, 169 ExpectedValid: false, 170 }, 171 { 172 Name: "Empty elements in slice", 173 Value: []string{""}, 174 ExpectedValid: false, 175 }, 176 } 177 178 for _, testCase := range testCases { 179 t.Run(testCase.Name, func(t *testing.T) { 180 //GIVEN 181 formationTemplateInput := fixValidFormationTemplateInput() 182 formationTemplateInput.ApplicationTypes = testCase.Value 183 // WHEN 184 err := formationTemplateInput.Validate() 185 // THEN 186 if testCase.ExpectedValid { 187 require.NoError(t, err) 188 } else { 189 require.Error(t, err) 190 } 191 }) 192 } 193 } 194 195 func TestFormationTemplateInput_ValidateRuntimeTypes(t *testing.T) { 196 testCases := []struct { 197 Name string 198 Value []string 199 ExpectedValid bool 200 }{ 201 { 202 Name: "Success", 203 Value: []string{"normal-type", "another-normal-type"}, 204 ExpectedValid: true, 205 }, 206 { 207 Name: "Empty slice", 208 Value: []string{}, 209 ExpectedValid: false, 210 }, 211 { 212 Name: "Nil slice", 213 Value: nil, 214 ExpectedValid: false, 215 }, 216 { 217 Name: "Empty elements in slice", 218 Value: []string{""}, 219 ExpectedValid: false, 220 }, 221 } 222 223 for _, testCase := range testCases { 224 t.Run(testCase.Name, func(t *testing.T) { 225 //GIVEN 226 formationTemplateInput := fixValidFormationTemplateInput() 227 formationTemplateInput.RuntimeTypes = testCase.Value 228 // WHEN 229 err := formationTemplateInput.Validate() 230 // THEN 231 if testCase.ExpectedValid { 232 require.NoError(t, err) 233 } else { 234 require.Error(t, err) 235 } 236 }) 237 } 238 } 239 240 func TestFormationTemplateInput_Validate_Webhooks(t *testing.T) { 241 webhookInput := fixValidWebhookInput(inputvalidationtest.ValidURL) 242 webhookInputWithInvalidOutputTemplate := fixValidWebhookInput(inputvalidationtest.ValidURL) 243 webhookInputWithInvalidMode := fixValidWebhookInput(inputvalidationtest.ValidURL) 244 webhookInputWithInvalidMode.Type = graphql.WebhookTypeFormationLifecycle 245 webhookInputWithInvalidMode.Mode = webhookModePtr(graphql.WebhookModeAsync) 246 webhookInputWithInvalidOutputTemplate.OutputTemplate = stringPtr(`{ "gone_status_code": 404, "success_status_code": 200}`) 247 webhookInputwithInvalidURL := fixValidWebhookInput(inputvalidationtest.ValidURL) 248 webhookInputwithInvalidURL.URL = nil 249 testCases := []struct { 250 Name string 251 Value []*graphql.WebhookInput 252 Valid bool 253 }{ 254 { 255 Name: "Valid", 256 Value: []*graphql.WebhookInput{&webhookInput}, 257 Valid: true, 258 }, 259 { 260 Name: "Valid - Empty", 261 Value: []*graphql.WebhookInput{}, 262 Valid: true, 263 }, 264 { 265 Name: "Valid - nil", 266 Value: nil, 267 Valid: true, 268 }, 269 { 270 Name: "Invalid - type is 'FORMATION_LIFECYCLE' and mode is not 'SYNC'", 271 Value: []*graphql.WebhookInput{&webhookInputWithInvalidMode}, 272 Valid: false, 273 }, 274 { 275 Name: "Invalid - some of the webhooks are in invalid state - invalid output template", 276 Value: []*graphql.WebhookInput{&webhookInputWithInvalidOutputTemplate}, 277 Valid: false, 278 }, 279 { 280 Name: "Invalid - some of the webhooks are in invalid state - invalid URL", 281 Value: []*graphql.WebhookInput{&webhookInputwithInvalidURL}, 282 Valid: false, 283 }, 284 } 285 286 for _, testCase := range testCases { 287 t.Run(testCase.Name, func(t *testing.T) { 288 //GIVEN 289 sut := fixValidFormationTemplateInput() 290 sut.Webhooks = testCase.Value 291 // WHEN 292 err := sut.Validate() 293 // THEN 294 if testCase.Valid { 295 require.NoError(t, err) 296 } else { 297 require.Error(t, err) 298 } 299 }) 300 } 301 } 302 303 func TestFormationTemplateInput_ValidateRuntimeRelatedFields(t *testing.T) { 304 testCases := []struct { 305 Name string 306 EmptyFields []string 307 ExpectedValid bool 308 }{ 309 { 310 Name: "Success all fields present", 311 EmptyFields: []string{}, 312 ExpectedValid: true, 313 }, 314 { 315 Name: "Success all fields missing", 316 EmptyFields: []string{runtimeTypesField, runtimeTypeDisplayNameField, runtimeArtifactKindField}, 317 ExpectedValid: true, 318 }, 319 { 320 Name: "Missing artifact kind", 321 EmptyFields: []string{runtimeArtifactKindField}, 322 ExpectedValid: false, 323 }, 324 { 325 Name: "Missing display name", 326 EmptyFields: []string{runtimeTypeDisplayNameField}, 327 ExpectedValid: false, 328 }, 329 { 330 Name: "Missing runtime types", 331 EmptyFields: []string{runtimeTypesField}, 332 ExpectedValid: false, 333 }, 334 { 335 Name: "Missing artifact kind and display name", 336 EmptyFields: []string{runtimeArtifactKindField, runtimeTypeDisplayNameField}, 337 ExpectedValid: false, 338 }, 339 { 340 Name: "Missing artifact kind and runtime types", 341 EmptyFields: []string{runtimeArtifactKindField, runtimeTypesField}, 342 ExpectedValid: false, 343 }, 344 { 345 Name: "Missing display name and runtime types", 346 EmptyFields: []string{runtimeTypeDisplayNameField, runtimeTypesField}, 347 ExpectedValid: false, 348 }, 349 } 350 351 for _, testCase := range testCases { 352 t.Run(testCase.Name, func(t *testing.T) { 353 //GIVEN 354 formationTemplateInput := fixValidFormationTemplateInput() 355 356 for _, field := range testCase.EmptyFields { 357 switch field { 358 case runtimeTypesField: 359 formationTemplateInput.RuntimeTypes = []string{} 360 case runtimeArtifactKindField: 361 formationTemplateInput.RuntimeArtifactKind = nil 362 case runtimeTypeDisplayNameField: 363 formationTemplateInput.RuntimeTypeDisplayName = nil 364 } 365 } 366 367 // WHEN 368 err := formationTemplateInput.Validate() 369 // THEN 370 if testCase.ExpectedValid { 371 require.NoError(t, err) 372 } else { 373 require.Error(t, err) 374 } 375 }) 376 } 377 } 378 379 func fixValidFormationTemplateInput() graphql.FormationTemplateInput { 380 kind := graphql.ArtifactTypeSubscription 381 return graphql.FormationTemplateInput{ 382 Name: "formation-template-name", 383 ApplicationTypes: []string{"some-application-type"}, 384 RuntimeTypes: []string{"some-runtime-type"}, 385 RuntimeTypeDisplayName: stringPtr("display-name-for-runtime"), 386 RuntimeArtifactKind: &kind, 387 } 388 }