kubectl/pkg/explain/v2/generator_test.go
Antoine Pelisse 2c4bec21e5 openapi: Make file client more easy to re-use
A few notes about the change:
1. I need to initialize the fileclient once, in an init function, so I
don't have access to `testing.T` yet.
2. I want to be able to configure the openapi files that I use
3. We already have a "cache" client that wraps another client, we don't
need to re-implement caching here, one can just do:
`cache.NewClient(openapitest.NewFileClient("some/path"))` to do a cached
client. Or initialize it in an init/global var.

Since there is still some value to use the embedded file, make an
alternative constructor while using fs.FS interface to be able to
manipulate both virtual and disk-based filesystems.

Kubernetes-commit: 29503fd8d45bc2c9438e92936bf4111162529b40
2023-03-28 13:40:28 -07:00

110 lines
3 KiB
Go

/*
Copyright 2022 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v2
import (
"bytes"
"encoding/json"
"testing"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/openapi/openapitest"
)
var appsv1Path = "apis/apps/v1"
var appsDeploymentGVR = schema.GroupVersionResource{
Group: "apps",
Version: "v1",
Resource: "deployments",
}
// Shows generic throws error when attempting to `Render“ an invalid output name
// And if it is then added as a template, no error is thrown upon `Render`
func TestGeneratorMissingOutput(t *testing.T) {
var buf bytes.Buffer
var doc map[string]interface{}
appsv1Bytes := bytesForGV(t, appsv1Path)
err := json.Unmarshal(appsv1Bytes, &doc)
require.NoError(t, err)
gen := NewGenerator()
badTemplateName := "bad-template"
err = gen.Render(badTemplateName, doc, appsDeploymentGVR, nil, false, &buf)
require.ErrorContains(t, err, "unrecognized format: "+badTemplateName)
require.Zero(t, buf.Len())
err = gen.AddTemplate(badTemplateName, "ok")
require.NoError(t, err)
err = gen.Render(badTemplateName, doc, appsDeploymentGVR, nil, false, &buf)
require.NoError(t, err)
require.Equal(t, "ok", buf.String())
}
// Shows that correct context with the passed object is passed to the template
func TestGeneratorContext(t *testing.T) {
var buf bytes.Buffer
var doc map[string]interface{}
appsv1Bytes := bytesForGV(t, appsv1Path)
err := json.Unmarshal(appsv1Bytes, &doc)
require.NoError(t, err)
gen := NewGenerator()
err = gen.AddTemplate("Context", "{{ toJson . }}")
require.NoError(t, err)
expectedContext := TemplateContext{
Document: doc,
GVR: appsDeploymentGVR,
Recursive: false,
FieldPath: nil,
}
err = gen.Render("Context",
expectedContext.Document,
expectedContext.GVR,
expectedContext.FieldPath,
expectedContext.Recursive,
&buf)
require.NoError(t, err)
var actualContext TemplateContext
err = json.Unmarshal(buf.Bytes(), &actualContext)
require.NoError(t, err)
require.Equal(t, expectedContext, actualContext)
}
// bytesForGV returns the OpenAPI V3 spec for the passed
// group/version as a byte slice. Assumes bytes are in json
// format. The passed path string looks like:
//
// apis/apps/v1
func bytesForGV(t *testing.T, gvPath string) []byte {
fakeClient := openapitest.NewEmbeddedFileClient()
paths, err := fakeClient.Paths()
require.NoError(t, err)
gv, found := paths[gvPath]
require.True(t, found)
gvBytes, err := gv.Schema("application/json")
require.NoError(t, err)
return gvBytes
}