mirror of
https://github.com/rancher/steve.git
synced 2025-09-03 08:25:13 +00:00
Adding tests for schemaDefinitions
This commit is contained in:
325
pkg/schema/definitions/handler_test.go
Normal file
325
pkg/schema/definitions/handler_test.go
Normal file
@@ -0,0 +1,325 @@
|
||||
package definitions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
openapi_v2 "github.com/google/gnostic-models/openapiv2"
|
||||
"github.com/rancher/apiserver/pkg/apierror"
|
||||
"github.com/rancher/apiserver/pkg/types"
|
||||
wschemas "github.com/rancher/wrangler/v2/pkg/schemas"
|
||||
"github.com/stretchr/testify/require"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/openapi"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
var globalRoleObject = types.APIObject{
|
||||
ID: "management.cattle.io.globalrole",
|
||||
Type: "schemaDefinition",
|
||||
Object: schemaDefinition{
|
||||
DefinitionType: "io.cattle.management.v2.GlobalRole",
|
||||
Definitions: map[string]definition{
|
||||
"io.cattle.management.v2.GlobalRole": {
|
||||
ResourceFields: map[string]definitionField{
|
||||
"apiVersion": {
|
||||
Type: "string",
|
||||
Description: "The APIVersion of this resource",
|
||||
},
|
||||
"kind": {
|
||||
Type: "string",
|
||||
Description: "The kind",
|
||||
},
|
||||
"metadata": {
|
||||
Type: "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta",
|
||||
Description: "The metadata",
|
||||
},
|
||||
"spec": {
|
||||
Type: "io.cattle.management.v2.GlobalRole.spec", Description: "The spec for the project",
|
||||
},
|
||||
},
|
||||
Type: "io.cattle.management.v2.GlobalRole",
|
||||
Description: "A Global Role V2 provides Global Permissions in Rancher",
|
||||
},
|
||||
"io.cattle.management.v2.GlobalRole.spec": {
|
||||
ResourceFields: map[string]definitionField{
|
||||
"clusterName": {
|
||||
Type: "string",
|
||||
Description: "The name of the cluster",
|
||||
Required: true,
|
||||
},
|
||||
"displayName": {
|
||||
Type: "string",
|
||||
Description: "The UI readable name",
|
||||
Required: true,
|
||||
},
|
||||
"newField": {
|
||||
Type: "string",
|
||||
Description: "A new field not present in v1",
|
||||
},
|
||||
"notRequired": {
|
||||
Type: "boolean",
|
||||
Description: "Some field that isn't required",
|
||||
},
|
||||
},
|
||||
Type: "io.cattle.management.v2.GlobalRole.spec",
|
||||
Description: "The spec for the project",
|
||||
},
|
||||
"io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": {
|
||||
ResourceFields: map[string]definitionField{
|
||||
"annotations": {
|
||||
Type: "map",
|
||||
SubType: "string",
|
||||
Description: "annotations of the resource",
|
||||
},
|
||||
"name": {
|
||||
Type: "string",
|
||||
SubType: "",
|
||||
Description: "name of the resource",
|
||||
},
|
||||
},
|
||||
Type: "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta",
|
||||
Description: "Object Metadata",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestByID(t *testing.T) {
|
||||
schemas := types.EmptyAPISchemas()
|
||||
addBaseSchema := func(names ...string) {
|
||||
for _, name := range names {
|
||||
schemas.MustAddSchema(types.APISchema{
|
||||
Schema: &wschemas.Schema{
|
||||
ID: name,
|
||||
CollectionMethods: []string{"get"},
|
||||
ResourceMethods: []string{"get"},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
intPtr := func(input int) *int {
|
||||
return &input
|
||||
}
|
||||
|
||||
addBaseSchema("management.cattle.io.globalrole", "management.cattle.io.missingfrommodel")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
schemaName string
|
||||
needsRefresh bool
|
||||
openapiError error
|
||||
serverGroupsResourcesErr error
|
||||
useBadOpenApiDoc bool
|
||||
unparseableGV bool
|
||||
wantObject *types.APIObject
|
||||
wantError bool
|
||||
wantErrorCode *int
|
||||
}{
|
||||
{
|
||||
name: "global role definition",
|
||||
schemaName: "management.cattle.io.globalrole",
|
||||
needsRefresh: true,
|
||||
wantObject: &globalRoleObject,
|
||||
},
|
||||
{
|
||||
name: "missing definition",
|
||||
schemaName: "management.cattle.io.cluster",
|
||||
needsRefresh: true,
|
||||
wantError: true,
|
||||
wantErrorCode: intPtr(404),
|
||||
},
|
||||
{
|
||||
name: "not refreshed",
|
||||
schemaName: "management.cattle.io.globalrole",
|
||||
needsRefresh: false,
|
||||
wantError: true,
|
||||
wantErrorCode: intPtr(503),
|
||||
},
|
||||
{
|
||||
name: "missing from model",
|
||||
schemaName: "management.cattle.io.missingfrommodel",
|
||||
needsRefresh: true,
|
||||
wantError: true,
|
||||
wantErrorCode: intPtr(503),
|
||||
},
|
||||
{
|
||||
name: "refresh error - openapi doc unavailable",
|
||||
schemaName: "management.cattle.io.globalrole",
|
||||
needsRefresh: true,
|
||||
openapiError: fmt.Errorf("server unavailable"),
|
||||
wantError: true,
|
||||
wantErrorCode: intPtr(500),
|
||||
},
|
||||
{
|
||||
name: "refresh error - unable to parse openapi doc",
|
||||
schemaName: "management.cattle.io.globalrole",
|
||||
needsRefresh: true,
|
||||
useBadOpenApiDoc: true,
|
||||
wantError: true,
|
||||
wantErrorCode: intPtr(500),
|
||||
},
|
||||
{
|
||||
name: "refresh error - unable to retrieve groups and resources",
|
||||
schemaName: "management.cattle.io.globalrole",
|
||||
needsRefresh: true,
|
||||
serverGroupsResourcesErr: fmt.Errorf("server not available"),
|
||||
wantError: true,
|
||||
wantErrorCode: intPtr(500),
|
||||
},
|
||||
{
|
||||
name: "refresh error - unable to retrieve all groups and resources",
|
||||
schemaName: "management.cattle.io.globalrole",
|
||||
needsRefresh: true,
|
||||
serverGroupsResourcesErr: &discovery.ErrGroupDiscoveryFailed{
|
||||
Groups: map[schema.GroupVersion]error{
|
||||
{
|
||||
Group: "other.cattle.io",
|
||||
Version: "v1",
|
||||
}: fmt.Errorf("some group error"),
|
||||
},
|
||||
},
|
||||
wantError: true,
|
||||
wantErrorCode: intPtr(500),
|
||||
},
|
||||
{
|
||||
name: "refresh error - unparesable gv",
|
||||
schemaName: "management.cattle.io.globalrole",
|
||||
needsRefresh: true,
|
||||
unparseableGV: true,
|
||||
wantError: true,
|
||||
wantErrorCode: intPtr(500),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
test := test
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client, err := buildDefaultDiscovery()
|
||||
client.DocumentErr = test.openapiError
|
||||
client.GroupResourcesErr = test.serverGroupsResourcesErr
|
||||
if test.useBadOpenApiDoc {
|
||||
schema := client.Document.Definitions.AdditionalProperties[0]
|
||||
schema.Value.Type = &openapi_v2.TypeItem{
|
||||
Value: []string{"multiple", "entries"},
|
||||
}
|
||||
}
|
||||
if test.unparseableGV {
|
||||
client.Resources = append(client.Resources, &metav1.APIResourceList{
|
||||
GroupVersion: "not/parse/able",
|
||||
})
|
||||
}
|
||||
require.Nil(t, err)
|
||||
handler := schemaDefinitionHandler{
|
||||
client: client,
|
||||
}
|
||||
if !test.needsRefresh {
|
||||
handler.lastRefresh = time.Now()
|
||||
handler.refreshStale = time.Minute * 1
|
||||
}
|
||||
request := types.APIRequest{
|
||||
Schemas: schemas,
|
||||
Name: test.schemaName,
|
||||
}
|
||||
response, err := handler.byIDHandler(&request)
|
||||
if test.wantError {
|
||||
require.Error(t, err)
|
||||
if test.wantErrorCode != nil {
|
||||
require.True(t, apierror.IsAPIError(err))
|
||||
apiErr, _ := err.(*apierror.APIError)
|
||||
require.Equal(t, *test.wantErrorCode, apiErr.Code.Status)
|
||||
}
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, *test.wantObject, response)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func buildDefaultDiscovery() (*fakeDiscovery, error) {
|
||||
document, err := openapi_v2.ParseDocument([]byte(openapi_raw))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse openapi document %w", err)
|
||||
}
|
||||
groups := []*metav1.APIGroup{
|
||||
{
|
||||
Name: "management.cattle.io",
|
||||
PreferredVersion: metav1.GroupVersionForDiscovery{
|
||||
Version: "v2",
|
||||
},
|
||||
},
|
||||
}
|
||||
resources := []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: schema.GroupVersion{
|
||||
Group: "management.cattle.io",
|
||||
Version: "v2",
|
||||
}.String(),
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Group: "management.cattle.io",
|
||||
Kind: "GlobalRole",
|
||||
Version: "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
GroupVersion: schema.GroupVersion{
|
||||
Group: "management.cattle.io",
|
||||
Version: "v1",
|
||||
}.String(),
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Group: "management.cattle.io",
|
||||
Kind: "GlobalRole",
|
||||
Version: "v2",
|
||||
},
|
||||
},
|
||||
},
|
||||
nil,
|
||||
}
|
||||
return &fakeDiscovery{
|
||||
Groups: groups,
|
||||
Resources: resources,
|
||||
Document: document,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type fakeDiscovery struct {
|
||||
Groups []*metav1.APIGroup
|
||||
Resources []*metav1.APIResourceList
|
||||
Document *openapi_v2.Document
|
||||
GroupResourcesErr error
|
||||
DocumentErr error
|
||||
}
|
||||
|
||||
// ServerGroupsAndResources is the only method we actually need for the test - just returns what is on the struct
|
||||
func (f *fakeDiscovery) ServerGroupsAndResources() ([]*metav1.APIGroup, []*metav1.APIResourceList, error) {
|
||||
return f.Groups, f.Resources, f.GroupResourcesErr
|
||||
}
|
||||
|
||||
// The rest of these methods are just here to conform to discovery.DiscoveryInterface
|
||||
func (f *fakeDiscovery) RESTClient() restclient.Interface { return nil }
|
||||
func (f *fakeDiscovery) ServerGroups() (*metav1.APIGroupList, error) { return nil, nil }
|
||||
func (f *fakeDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *fakeDiscovery) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *fakeDiscovery) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *fakeDiscovery) ServerVersion() (*version.Info, error) { return nil, nil }
|
||||
func (f *fakeDiscovery) OpenAPISchema() (*openapi_v2.Document, error) {
|
||||
return f.Document, f.DocumentErr
|
||||
}
|
||||
func (f *fakeDiscovery) OpenAPIV3() openapi.Client { return nil }
|
||||
func (f *fakeDiscovery) WithLegacy() discovery.DiscoveryInterface { return f }
|
99
pkg/schema/definitions/openapi_test.go
Normal file
99
pkg/schema/definitions/openapi_test.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package definitions
|
||||
|
||||
const openapi_raw = `
|
||||
swagger: "2.0"
|
||||
info:
|
||||
title: "Test openapi spec"
|
||||
version: "v1.0.0"
|
||||
paths:
|
||||
/apis/management.cattle.io/v3/globalroles:
|
||||
get:
|
||||
description: "get a global role"
|
||||
responses:
|
||||
200:
|
||||
description: "OK"
|
||||
definitions:
|
||||
io.cattle.management.v1.GlobalRole:
|
||||
description: "A Global Role V1 provides Global Permissions in Rancher"
|
||||
type: "object"
|
||||
properties:
|
||||
apiVersion:
|
||||
description: "The APIVersion of this resource"
|
||||
type: "string"
|
||||
kind:
|
||||
description: "The kind"
|
||||
type: "string"
|
||||
metadata:
|
||||
description: "The metadata"
|
||||
$ref: "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"
|
||||
spec:
|
||||
description: "The spec for the project"
|
||||
type: "object"
|
||||
required:
|
||||
- "clusterName"
|
||||
- "displayName"
|
||||
properties:
|
||||
clusterName:
|
||||
description: "The name of the cluster"
|
||||
type: "string"
|
||||
displayName:
|
||||
description: "The UI readable name"
|
||||
type: "string"
|
||||
notRequired:
|
||||
description: "Some field that isn't required"
|
||||
type: "boolean"
|
||||
x-kubernetes-group-version-kind:
|
||||
- group: "management.cattle.io"
|
||||
version: "v1"
|
||||
kind: "GlobalRole"
|
||||
io.cattle.management.v2.GlobalRole:
|
||||
description: "A Global Role V2 provides Global Permissions in Rancher"
|
||||
type: "object"
|
||||
properties:
|
||||
apiVersion:
|
||||
description: "The APIVersion of this resource"
|
||||
type: "string"
|
||||
kind:
|
||||
description: "The kind"
|
||||
type: "string"
|
||||
metadata:
|
||||
description: "The metadata"
|
||||
$ref: "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"
|
||||
spec:
|
||||
description: "The spec for the project"
|
||||
type: "object"
|
||||
required:
|
||||
- "clusterName"
|
||||
- "displayName"
|
||||
properties:
|
||||
clusterName:
|
||||
description: "The name of the cluster"
|
||||
type: "string"
|
||||
displayName:
|
||||
description: "The UI readable name"
|
||||
type: "string"
|
||||
notRequired:
|
||||
description: "Some field that isn't required"
|
||||
type: "boolean"
|
||||
newField:
|
||||
description: "A new field not present in v1"
|
||||
type: "string"
|
||||
x-kubernetes-group-version-kind:
|
||||
- group: "management.cattle.io"
|
||||
version: "v2"
|
||||
kind: "GlobalRole"
|
||||
io.management.cattle.NotAKind:
|
||||
type: "string"
|
||||
description: "Some string which isn't a kind"
|
||||
io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta:
|
||||
description: "Object Metadata"
|
||||
properties:
|
||||
annotations:
|
||||
description: "annotations of the resource"
|
||||
type: "object"
|
||||
additionalProperties:
|
||||
type: "string"
|
||||
name:
|
||||
description: "name of the resource"
|
||||
type: "string"
|
||||
`
|
259
pkg/schema/definitions/visitor_test.go
Normal file
259
pkg/schema/definitions/visitor_test.go
Normal file
@@ -0,0 +1,259 @@
|
||||
package definitions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
protoPrimitive = proto.Primitive{
|
||||
BaseSchema: proto.BaseSchema{
|
||||
Description: "primitive value",
|
||||
},
|
||||
Type: "string",
|
||||
}
|
||||
protoPrimitiveInt = proto.Primitive{
|
||||
BaseSchema: proto.BaseSchema{
|
||||
Description: "primitive value - int",
|
||||
},
|
||||
Type: "integer",
|
||||
}
|
||||
protoPrimitiveNumber = proto.Primitive{
|
||||
BaseSchema: proto.BaseSchema{
|
||||
Description: "primitive value - number",
|
||||
},
|
||||
Type: "number",
|
||||
}
|
||||
protoArray = proto.Array{
|
||||
BaseSchema: proto.BaseSchema{
|
||||
Description: "testArray",
|
||||
},
|
||||
SubType: &protoPrimitive,
|
||||
}
|
||||
protoMap = proto.Map{
|
||||
BaseSchema: proto.BaseSchema{
|
||||
Description: "testMap",
|
||||
},
|
||||
SubType: &protoPrimitive,
|
||||
}
|
||||
protoKind = proto.Kind{
|
||||
BaseSchema: proto.BaseSchema{
|
||||
Description: "testKind",
|
||||
Path: proto.NewPath("io.cattle.test"),
|
||||
},
|
||||
Fields: map[string]proto.Schema{
|
||||
"protoArray": &protoArray,
|
||||
"protoPrimitive": &protoPrimitive,
|
||||
"protoMap": &protoMap,
|
||||
},
|
||||
RequiredFields: []string{
|
||||
"protoArray",
|
||||
"protoPrimitive",
|
||||
"missing",
|
||||
},
|
||||
}
|
||||
protoRefNoSubSchema = testRef{
|
||||
BaseSchema: proto.BaseSchema{
|
||||
Description: "testRef - no subSchema",
|
||||
},
|
||||
reference: "some-other-type",
|
||||
}
|
||||
protoRef = testRef{
|
||||
BaseSchema: proto.BaseSchema{
|
||||
Description: "testRef",
|
||||
},
|
||||
reference: "testKind",
|
||||
subSchema: &protoKind,
|
||||
}
|
||||
protoArbitrary = proto.Arbitrary{
|
||||
BaseSchema: proto.BaseSchema{
|
||||
Description: "testArbitrary",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// testRef implements proto.Reference to test VisitReference
|
||||
type testRef struct {
|
||||
proto.BaseSchema
|
||||
reference string
|
||||
subSchema proto.Schema
|
||||
}
|
||||
|
||||
func (t *testRef) Reference() string {
|
||||
return t.reference
|
||||
}
|
||||
|
||||
func (t *testRef) SubSchema() proto.Schema {
|
||||
return t.subSchema
|
||||
}
|
||||
|
||||
func (t *testRef) Accept(v proto.SchemaVisitor) {
|
||||
v.VisitReference(t)
|
||||
}
|
||||
|
||||
func (t *testRef) GetName() string {
|
||||
return fmt.Sprintf("Reference to %q", t.reference)
|
||||
}
|
||||
|
||||
func TestSchemaFieldVisitor(t *testing.T) {
|
||||
protoKind.Fields["protoRef"] = &protoRef
|
||||
tests := []struct {
|
||||
name string
|
||||
inputSchema proto.Schema
|
||||
wantDefinitions map[string]definition
|
||||
wantField definitionField
|
||||
}{
|
||||
{
|
||||
name: "array",
|
||||
inputSchema: &protoArray,
|
||||
wantDefinitions: map[string]definition{},
|
||||
wantField: definitionField{
|
||||
Type: "array",
|
||||
Description: protoArray.Description,
|
||||
SubType: protoPrimitive.Type,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "map",
|
||||
inputSchema: &protoMap,
|
||||
wantDefinitions: map[string]definition{},
|
||||
wantField: definitionField{
|
||||
Type: "map",
|
||||
Description: protoMap.Description,
|
||||
SubType: protoPrimitive.Type,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "string primitive",
|
||||
inputSchema: &protoPrimitive,
|
||||
wantDefinitions: map[string]definition{},
|
||||
wantField: definitionField{
|
||||
Type: protoPrimitive.Type,
|
||||
Description: protoPrimitive.Description,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "integer primitive",
|
||||
inputSchema: &protoPrimitiveInt,
|
||||
wantDefinitions: map[string]definition{},
|
||||
wantField: definitionField{
|
||||
Type: "int",
|
||||
Description: protoPrimitiveInt.Description,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "number primitive",
|
||||
inputSchema: &protoPrimitiveNumber,
|
||||
wantDefinitions: map[string]definition{},
|
||||
wantField: definitionField{
|
||||
Type: "int",
|
||||
Description: protoPrimitiveNumber.Description,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "kind",
|
||||
inputSchema: &protoKind,
|
||||
wantDefinitions: map[string]definition{
|
||||
protoKind.Path.String(): {
|
||||
ResourceFields: map[string]definitionField{
|
||||
"protoArray": {
|
||||
Type: "array",
|
||||
Description: protoArray.Description,
|
||||
SubType: protoPrimitive.Type,
|
||||
Required: true,
|
||||
},
|
||||
"protoMap": {
|
||||
Type: "map",
|
||||
Description: protoMap.Description,
|
||||
SubType: protoPrimitive.Type,
|
||||
},
|
||||
"protoPrimitive": {
|
||||
Type: protoPrimitive.Type,
|
||||
Description: protoPrimitive.Description,
|
||||
Required: true,
|
||||
},
|
||||
"protoRef": {
|
||||
Type: protoKind.Path.String(),
|
||||
Description: protoRef.Description,
|
||||
},
|
||||
},
|
||||
Type: protoKind.Path.String(),
|
||||
Description: protoKind.Description,
|
||||
},
|
||||
},
|
||||
wantField: definitionField{
|
||||
Description: protoKind.Description,
|
||||
Type: protoKind.Path.String(),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "reference no subschema",
|
||||
inputSchema: &protoRefNoSubSchema,
|
||||
wantDefinitions: map[string]definition{},
|
||||
wantField: definitionField{
|
||||
Type: protoRefNoSubSchema.reference,
|
||||
Description: protoRefNoSubSchema.Description,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "reference",
|
||||
inputSchema: &protoRef,
|
||||
wantDefinitions: map[string]definition{
|
||||
protoKind.Path.String(): {
|
||||
ResourceFields: map[string]definitionField{
|
||||
"protoArray": {
|
||||
Type: "array",
|
||||
Description: protoArray.Description,
|
||||
SubType: protoPrimitive.Type,
|
||||
Required: true,
|
||||
},
|
||||
"protoMap": {
|
||||
Type: "map",
|
||||
Description: protoMap.Description,
|
||||
SubType: protoPrimitive.Type,
|
||||
},
|
||||
"protoPrimitive": {
|
||||
Type: protoPrimitive.Type,
|
||||
Description: protoPrimitive.Description,
|
||||
Required: true,
|
||||
},
|
||||
"protoRef": {
|
||||
Type: protoKind.Path.String(),
|
||||
Description: protoRef.Description,
|
||||
},
|
||||
},
|
||||
Type: protoKind.Path.String(),
|
||||
Description: protoKind.Description,
|
||||
},
|
||||
},
|
||||
wantField: definitionField{
|
||||
Type: protoKind.Path.String(),
|
||||
Description: protoRef.Description,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "abitrary schema",
|
||||
inputSchema: &protoArbitrary,
|
||||
wantDefinitions: map[string]definition{},
|
||||
wantField: definitionField{
|
||||
Type: "string",
|
||||
Description: protoArbitrary.Description,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
definitions := map[string]definition{}
|
||||
visitor := schemaFieldVisitor{
|
||||
definitions: definitions,
|
||||
}
|
||||
test.inputSchema.Accept(&visitor)
|
||||
require.Equal(t, test.wantField, visitor.field)
|
||||
require.Equal(t, test.wantDefinitions, visitor.definitions)
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user