k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/validation/validate/schema_test.go (about)

     1  // Copyright 2015 go-swagger maintainers
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package validate
    16  
    17  import (
    18  	"encoding/json"
    19  	"math"
    20  	"reflect"
    21  	"testing"
    22  
    23  	"github.com/stretchr/testify/assert"
    24  	"github.com/stretchr/testify/require"
    25  
    26  	"github.com/go-openapi/swag"
    27  	"k8s.io/kube-openapi/pkg/validation/spec"
    28  	"k8s.io/kube-openapi/pkg/validation/strfmt"
    29  )
    30  
    31  func TestSchemaValidator_Validate_Pattern(t *testing.T) {
    32  	var schemaJSON = `
    33  {
    34      "properties": {
    35          "name": {
    36              "type": "string",
    37              "pattern": "^[A-Za-z]+$",
    38              "minLength": 1
    39          },
    40          "place": {
    41              "type": "string",
    42              "pattern": "^[A-Za-z]+$",
    43              "minLength": 1
    44          }
    45      },
    46      "required": [
    47          "name"
    48      ]
    49  }`
    50  
    51  	schema := new(spec.Schema)
    52  	require.NoError(t, json.Unmarshal([]byte(schemaJSON), schema))
    53  
    54  	var input map[string]interface{}
    55  	var inputJSON = `{"name": "Ivan"}`
    56  
    57  	require.NoError(t, json.Unmarshal([]byte(inputJSON), &input))
    58  	assert.NoError(t, AgainstSchema(schema, input, strfmt.Default))
    59  
    60  	input["place"] = json.Number("10")
    61  
    62  	assert.Error(t, AgainstSchema(schema, input, strfmt.Default))
    63  
    64  }
    65  
    66  func TestSchemaValidator_PatternProperties(t *testing.T) {
    67  	var schemaJSON = `
    68  {
    69      "properties": {
    70          "name": {
    71              "type": "string",
    72              "pattern": "^[A-Za-z]+$",
    73              "minLength": 1
    74          }
    75  	},
    76      "patternProperties": {
    77  	  "address-[0-9]+": {
    78           "type": "string",
    79           "pattern": "^[\\s|a-z]+$"
    80  	  }
    81      },
    82      "required": [
    83          "name"
    84      ],
    85  	"additionalProperties": false
    86  }`
    87  
    88  	schema := new(spec.Schema)
    89  	require.NoError(t, json.Unmarshal([]byte(schemaJSON), schema))
    90  
    91  	var input map[string]interface{}
    92  
    93  	// ok
    94  	var inputJSON = `{"name": "Ivan","address-1": "sesame street"}`
    95  	require.NoError(t, json.Unmarshal([]byte(inputJSON), &input))
    96  	assert.NoError(t, AgainstSchema(schema, input, strfmt.Default))
    97  
    98  	// fail pattern regexp
    99  	input["address-1"] = "1, Sesame Street"
   100  	assert.Error(t, AgainstSchema(schema, input, strfmt.Default))
   101  
   102  	// fail patternProperties regexp
   103  	inputJSON = `{"name": "Ivan","address-1": "sesame street","address-A": "address"}`
   104  	require.NoError(t, json.Unmarshal([]byte(inputJSON), &input))
   105  	assert.Error(t, AgainstSchema(schema, input, strfmt.Default))
   106  
   107  }
   108  
   109  func TestSchemaValidator_ReferencePanic(t *testing.T) {
   110  	assert.PanicsWithValue(t, `schema references not supported: http://localhost:1234/integer.json`, schemaRefValidator)
   111  }
   112  
   113  func schemaRefValidator() {
   114  	var schemaJSON = `
   115  {
   116      "$ref": "http://localhost:1234/integer.json"
   117  }`
   118  
   119  	schema := new(spec.Schema)
   120  	_ = json.Unmarshal([]byte(schemaJSON), schema)
   121  
   122  	var input map[string]interface{}
   123  
   124  	// ok
   125  	var inputJSON = `{"name": "Ivan","address-1": "sesame street"}`
   126  	_ = json.Unmarshal([]byte(inputJSON), &input)
   127  	// panics
   128  	_ = AgainstSchema(schema, input, strfmt.Default)
   129  }
   130  
   131  // Test edge cases in schemaValidator which are difficult
   132  // to simulate with specs
   133  func TestSchemaValidator_EdgeCases(t *testing.T) {
   134  	var s *SchemaValidator
   135  
   136  	res := s.Validate("123")
   137  	assert.NotNil(t, res)
   138  	assert.True(t, res.IsValid())
   139  
   140  	s = NewSchemaValidator(nil, nil, "", strfmt.Default)
   141  	assert.Nil(t, s)
   142  
   143  	v := "ABC"
   144  	b := s.Applies(v, reflect.String)
   145  	assert.False(t, b)
   146  
   147  	sp := spec.Schema{}
   148  	b = s.Applies(&sp, reflect.Struct)
   149  	assert.True(t, b)
   150  
   151  	spp := spec.Float64Property()
   152  
   153  	s = NewSchemaValidator(spp, nil, "", strfmt.Default)
   154  
   155  	s.SetPath("path")
   156  	assert.Equal(t, "path", s.Path)
   157  
   158  	r := s.Validate(nil)
   159  	assert.NotNil(t, r)
   160  	assert.False(t, r.IsValid())
   161  
   162  	// Validating json.Number data against number|float64
   163  	j := json.Number("123")
   164  	r = s.Validate(j)
   165  	assert.True(t, r.IsValid())
   166  
   167  	// Validating json.Number data against integer|int32
   168  	spp = spec.Int32Property()
   169  	s = NewSchemaValidator(spp, nil, "", strfmt.Default)
   170  	j = json.Number("123")
   171  	r = s.Validate(j)
   172  	assert.True(t, r.IsValid())
   173  
   174  	bignum := swag.FormatFloat64(math.MaxFloat64)
   175  	j = json.Number(bignum)
   176  	r = s.Validate(j)
   177  	assert.False(t, r.IsValid())
   178  
   179  	// Validating incorrect json.Number data
   180  	spp = spec.Float64Property()
   181  	s = NewSchemaValidator(spp, nil, "", strfmt.Default)
   182  	j = json.Number("AXF")
   183  	r = s.Validate(j)
   184  	assert.False(t, r.IsValid())
   185  }