sigs.k8s.io/cluster-api@v1.7.1/internal/topology/variables/schema_test.go (about)

     1  /*
     2  Copyright 2021 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package variables
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
    24  	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
    25  	"k8s.io/apimachinery/pkg/util/validation/field"
    26  	"k8s.io/utils/ptr"
    27  
    28  	clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
    29  )
    30  
    31  func Test_convertToAPIExtensionsJSONSchemaProps(t *testing.T) {
    32  	defaultJSON := apiextensions.JSON(`defaultValue`)
    33  
    34  	tests := []struct {
    35  		name    string
    36  		schema  *clusterv1.JSONSchemaProps
    37  		want    *apiextensions.JSONSchemaProps
    38  		wantErr bool
    39  	}{
    40  		{
    41  			name: "pass for basic schema validation",
    42  			schema: &clusterv1.JSONSchemaProps{
    43  				Type:             "integer",
    44  				Format:           "uri",
    45  				MaxLength:        ptr.To[int64](4),
    46  				MinLength:        ptr.To[int64](2),
    47  				Pattern:          "abc.*",
    48  				Maximum:          ptr.To[int64](43),
    49  				ExclusiveMaximum: true,
    50  				Minimum:          ptr.To[int64](1),
    51  				ExclusiveMinimum: false,
    52  			},
    53  			want: &apiextensions.JSONSchemaProps{
    54  				Type:             "integer",
    55  				Format:           "uri",
    56  				MaxLength:        ptr.To[int64](4),
    57  				MinLength:        ptr.To[int64](2),
    58  				Pattern:          "abc.*",
    59  				Maximum:          ptr.To[float64](43),
    60  				ExclusiveMaximum: true,
    61  				Minimum:          ptr.To[float64](1),
    62  				ExclusiveMinimum: false,
    63  			},
    64  		},
    65  		{
    66  			name: "pass for schema validation with enum & default",
    67  			schema: &clusterv1.JSONSchemaProps{
    68  				Example: &apiextensionsv1.JSON{
    69  					Raw: []byte(`"defaultValue"`),
    70  				},
    71  				Default: &apiextensionsv1.JSON{
    72  					Raw: []byte(`"defaultValue"`),
    73  				},
    74  				Enum: []apiextensionsv1.JSON{
    75  					{Raw: []byte(`"enumValue1"`)},
    76  					{Raw: []byte(`"enumValue2"`)},
    77  				},
    78  			},
    79  			want: &apiextensions.JSONSchemaProps{
    80  				Default: &defaultJSON,
    81  				Example: &defaultJSON,
    82  				Enum: []apiextensions.JSON{
    83  					`enumValue1`,
    84  					`enumValue2`,
    85  				},
    86  			},
    87  		},
    88  		{
    89  			name: "fail for schema validation with default value with invalid JSON",
    90  			schema: &clusterv1.JSONSchemaProps{
    91  				Default: &apiextensionsv1.JSON{
    92  					Raw: []byte(`defaultValue`), // missing quotes
    93  				},
    94  			},
    95  			wantErr: true,
    96  		},
    97  		{
    98  			name: "pass for schema validation with object",
    99  			schema: &clusterv1.JSONSchemaProps{
   100  				Properties: map[string]clusterv1.JSONSchemaProps{
   101  					"property1": {
   102  						Type:    "integer",
   103  						Minimum: ptr.To[int64](1),
   104  					},
   105  					"property2": {
   106  						Type:      "string",
   107  						Format:    "uri",
   108  						MinLength: ptr.To[int64](2),
   109  						MaxLength: ptr.To[int64](4),
   110  					},
   111  				},
   112  			},
   113  			want: &apiextensions.JSONSchemaProps{
   114  				Properties: map[string]apiextensions.JSONSchemaProps{
   115  					"property1": {
   116  						Type:    "integer",
   117  						Minimum: ptr.To[float64](1),
   118  					},
   119  					"property2": {
   120  						Type:      "string",
   121  						Format:    "uri",
   122  						MinLength: ptr.To[int64](2),
   123  						MaxLength: ptr.To[int64](4),
   124  					},
   125  				},
   126  			},
   127  		},
   128  		{
   129  			name: "pass for schema validation with map",
   130  			schema: &clusterv1.JSONSchemaProps{
   131  				AdditionalProperties: &clusterv1.JSONSchemaProps{
   132  					Properties: map[string]clusterv1.JSONSchemaProps{
   133  						"property1": {
   134  							Type:    "integer",
   135  							Minimum: ptr.To[int64](1),
   136  						},
   137  						"property2": {
   138  							Type:      "string",
   139  							Format:    "uri",
   140  							MinLength: ptr.To[int64](2),
   141  							MaxLength: ptr.To[int64](4),
   142  						},
   143  					},
   144  				},
   145  			},
   146  			want: &apiextensions.JSONSchemaProps{
   147  				AdditionalProperties: &apiextensions.JSONSchemaPropsOrBool{
   148  					Allows: true,
   149  					Schema: &apiextensions.JSONSchemaProps{
   150  						Properties: map[string]apiextensions.JSONSchemaProps{
   151  							"property1": {
   152  								Type:    "integer",
   153  								Minimum: ptr.To[float64](1),
   154  							},
   155  							"property2": {
   156  								Type:      "string",
   157  								Format:    "uri",
   158  								MinLength: ptr.To[int64](2),
   159  								MaxLength: ptr.To[int64](4),
   160  							},
   161  						},
   162  					},
   163  				},
   164  			},
   165  		},
   166  		{
   167  			name: "pass for schema validation with array",
   168  			schema: &clusterv1.JSONSchemaProps{
   169  				Items: &clusterv1.JSONSchemaProps{
   170  					Type:      "integer",
   171  					Minimum:   ptr.To[int64](1),
   172  					Format:    "uri",
   173  					MinLength: ptr.To[int64](2),
   174  					MaxLength: ptr.To[int64](4),
   175  				},
   176  			},
   177  			want: &apiextensions.JSONSchemaProps{
   178  				Items: &apiextensions.JSONSchemaPropsOrArray{
   179  					Schema: &apiextensions.JSONSchemaProps{
   180  						Type:      "integer",
   181  						Minimum:   ptr.To[float64](1),
   182  						Format:    "uri",
   183  						MinLength: ptr.To[int64](2),
   184  						MaxLength: ptr.To[int64](4),
   185  					},
   186  				},
   187  			},
   188  		},
   189  	}
   190  	for _, tt := range tests {
   191  		t.Run(tt.name, func(t *testing.T) {
   192  			got, errs := convertToAPIExtensionsJSONSchemaProps(tt.schema, field.NewPath(""))
   193  			if tt.wantErr {
   194  				if len(errs) == 0 {
   195  					t.Errorf("convertToAPIExtensionsJSONSchemaProps() error = %v, wantErr %v", errs, tt.wantErr)
   196  				}
   197  				return
   198  			}
   199  			if !reflect.DeepEqual(got, tt.want) {
   200  				t.Errorf("convertToAPIExtensionsJSONSchemaProps() got = %v, want %v", got, tt.want)
   201  			}
   202  		})
   203  	}
   204  }