github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/pkg/graphql/api_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/graphql"
     8  	"github.com/kyma-incubator/compass/components/director/pkg/inputvalidation/inputvalidationtest"
     9  	"github.com/kyma-incubator/compass/components/director/pkg/str"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func TestAPIDefinitionInput_Validate_Name(t *testing.T) {
    14  	testCases := []struct {
    15  		Name          string
    16  		Value         string
    17  		ExpectedValid bool
    18  	}{
    19  		{
    20  			Name:          "ExpectedValid",
    21  			Value:         "name-123.com",
    22  			ExpectedValid: true,
    23  		},
    24  		{
    25  			Name:          "Valid Printable ASCII",
    26  			Value:         "V1 +=_-)(*&^%$#@!?/>.<,|\\\"':;}{][",
    27  			ExpectedValid: true,
    28  		},
    29  		{
    30  			Name:          "Empty string",
    31  			Value:         inputvalidationtest.EmptyString,
    32  			ExpectedValid: false,
    33  		},
    34  		{
    35  			Name:          "String longer than 100 chars",
    36  			Value:         inputvalidationtest.String129Long,
    37  			ExpectedValid: false,
    38  		},
    39  		{
    40  			Name:          "String contains invalid ASCII",
    41  			Value:         "ąćńłóęǖǘǚǜ",
    42  			ExpectedValid: false,
    43  		},
    44  	}
    45  
    46  	for _, testCase := range testCases {
    47  		t.Run(testCase.Name, func(t *testing.T) {
    48  			//GIVEN
    49  			obj := fixValidAPIDefinitionInput()
    50  			obj.Name = testCase.Value
    51  			// WHEN
    52  			err := obj.Validate()
    53  			// THEN
    54  			if testCase.ExpectedValid {
    55  				require.NoError(t, err)
    56  			} else {
    57  				require.Error(t, err)
    58  			}
    59  		})
    60  	}
    61  }
    62  
    63  func TestAPIDefinitionInput_Validate_Description(t *testing.T) {
    64  	testCases := []struct {
    65  		Name          string
    66  		Value         *string
    67  		ExpectedValid bool
    68  	}{
    69  		{
    70  			Name:          "ExpectedValid",
    71  			Value:         str.Ptr("this is a valid description"),
    72  			ExpectedValid: true,
    73  		},
    74  		{
    75  			Name:          "Nil pointer",
    76  			Value:         nil,
    77  			ExpectedValid: true,
    78  		},
    79  		{
    80  			Name:          "Empty string",
    81  			Value:         str.Ptr(inputvalidationtest.EmptyString),
    82  			ExpectedValid: true,
    83  		},
    84  		{
    85  			Name:          "String longer than 2000 chars",
    86  			Value:         str.Ptr(inputvalidationtest.String2001Long),
    87  			ExpectedValid: false,
    88  		},
    89  	}
    90  
    91  	for _, testCase := range testCases {
    92  		t.Run(testCase.Name, func(t *testing.T) {
    93  			//GIVEN
    94  			obj := fixValidAPIDefinitionInput()
    95  			obj.Description = testCase.Value
    96  			// WHEN
    97  			err := obj.Validate()
    98  			// THEN
    99  			if testCase.ExpectedValid {
   100  				require.NoError(t, err)
   101  			} else {
   102  				require.Error(t, err)
   103  			}
   104  		})
   105  	}
   106  }
   107  
   108  func TestAPIDefinitionInput_Validate_TargetURL(t *testing.T) {
   109  	testCases := []struct {
   110  		Name          string
   111  		Value         string
   112  		ExpectedValid bool
   113  	}{
   114  		{
   115  			Name:          "ExpectedValid",
   116  			Value:         inputvalidationtest.ValidURL,
   117  			ExpectedValid: true,
   118  		},
   119  		{
   120  			Name:          "URL longer than 256",
   121  			Value:         "kyma-project.io/" + strings.Repeat("a", 241),
   122  			ExpectedValid: false,
   123  		},
   124  		{
   125  			Name:          "Invalid, space in URL",
   126  			Value:         "https://kyma test project.io",
   127  			ExpectedValid: false,
   128  		},
   129  		{
   130  			Name:          "Invalid, no protocol",
   131  			Value:         "kyma-project.io",
   132  			ExpectedValid: false,
   133  		},
   134  	}
   135  
   136  	for _, testCase := range testCases {
   137  		t.Run(testCase.Name, func(t *testing.T) {
   138  			//GIVEN
   139  			app := fixValidAPIDefinitionInput()
   140  			app.TargetURL = testCase.Value
   141  			// WHEN
   142  			err := app.Validate()
   143  			// THEN
   144  			if testCase.ExpectedValid {
   145  				require.NoError(t, err)
   146  			} else {
   147  				require.Error(t, err)
   148  			}
   149  		})
   150  	}
   151  }
   152  
   153  func TestAPIDefinitionInput_Validate_Group(t *testing.T) {
   154  	testCases := []struct {
   155  		Name          string
   156  		Value         *string
   157  		ExpectedValid bool
   158  	}{
   159  		{
   160  			Name:          "ExpectedValid",
   161  			Value:         str.Ptr("this is a valid description"),
   162  			ExpectedValid: true,
   163  		},
   164  		{
   165  			Name:          "Nil pointer",
   166  			Value:         nil,
   167  			ExpectedValid: true,
   168  		},
   169  		{
   170  			Name:          "Empty string",
   171  			Value:         str.Ptr(inputvalidationtest.EmptyString),
   172  			ExpectedValid: true,
   173  		},
   174  		{
   175  			Name:          "String longer than 100 chars",
   176  			Value:         str.Ptr(inputvalidationtest.String101Long),
   177  			ExpectedValid: false,
   178  		},
   179  	}
   180  
   181  	for _, testCase := range testCases {
   182  		t.Run(testCase.Name, func(t *testing.T) {
   183  			//GIVEN
   184  			obj := fixValidAPIDefinitionInput()
   185  			obj.Group = testCase.Value
   186  			// WHEN
   187  			err := obj.Validate()
   188  			// THEN
   189  			if testCase.ExpectedValid {
   190  				require.NoError(t, err)
   191  			} else {
   192  				require.Error(t, err)
   193  			}
   194  		})
   195  	}
   196  }
   197  
   198  func TestAPIDefinitionInput_Validate_APISpecInput(t *testing.T) {
   199  	validObj := fixValidAPISpecInput()
   200  	emptyObj := graphql.APISpecInput{}
   201  
   202  	testCases := []struct {
   203  		Name          string
   204  		Value         *graphql.APISpecInput
   205  		ExpectedValid bool
   206  	}{
   207  		{
   208  			Name:          "ExpectedValid obj",
   209  			Value:         &validObj,
   210  			ExpectedValid: true,
   211  		},
   212  		{
   213  			Name:          "Nil object",
   214  			Value:         nil,
   215  			ExpectedValid: true,
   216  		},
   217  		{
   218  			Name:          "Invalid object",
   219  			Value:         &emptyObj,
   220  			ExpectedValid: false,
   221  		},
   222  	}
   223  
   224  	for _, testCase := range testCases {
   225  		t.Run(testCase.Name, func(t *testing.T) {
   226  			//GIVEN
   227  			obj := fixValidAPIDefinitionInput()
   228  			obj.Spec = testCase.Value
   229  			// WHEN
   230  			err := obj.Validate()
   231  			// THEN
   232  			if testCase.ExpectedValid {
   233  				require.NoError(t, err)
   234  			} else {
   235  				require.Error(t, err)
   236  			}
   237  		})
   238  	}
   239  }
   240  
   241  func TestAPIDefinitionInput_Validate_Version(t *testing.T) {
   242  	validObj := fixValidVersionInput()
   243  	emptyObj := graphql.VersionInput{}
   244  
   245  	testCases := []struct {
   246  		Name          string
   247  		Value         *graphql.VersionInput
   248  		ExpectedValid bool
   249  	}{
   250  		{
   251  			Name:          "ExpectedValid obj",
   252  			Value:         &validObj,
   253  			ExpectedValid: true,
   254  		},
   255  		{
   256  			Name:          "Nil object",
   257  			Value:         nil,
   258  			ExpectedValid: true,
   259  		},
   260  		{
   261  			Name:          "Invalid object",
   262  			Value:         &emptyObj,
   263  			ExpectedValid: false,
   264  		},
   265  	}
   266  
   267  	for _, testCase := range testCases {
   268  		t.Run(testCase.Name, func(t *testing.T) {
   269  			//GIVEN
   270  			obj := fixValidAPIDefinitionInput()
   271  			obj.Version = testCase.Value
   272  			// WHEN
   273  			err := obj.Validate()
   274  			// THEN
   275  			if testCase.ExpectedValid {
   276  				require.NoError(t, err)
   277  			} else {
   278  				require.Error(t, err)
   279  			}
   280  		})
   281  	}
   282  }
   283  
   284  func TestAPISpecInput_Validate_Type(t *testing.T) {
   285  	testCases := []struct {
   286  		Name          string
   287  		Value         graphql.APISpecType
   288  		ExpectedValid bool
   289  	}{
   290  		{
   291  			Name:          "ExpectedValid",
   292  			Value:         graphql.APISpecTypeOpenAPI,
   293  			ExpectedValid: true,
   294  		},
   295  		{
   296  			Name:          "Invalid object",
   297  			Value:         graphql.APISpecType("INVALID"),
   298  			ExpectedValid: false,
   299  		},
   300  		{
   301  			Name:          "Invalid default value",
   302  			ExpectedValid: false,
   303  		},
   304  	}
   305  
   306  	for _, testCase := range testCases {
   307  		t.Run(testCase.Name, func(t *testing.T) {
   308  			//GIVEN
   309  			obj := fixValidAPISpecInput()
   310  			obj.Type = testCase.Value
   311  			// WHEN
   312  			err := obj.Validate()
   313  			// THEN
   314  			if testCase.ExpectedValid {
   315  				require.NoError(t, err)
   316  			} else {
   317  				require.Error(t, err)
   318  			}
   319  		})
   320  	}
   321  }
   322  
   323  func TestAPISpecInput_Validate_Format(t *testing.T) {
   324  	testCases := []struct {
   325  		Name          string
   326  		Value         graphql.SpecFormat
   327  		ExpectedValid bool
   328  	}{
   329  		{
   330  			Name:          "ExpectedValid JSON",
   331  			Value:         graphql.SpecFormatJSON,
   332  			ExpectedValid: true,
   333  		},
   334  		{
   335  			Name:          "Invalid object",
   336  			Value:         graphql.SpecFormat("INVALID"),
   337  			ExpectedValid: false,
   338  		},
   339  		{
   340  			Name:          "Invalid default value",
   341  			ExpectedValid: false,
   342  		},
   343  	}
   344  
   345  	for _, testCase := range testCases {
   346  		t.Run(testCase.Name, func(t *testing.T) {
   347  			//GIVEN
   348  			obj := fixValidAPISpecInput()
   349  			obj.Format = testCase.Value
   350  			// WHEN
   351  			err := obj.Validate()
   352  			// THEN
   353  			if testCase.ExpectedValid {
   354  				require.NoError(t, err)
   355  			} else {
   356  				require.Error(t, err)
   357  			}
   358  		})
   359  	}
   360  }
   361  
   362  func TestAPISpecInput_Validate_TypeODataWithFormat(t *testing.T) {
   363  	testCases := []struct {
   364  		Name          string
   365  		InputType     graphql.APISpecType
   366  		InputFormat   graphql.SpecFormat
   367  		ExpectedValid bool
   368  	}{
   369  		{
   370  			Name:          "ExpectedValid ODATA with XML",
   371  			InputType:     graphql.APISpecTypeOdata,
   372  			InputFormat:   graphql.SpecFormatXML,
   373  			ExpectedValid: true,
   374  		},
   375  		{
   376  			Name:          "ExpectedValid ODATA with JSON",
   377  			InputType:     graphql.APISpecTypeOdata,
   378  			InputFormat:   graphql.SpecFormatJSON,
   379  			ExpectedValid: true,
   380  		},
   381  		{
   382  			Name:          "Invalid ODATA with YAML",
   383  			InputType:     graphql.APISpecTypeOdata,
   384  			InputFormat:   graphql.SpecFormatYaml,
   385  			ExpectedValid: false,
   386  		},
   387  	}
   388  
   389  	for _, testCase := range testCases {
   390  		t.Run(testCase.Name, func(t *testing.T) {
   391  			//GIVEN
   392  			obj := fixValidAPISpecInput()
   393  			obj.Type = testCase.InputType
   394  			obj.Format = testCase.InputFormat
   395  			// WHEN
   396  			err := obj.Validate()
   397  			// THEN
   398  			if testCase.ExpectedValid {
   399  				require.NoError(t, err)
   400  			} else {
   401  				require.Error(t, err)
   402  			}
   403  		})
   404  	}
   405  }
   406  
   407  func TestAPISpecInput_Validate_TypeOpenAPIWithFormat(t *testing.T) {
   408  	testCases := []struct {
   409  		Name          string
   410  		InputType     graphql.APISpecType
   411  		InputFormat   graphql.SpecFormat
   412  		ExpectedValid bool
   413  	}{
   414  		{
   415  			Name:          "ExpectedValid OpenAPI with JSON",
   416  			InputType:     graphql.APISpecTypeOpenAPI,
   417  			InputFormat:   graphql.SpecFormatJSON,
   418  			ExpectedValid: true,
   419  		},
   420  		{
   421  			Name:          "ExpectedValid OpenAPI with YAML",
   422  			InputType:     graphql.APISpecTypeOpenAPI,
   423  			InputFormat:   graphql.SpecFormatYaml,
   424  			ExpectedValid: true,
   425  		},
   426  		{
   427  			Name:          "invalid OpenAPI with XML",
   428  			InputType:     graphql.APISpecTypeOpenAPI,
   429  			InputFormat:   graphql.SpecFormatXML,
   430  			ExpectedValid: false,
   431  		},
   432  	}
   433  
   434  	for _, testCase := range testCases {
   435  		t.Run(testCase.Name, func(t *testing.T) {
   436  			//GIVEN
   437  			obj := fixValidAPISpecInput()
   438  			obj.Type = testCase.InputType
   439  			obj.Format = testCase.InputFormat
   440  			// WHEN
   441  			err := obj.Validate()
   442  			// THEN
   443  			if testCase.ExpectedValid {
   444  				require.NoError(t, err)
   445  			} else {
   446  				require.Error(t, err)
   447  			}
   448  		})
   449  	}
   450  }
   451  
   452  func TestAPISpecInput_Validate_FetchRequest(t *testing.T) {
   453  	validObj := fixValidFetchRequestInput()
   454  	emptyObj := graphql.FetchRequestInput{}
   455  
   456  	testCases := []struct {
   457  		Name          string
   458  		Value         *graphql.FetchRequestInput
   459  		DataClob      *graphql.CLOB
   460  		ExpectedValid bool
   461  	}{
   462  		{
   463  			Name:          "ExpectedValid obj",
   464  			Value:         &validObj,
   465  			ExpectedValid: true,
   466  		},
   467  		{
   468  			Name:          "Nil object",
   469  			Value:         nil,
   470  			DataClob:      fixCLOB("data"),
   471  			ExpectedValid: true,
   472  		},
   473  		{
   474  			Name:          "Invalid object",
   475  			Value:         &emptyObj,
   476  			ExpectedValid: false,
   477  		},
   478  	}
   479  
   480  	for _, testCase := range testCases {
   481  		t.Run(testCase.Name, func(t *testing.T) {
   482  			//GIVEN
   483  			obj := fixValidAPISpecInput()
   484  			obj.FetchRequest = testCase.Value
   485  			obj.Data = testCase.DataClob
   486  			// WHEN
   487  			err := obj.Validate()
   488  			// THEN
   489  			if testCase.ExpectedValid {
   490  				require.NoError(t, err)
   491  			} else {
   492  				require.Error(t, err)
   493  			}
   494  		})
   495  	}
   496  }
   497  
   498  func fixValidAPISpecInput() graphql.APISpecInput {
   499  	return graphql.APISpecInput{
   500  		Type:   graphql.APISpecTypeOpenAPI,
   501  		Format: graphql.SpecFormatJSON,
   502  		Data:   fixCLOB("data"),
   503  	}
   504  }
   505  
   506  func fixValidAPIDefinitionInput() graphql.APIDefinitionInput {
   507  	return graphql.APIDefinitionInput{
   508  		Name:      inputvalidationtest.ValidName,
   509  		TargetURL: inputvalidationtest.ValidURL,
   510  	}
   511  }