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 }