Server : LiteSpeed System : Linux in-mum-web1949.main-hosting.eu 5.14.0-503.40.1.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Mon May 5 06:06:04 EDT 2025 x86_64 User : u595547767 ( 595547767) PHP Version : 7.4.33 Disable Function : NONE Directory : /opt/go/pkg/mod/github.com/go-openapi/analysis@v0.23.0/internal/flatten/replace/ |
package replace
import (
"path/filepath"
"testing"
"github.com/go-openapi/analysis/internal/antest"
"github.com/go-openapi/jsonpointer"
"github.com/go-openapi/spec"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var refFixtures = []struct {
Key string
Ref spec.Ref
}{
{"#/parameters/someParam/schema", spec.MustCreateRef("#/definitions/record")},
{"#/paths/~1some~1where~1{id}/parameters/1/schema", spec.MustCreateRef("#/definitions/record")},
{"#/paths/~1some~1where~1{id}/get/parameters/2/schema", spec.MustCreateRef("#/definitions/record")},
{"#/responses/someResponse/schema", spec.MustCreateRef("#/definitions/record")},
{"#/paths/~1some~1where~1{id}/get/responses/default/schema", spec.MustCreateRef("#/definitions/record")},
{"#/paths/~1some~1where~1{id}/get/responses/200/schema", spec.MustCreateRef("#/definitions/record")},
{"#/definitions/namedAgain", spec.MustCreateRef("#/definitions/named")},
{"#/definitions/datedTag/allOf/1", spec.MustCreateRef("#/definitions/tag")},
{"#/definitions/datedRecords/items/1", spec.MustCreateRef("#/definitions/record")},
{"#/definitions/datedTaggedRecords/items/1", spec.MustCreateRef("#/definitions/record")},
{"#/definitions/datedTaggedRecords/additionalItems", spec.MustCreateRef("#/definitions/tag")},
{"#/definitions/otherRecords/items", spec.MustCreateRef("#/definitions/record")},
{"#/definitions/tags/additionalProperties", spec.MustCreateRef("#/definitions/tag")},
{"#/definitions/namedThing/properties/name", spec.MustCreateRef("#/definitions/named")},
}
func TestUpdateRef(t *testing.T) {
t.Parallel()
bp := filepath.Join("..", "..", "..", "fixtures", "external_definitions.yml")
sp := antest.LoadOrFail(t, bp)
for _, v := range refFixtures {
err := UpdateRef(sp, v.Key, v.Ref)
require.NoError(t, err)
ptr, err := jsonpointer.New(v.Key[1:])
require.NoError(t, err)
vv, _, err := ptr.Get(sp)
require.NoError(t, err)
switch tv := vv.(type) {
case *spec.Schema:
assert.Equal(t, v.Ref.String(), tv.Ref.String())
case spec.Schema:
assert.Equal(t, v.Ref.String(), tv.Ref.String())
case *spec.SchemaOrBool:
assert.Equal(t, v.Ref.String(), tv.Schema.Ref.String())
case *spec.SchemaOrArray:
assert.Equal(t, v.Ref.String(), tv.Schema.Ref.String())
default:
assert.Fail(t, "unknown type", "got %T", vv)
}
}
}
func TestRewriteSchemaRef(t *testing.T) {
t.Parallel()
bp := filepath.Join("..", "..", "..", "fixtures", "inline_schemas.yml")
sp := antest.LoadOrFail(t, bp)
for i, v := range refFixtures {
err := RewriteSchemaToRef(sp, v.Key, v.Ref)
require.NoError(t, err)
ptr, err := jsonpointer.New(v.Key[1:])
require.NoError(t, err)
vv, _, err := ptr.Get(sp)
require.NoError(t, err)
switch tv := vv.(type) {
case *spec.Schema:
assert.Equal(t, v.Ref.String(), tv.Ref.String(), "at %d for %s", i, v.Key)
case spec.Schema:
assert.Equal(t, v.Ref.String(), tv.Ref.String(), "at %d for %s", i, v.Key)
case *spec.SchemaOrBool:
assert.Equal(t, v.Ref.String(), tv.Schema.Ref.String(), "at %d for %s", i, v.Key)
case *spec.SchemaOrArray:
assert.Equal(t, v.Ref.String(), tv.Schema.Ref.String(), "at %d for %s", i, v.Key)
default:
assert.Fail(t, "unknown type", "got %T", vv)
}
}
}
func TestReplace_ErrorHandling(t *testing.T) {
t.Parallel()
const wantedFailure = "expected a failure"
bp := filepath.Join("..", "..", "..", "fixtures", "errors", "fixture-unexpandable-2.yaml")
sp := antest.LoadOrFail(t, bp)
t.Run("with invalid $ref", func(t *testing.T) {
const ref = "#/invalidPointer/key"
require.Errorf(t, RewriteSchemaToRef(sp, ref, spec.Ref{}), wantedFailure)
require.Errorf(t, rewriteParentRef(sp, ref, spec.Ref{}), wantedFailure)
require.Errorf(t, UpdateRef(sp, ref, spec.Ref{}), wantedFailure)
require.Errorf(t, UpdateRefWithSchema(sp, ref, &spec.Schema{}), wantedFailure)
_, _, err := getPointerFromKey(sp, ref)
require.Errorf(t, err, wantedFailure)
_, _, _, err = getParentFromKey(sp, ref)
require.Errorf(t, err, wantedFailure)
})
t.Run("with invalid jsonpointer formatting", func(t *testing.T) {
const pointer = "-->#/invalidJsonPointer"
_, _, err := getPointerFromKey(sp, pointer)
require.Errorf(t, err, wantedFailure)
_, _, _, err = getParentFromKey(sp, pointer)
require.Errorf(t, err, wantedFailure)
})
t.Run("with invalid target", func(t *testing.T) {
require.Errorf(t, RewriteSchemaToRef(sp, "#/parameters/someWhere", spec.Ref{}), wantedFailure)
})
t.Run("with invalid response target", func(t *testing.T) {
const ref = "#/paths/~1wrong/get/responses/200"
require.Errorf(t, RewriteSchemaToRef(sp, ref, spec.Ref{}), wantedFailure)
})
t.Run("with invalid response code", func(t *testing.T) {
const ref = "#/paths/~1wrongcode/get/responses/two-hundred"
require.Errorf(t, rewriteParentRef(sp, ref, spec.Ref{}), wantedFailure)
})
t.Run("with panic case", func(t *testing.T) {
t.Run("should not call with types other than *Schema or *Swagger", func(t *testing.T) {
require.Panics(t, func() {
_, _, _ = getPointerFromKey("oops", "#/key")
})
require.Panics(t, func() {
_, _, _, _ = getParentFromKey("oops", "#/key")
})
require.Panics(t, func() {
_ = UpdateRef("oops", "#/key", spec.Ref{})
})
})
})
}