github.com/jdolitsky/cnab-go@v0.7.1-beta1/bundle/definition/validation_test.go (about)

     1  package definition
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestObjectValidationValid(t *testing.T) {
    12  	s := `{
    13  		"type": "object",
    14  		"properties" : {
    15  			"port" : {
    16  				"default": 80,
    17  				"maximum": 10240,
    18  				"minimum": 10,
    19  				"type": "integer"
    20  			}
    21  		}, 
    22  		"required" : ["port"]
    23  	}`
    24  	definition := new(Schema)
    25  	err := json.Unmarshal([]byte(s), definition)
    26  	require.NoError(t, err, "should have been able to marshall definition")
    27  	assert.Equal(t, "object", definition.Type, "type should have been an object")
    28  	props := definition.Properties
    29  	assert.NotNil(t, props, "should have found properties")
    30  	assert.Equal(t, 1, len(props), "should have had a single property")
    31  	propSchema, ok := props["port"]
    32  	assert.True(t, ok, "should have found port property")
    33  	assert.Equal(t, "integer", propSchema.Type, "port type should have been an integer")
    34  
    35  	val := struct {
    36  		Port int `json:"port"`
    37  	}{
    38  		Port: 80,
    39  	}
    40  	valErrors, err := definition.Validate(val)
    41  	assert.Len(t, valErrors, 0, "expected no validation errors")
    42  	assert.NoError(t, err)
    43  }
    44  
    45  func TestObjectValidationValid_CustomValidator_ContentEncoding_base64(t *testing.T) {
    46  	s := `{
    47  		"type": "object",
    48  		"properties" : {
    49  			"file" : {
    50  				"type": "string",
    51  				"contentEncoding": "base64"
    52  			}
    53  		},
    54  		"required" : ["file"]
    55  	}`
    56  	definition := new(Schema)
    57  	err := json.Unmarshal([]byte(s), definition)
    58  	require.NoError(t, err, "should have been able to marshal definition")
    59  	assert.Equal(t, "object", definition.Type, "type should have been an object")
    60  	props := definition.Properties
    61  	assert.NotNil(t, props, "should have found properties")
    62  	assert.Equal(t, 1, len(props), "should have had a single property")
    63  	propSchema, ok := props["file"]
    64  	assert.True(t, ok, "should have found file property")
    65  	assert.Equal(t, "string", propSchema.Type, "file type should have been a string")
    66  	assert.Equal(t, "base64", propSchema.ContentEncoding, "file contentEncoding should have been base64")
    67  
    68  	val := struct {
    69  		File string `json:"file"`
    70  	}{
    71  		File: "SGVsbG8gV29ybGQhCg==",
    72  	}
    73  	valErrors, err := definition.Validate(val)
    74  	assert.NoError(t, err)
    75  	assert.Len(t, valErrors, 0, "expected no validation errors")
    76  
    77  	invalidVal := struct {
    78  		File string `json:"file"`
    79  	}{
    80  		File: "SGVsbG8gV29ybGQhCg===",
    81  	}
    82  	valErrors, err = definition.Validate(invalidVal)
    83  	assert.NoError(t, err)
    84  	assert.Len(t, valErrors, 1, "expected 1 validation error")
    85  	assert.Equal(t, "invalid base64 value: SGVsbG8gV29ybGQhCg===", valErrors[0].Error)
    86  }
    87  
    88  func TestObjectValidationValid_CustomValidator_ContentEncoding_InvalidEncoding(t *testing.T) {
    89  	s := `{
    90  		"type": "object",
    91  		"properties" : {
    92  			"file" : {
    93  				"type": "string",
    94  				"contentEncoding": "base65"
    95  			}
    96  		},
    97  		"required" : ["file"]
    98  	}`
    99  	definition := new(Schema)
   100  	err := json.Unmarshal([]byte(s), definition)
   101  	require.NoError(t, err, "should have been able to marshal definition")
   102  
   103  	val := struct {
   104  		File string `json:"file"`
   105  	}{
   106  		File: "SGVsbG8gV29ybGQhCg==",
   107  	}
   108  	valErrors, err := definition.Validate(val)
   109  	assert.NoError(t, err)
   110  	assert.Len(t, valErrors, 1, "expected 1 validation error")
   111  	assert.Equal(t, "unsupported or invalid contentEncoding type of base65", valErrors[0].Error)
   112  }
   113  
   114  func TestObjectValidationInValidMinimum(t *testing.T) {
   115  	s := `{
   116  		"type": "object",
   117  		"properties" : {
   118  			"port" : {
   119  				"default": 80,
   120  				"maximum": 10240,
   121  				"minimum": 100,
   122  				"type": "integer"
   123  			}
   124  		}, 
   125  		"required" : ["port"]
   126  	}`
   127  	definition := new(Schema)
   128  	err := json.Unmarshal([]byte(s), definition)
   129  	require.NoError(t, err, "should have been able to marshall definition")
   130  	assert.Equal(t, "object", definition.Type, "type should have been an object")
   131  	props := definition.Properties
   132  	assert.NotNil(t, props, "should have found properties")
   133  	assert.Equal(t, 1, len(props), "should have had a single property")
   134  	propSchema, ok := props["port"]
   135  	assert.True(t, ok, "should have found port property")
   136  	assert.Equal(t, "integer", propSchema.Type, "port type should have been an integer")
   137  
   138  	val := struct {
   139  		Port int `json:"port"`
   140  	}{
   141  		Port: 80,
   142  	}
   143  	valErrors, err := definition.Validate(val)
   144  	assert.Nil(t, err, "expected no error")
   145  	assert.Len(t, valErrors, 1, "expected a single validation error")
   146  	valErr := valErrors[0]
   147  	assert.NotNil(t, valErr, "expected the obtain the validation error")
   148  	assert.Equal(t, "/port", valErr.Path, "expected validation error to reference port")
   149  	assert.Equal(t, "must be greater than or equal to 100.000000", valErr.Error, "expected validation error to reference port")
   150  }
   151  
   152  func TestObjectValidationPropertyRequired(t *testing.T) {
   153  	s := `{
   154  		"type": "object",
   155  		"properties" : {
   156  			"port" : {
   157  				"default": 80,
   158  				"maximum": 10240,
   159  				"minimum": 10,
   160  				"type": "integer"
   161  			},
   162  			"host" : {
   163  				"type" : "string"
   164  			}
   165  		}, 
   166  		"required" : ["port","host"]
   167  	}`
   168  	definition := new(Schema)
   169  	err := json.Unmarshal([]byte(s), definition)
   170  	require.NoError(t, err, "should have been able to marshall definition")
   171  	assert.Equal(t, "object", definition.Type, "type should have been an object")
   172  	props := definition.Properties
   173  	assert.NotNil(t, props, "should have found properties")
   174  	assert.Equal(t, 2, len(props), "should have had a two properties")
   175  	propSchema, ok := props["port"]
   176  	assert.True(t, ok, "should have found port property")
   177  	assert.Equal(t, "integer", propSchema.Type, "port type should have been an integer")
   178  
   179  	val := struct {
   180  		Port int `json:"port"`
   181  	}{
   182  		Port: 80,
   183  	}
   184  	valErrors, err := definition.Validate(val)
   185  	assert.Len(t, valErrors, 1, "expected a validation error")
   186  	assert.NoError(t, err)
   187  	assert.Equal(t, "\"host\" value is required", valErrors[0].Error)
   188  
   189  }
   190  
   191  func TestObjectValidationNoAdditionalPropertiesAllowed(t *testing.T) {
   192  	s := `{
   193  		"type": "object",
   194  		"properties" : {
   195  			"port" : {
   196  				"default": 80,
   197  				"maximum": 10240,
   198  				"minimum": 10,
   199  				"type": "integer"
   200  			},
   201  			"host" : {
   202  				"type" : "string"
   203  			}
   204  		},
   205  		"additionalProperties" : false,
   206  		"required" : ["port","host"]
   207  	}`
   208  	definition := new(Schema)
   209  	err := json.Unmarshal([]byte(s), definition)
   210  	require.NoError(t, err, "should have been able to marshall definition")
   211  	assert.Equal(t, "object", definition.Type, "type should have been an object")
   212  	props := definition.Properties
   213  	assert.NotNil(t, props, "should have found properties")
   214  	assert.Equal(t, 2, len(props), "should have had a two properties")
   215  	propSchema, ok := props["port"]
   216  	assert.True(t, ok, "should have found port property")
   217  	assert.Equal(t, "integer", propSchema.Type, "port type should have been an integer")
   218  
   219  	val := struct {
   220  		Port     int    `json:"port"`
   221  		Host     string `json:"host"`
   222  		BadActor bool   `json:"badActor"`
   223  	}{
   224  		Port:     80,
   225  		Host:     "localhost",
   226  		BadActor: true,
   227  	}
   228  	valErrors, err := definition.Validate(val)
   229  	assert.Len(t, valErrors, 1, "expected a validation error")
   230  	assert.NoError(t, err)
   231  	assert.Equal(t, "/badActor", valErrors[0].Path, "expected the error to be on badActor")
   232  	assert.Equal(t, "cannot match schema", valErrors[0].Error)
   233  }
   234  
   235  func TestObjectValidationAdditionalPropertiesAreStrings(t *testing.T) {
   236  	s := `{
   237  		"type": "object",
   238  		"properties" : {
   239  			"port" : {
   240  				"default": 80,
   241  				"maximum": 10240,
   242  				"minimum": 10,
   243  				"type": "integer"
   244  			},
   245  			"host" : {
   246  				"type" : "string"
   247  			}
   248  		},
   249  		"additionalProperties" : {
   250  			"type" : "string"
   251  		},
   252  		"required" : ["port"]
   253  	}`
   254  	definition := new(Schema)
   255  	err := json.Unmarshal([]byte(s), definition)
   256  	require.NoError(t, err, "should have been able to marshall definition")
   257  	assert.Equal(t, "object", definition.Type, "type should have been an object")
   258  	props := definition.Properties
   259  	assert.NotNil(t, props, "should have found properties")
   260  	assert.Equal(t, 2, len(props), "should have had a two properties")
   261  	propSchema, ok := props["port"]
   262  	assert.True(t, ok, "should have found port property")
   263  	assert.Equal(t, "integer", propSchema.Type, "port type should have been an integer")
   264  
   265  	val := struct {
   266  		Port      int    `json:"port"`
   267  		Host      string `json:"host"`
   268  		GoodActor string `json:"goodActor"`
   269  		BadActor  bool   `json:"badActor"`
   270  	}{
   271  		Port:      80,
   272  		Host:      "localhost",
   273  		GoodActor: "hello",
   274  		BadActor:  false,
   275  	}
   276  	valErrors, err := definition.Validate(val)
   277  	assert.Len(t, valErrors, 1, "expected a validation error")
   278  	assert.NoError(t, err)
   279  	assert.Equal(t, "type should be string", valErrors[0].Error)
   280  }