k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/validation/spec/header_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 spec
    16  
    17  import (
    18  	"encoding/json"
    19  	"reflect"
    20  	"testing"
    21  
    22  	"github.com/google/go-cmp/cmp"
    23  	"github.com/stretchr/testify/assert"
    24  	"github.com/stretchr/testify/require"
    25  	jsontesting "k8s.io/kube-openapi/pkg/util/jsontesting"
    26  )
    27  
    28  func float64Ptr(f float64) *float64 {
    29  	return &f
    30  }
    31  func int64Ptr(f int64) *int64 {
    32  	return &f
    33  }
    34  
    35  var header = Header{
    36  	VendorExtensible: VendorExtensible{Extensions: map[string]interface{}{
    37  		"x-framework": "swagger-go",
    38  	}},
    39  	HeaderProps: HeaderProps{Description: "the description of this header"},
    40  	SimpleSchema: SimpleSchema{
    41  		Items: &Items{
    42  			Refable: Refable{Ref: MustCreateRef("Cat")},
    43  		},
    44  		Type:    "string",
    45  		Format:  "date",
    46  		Default: "8",
    47  	},
    48  	CommonValidations: CommonValidations{
    49  		Maximum:          float64Ptr(100),
    50  		ExclusiveMaximum: true,
    51  		ExclusiveMinimum: true,
    52  		Minimum:          float64Ptr(5),
    53  		MaxLength:        int64Ptr(100),
    54  		MinLength:        int64Ptr(5),
    55  		Pattern:          "\\w{1,5}\\w+",
    56  		MaxItems:         int64Ptr(100),
    57  		MinItems:         int64Ptr(5),
    58  		UniqueItems:      true,
    59  		MultipleOf:       float64Ptr(5),
    60  		Enum:             []interface{}{"hello", "world"},
    61  	},
    62  }
    63  
    64  const headerJSON = `{
    65    "items": {
    66      "$ref": "Cat"
    67    },
    68    "x-framework": "swagger-go",
    69    "description": "the description of this header",
    70    "maximum": 100,
    71    "minimum": 5,
    72    "exclusiveMaximum": true,
    73    "exclusiveMinimum": true,
    74    "maxLength": 100,
    75    "minLength": 5,
    76    "pattern": "\\w{1,5}\\w+",
    77    "maxItems": 100,
    78    "minItems": 5,
    79    "uniqueItems": true,
    80    "multipleOf": 5,
    81    "enum": ["hello", "world"],
    82    "type": "string",
    83    "format": "date",
    84    "default": "8"
    85  }`
    86  
    87  // cmp.Diff panics when reflecting unexported fields under jsonreference.Ref
    88  // a custom comparator is required
    89  var swaggerDiffOptions = []cmp.Option{cmp.Comparer(func(a Ref, b Ref) bool {
    90  	return a.String() == b.String()
    91  })}
    92  
    93  func TestIntegrationHeader(t *testing.T) {
    94  	var actual Header
    95  	if assert.NoError(t, json.Unmarshal([]byte(headerJSON), &actual)) {
    96  		if !reflect.DeepEqual(header, actual) {
    97  			t.Fatal(cmp.Diff(header, actual, swaggerDiffOptions...))
    98  		}
    99  	}
   100  
   101  	assertParsesJSON(t, headerJSON, header)
   102  }
   103  
   104  // Makes sure that a Header unmarshaled from known good JSON, and one unmarshaled
   105  // from generated JSON are equivalent.
   106  func TestHeaderSerialization(t *testing.T) {
   107  	generatedJSON, err := json.Marshal(header)
   108  	require.NoError(t, err)
   109  
   110  	generatedJSONActual := Header{}
   111  	require.NoError(t, json.Unmarshal(generatedJSON, &generatedJSONActual))
   112  	if !reflect.DeepEqual(header, generatedJSONActual) {
   113  		t.Fatal(cmp.Diff(header, generatedJSONActual, swaggerDiffOptions...))
   114  	}
   115  
   116  	goodJSONActual := Header{}
   117  	require.NoError(t, json.Unmarshal([]byte(headerJSON), &goodJSONActual))
   118  	if !reflect.DeepEqual(header, goodJSONActual) {
   119  		t.Fatal(cmp.Diff(header, goodJSONActual, swaggerDiffOptions...))
   120  	}
   121  }
   122  
   123  func TestHeaderRoundTrip(t *testing.T) {
   124  	cases := []jsontesting.RoundTripTestCase{
   125  		{
   126  			// Show at least one field from each embededd struct sitll allows
   127  			// roundtrips successfully
   128  			Name: "UnmarshalEmbedded",
   129  			JSON: `{
   130  				"pattern": "x-^",
   131  				"type": "string",
   132  				"x-framework": "swagger-go",
   133  				"description": "the description of this header"
   134  			  }`,
   135  			Object: &Header{
   136  				CommonValidations{
   137  					Pattern: "x-^",
   138  				},
   139  				SimpleSchema{
   140  					Type: "string",
   141  				},
   142  				VendorExtensible{Extensions{
   143  					"x-framework": "swagger-go",
   144  				}},
   145  				HeaderProps{
   146  					Description: "the description of this header",
   147  				},
   148  			},
   149  		}, {
   150  			Name:   "BasicCase",
   151  			JSON:   headerJSON,
   152  			Object: &header,
   153  		},
   154  	}
   155  
   156  	for _, tcase := range cases {
   157  		t.Run(tcase.Name, func(t *testing.T) {
   158  			require.NoError(t, tcase.RoundTripTest(&Header{}))
   159  		})
   160  	}
   161  }