mirror of
https://github.com/LukeHagar/libopenapi.git
synced 2025-12-09 20:47:44 +00:00
v3 Links, callbacks operations low level models at 100% coverage
This commit is contained in:
@@ -38,7 +38,7 @@ func NewLink(link *low.Link) *Link {
|
||||
l.OperationRef = link.OperationRef.Value
|
||||
l.OperationId = link.OperationId.Value
|
||||
params := make(map[string]string)
|
||||
for k, v := range link.Parameters.Value {
|
||||
for k, v := range link.Parameters {
|
||||
params[k.Value] = v.Value
|
||||
}
|
||||
l.Parameters = params
|
||||
|
||||
@@ -4,9 +4,12 @@
|
||||
package v3
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
"gopkg.in/yaml.v3"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Callback represents a low-level Callback object for OpenAPI 3+.
|
||||
@@ -59,3 +62,18 @@ func (cb *Callback) Build(root *yaml.Node, idx *index.SpecIndex) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Hash will return a consistent SHA256 Hash of the Callback object
|
||||
func (cb *Callback) Hash() [32]byte {
|
||||
var f []string
|
||||
var keys []string
|
||||
keys = make([]string, len(cb.Expression.Value))
|
||||
z := 0
|
||||
for k := range cb.Expression.Value {
|
||||
keys[z] = low.GenerateHashString(cb.Expression.Value[k].Value)
|
||||
z++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
f = append(f, keys...)
|
||||
return sha256.Sum256([]byte(strings.Join(f, "|")))
|
||||
}
|
||||
|
||||
@@ -111,3 +111,44 @@ func TestCallback_Build_Using_InlineRef(t *testing.T) {
|
||||
assert.Equal(t, "this is something", exp.Value.Post.Value.RequestBody.Value.Description.Value)
|
||||
|
||||
}
|
||||
|
||||
func TestCallback_Hash(t *testing.T) {
|
||||
|
||||
yml := `x-seed: grow
|
||||
pizza:
|
||||
description: cheesy
|
||||
burgers:
|
||||
description: tasty!
|
||||
beer:
|
||||
description: fantastic
|
||||
x-weed: loved`
|
||||
|
||||
var idxNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(yml), &idxNode)
|
||||
idx := index.NewSpecIndex(&idxNode)
|
||||
|
||||
var n Callback
|
||||
_ = low.BuildModel(idxNode.Content[0], &n)
|
||||
_ = n.Build(idxNode.Content[0], idx)
|
||||
|
||||
yml2 := `burgers:
|
||||
description: tasty!
|
||||
pizza:
|
||||
description: cheesy
|
||||
x-weed: loved
|
||||
x-seed: grow
|
||||
beer:
|
||||
description: fantastic
|
||||
`
|
||||
var idxNode2 yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(yml2), &idxNode2)
|
||||
idx2 := index.NewSpecIndex(&idxNode2)
|
||||
|
||||
var n2 Callback
|
||||
_ = low.BuildModel(idxNode2.Content[0], &n2)
|
||||
_ = n2.Build(idxNode2.Content[0], idx2)
|
||||
|
||||
// hash
|
||||
assert.Equal(t, n.Hash(), n2.Hash())
|
||||
|
||||
}
|
||||
|
||||
@@ -141,5 +141,4 @@ example: a thing`
|
||||
|
||||
// hash
|
||||
assert.Equal(t, n.Hash(), n2.Hash())
|
||||
|
||||
}
|
||||
|
||||
@@ -182,16 +182,22 @@ func (o *Operation) Hash() [32]byte {
|
||||
for k := range o.Parameters.Value {
|
||||
keys[k] = low.GenerateHashString(o.Parameters.Value[k].Value)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
f = append(f, keys...)
|
||||
|
||||
keys = make([]string, len(o.Callbacks.Value))
|
||||
z := 0
|
||||
for k := range o.Callbacks.Value {
|
||||
keys[z] = low.GenerateHashString(o.Callbacks.Value[k].Value)
|
||||
z++
|
||||
}
|
||||
sort.Strings(keys)
|
||||
f = append(f, keys...)
|
||||
|
||||
for k := range o.Extensions {
|
||||
f = append(f, fmt.Sprintf("%s-%x", k.Value,
|
||||
sha256.Sum256([]byte(fmt.Sprint(o.Extensions[k].Value)))))
|
||||
}
|
||||
|
||||
// TODO: add callbacks in here.
|
||||
|
||||
return sha256.Sum256([]byte(strings.Join(f, "|")))
|
||||
}
|
||||
|
||||
@@ -200,15 +206,12 @@ func (o *Operation) Hash() [32]byte {
|
||||
func (o *Operation) GetTags() low.NodeReference[[]low.ValueReference[string]] {
|
||||
return o.Tags
|
||||
}
|
||||
|
||||
func (o *Operation) GetSummary() low.NodeReference[string] {
|
||||
return o.Summary
|
||||
}
|
||||
|
||||
func (o *Operation) GetDescription() low.NodeReference[string] {
|
||||
return o.Description
|
||||
}
|
||||
|
||||
func (o *Operation) GetExternalDocs() low.NodeReference[any] {
|
||||
return low.NodeReference[any]{
|
||||
ValueNode: o.ExternalDocs.ValueNode,
|
||||
@@ -216,19 +219,15 @@ func (o *Operation) GetExternalDocs() low.NodeReference[any] {
|
||||
Value: o.ExternalDocs.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Operation) GetOperationId() low.NodeReference[string] {
|
||||
return o.OperationId
|
||||
}
|
||||
|
||||
func (o *Operation) GetDeprecated() low.NodeReference[bool] {
|
||||
return o.Deprecated
|
||||
}
|
||||
|
||||
func (o *Operation) GetExtensions() map[low.KeyReference[string]]low.ValueReference[any] {
|
||||
return o.Extensions
|
||||
}
|
||||
|
||||
func (o *Operation) GetResponses() low.NodeReference[any] {
|
||||
return low.NodeReference[any]{
|
||||
ValueNode: o.Responses.ValueNode,
|
||||
@@ -236,7 +235,6 @@ func (o *Operation) GetResponses() low.NodeReference[any] {
|
||||
Value: o.Responses.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Operation) GetParameters() low.NodeReference[any] {
|
||||
return low.NodeReference[any]{
|
||||
ValueNode: o.Parameters.ValueNode,
|
||||
@@ -244,7 +242,6 @@ func (o *Operation) GetParameters() low.NodeReference[any] {
|
||||
Value: o.Parameters.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Operation) GetSecurity() low.NodeReference[any] {
|
||||
return low.NodeReference[any]{
|
||||
ValueNode: o.Security.ValueNode,
|
||||
@@ -252,7 +249,6 @@ func (o *Operation) GetSecurity() low.NodeReference[any] {
|
||||
Value: o.Security.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Operation) GetServers() low.NodeReference[any] {
|
||||
return low.NodeReference[any]{
|
||||
ValueNode: o.Servers.ValueNode,
|
||||
@@ -260,7 +256,6 @@ func (o *Operation) GetServers() low.NodeReference[any] {
|
||||
Value: o.Servers.Value,
|
||||
}
|
||||
}
|
||||
|
||||
//func (o *Operation) GetCallbacks() low.NodeReference[[]low.ValueReference[any]] {
|
||||
// return o.Produces
|
||||
//}
|
||||
func (o *Operation) GetCallbacks() low.NodeReference[map[low.KeyReference[string]]low.ValueReference[*Callback]] {
|
||||
return o.Callbacks
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ package v3
|
||||
|
||||
import (
|
||||
"github.com/pb33f/libopenapi/datamodel/low"
|
||||
"github.com/pb33f/libopenapi/datamodel/low/base"
|
||||
"github.com/pb33f/libopenapi/index"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
@@ -191,3 +192,97 @@ func TestOperation_Build_FailServers(t *testing.T) {
|
||||
err = n.Build(idxNode.Content[0], idx)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestOperation_Hash_n_Grab(t *testing.T) {
|
||||
|
||||
yml := `tags:
|
||||
- nice
|
||||
- rice
|
||||
summary: a thing
|
||||
description: another thing
|
||||
externalDocs:
|
||||
url: https://pb33f.io/docs
|
||||
operationId: sleepyMornings
|
||||
parameters:
|
||||
- name: parammy
|
||||
in: my head
|
||||
requestBody:
|
||||
description: a thing
|
||||
responses:
|
||||
"200":
|
||||
description: ok
|
||||
callbacks:
|
||||
callMe:
|
||||
something: blue
|
||||
deprecated: true
|
||||
security:
|
||||
- lego:
|
||||
dont: stand
|
||||
or: eat
|
||||
servers:
|
||||
- url: https://pb33f.io
|
||||
x-mint: sweet`
|
||||
|
||||
var idxNode yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(yml), &idxNode)
|
||||
idx := index.NewSpecIndex(&idxNode)
|
||||
|
||||
var n Operation
|
||||
_ = low.BuildModel(idxNode.Content[0], &n)
|
||||
_ = n.Build(idxNode.Content[0], idx)
|
||||
|
||||
yml2 := `tags:
|
||||
- nice
|
||||
- rice
|
||||
summary: a thing
|
||||
description: another thing
|
||||
externalDocs:
|
||||
url: https://pb33f.io/docs
|
||||
operationId: sleepyMornings
|
||||
parameters:
|
||||
- name: parammy
|
||||
in: my head
|
||||
requestBody:
|
||||
description: a thing
|
||||
responses:
|
||||
"200":
|
||||
description: ok
|
||||
callbacks:
|
||||
callMe:
|
||||
something: blue
|
||||
deprecated: true
|
||||
security:
|
||||
- lego:
|
||||
dont: stand
|
||||
or: eat
|
||||
servers:
|
||||
- url: https://pb33f.io
|
||||
x-mint: sweet`
|
||||
|
||||
var idxNode2 yaml.Node
|
||||
_ = yaml.Unmarshal([]byte(yml2), &idxNode2)
|
||||
idx2 := index.NewSpecIndex(&idxNode2)
|
||||
|
||||
var n2 Operation
|
||||
_ = low.BuildModel(idxNode2.Content[0], &n2)
|
||||
_ = n2.Build(idxNode2.Content[0], idx2)
|
||||
|
||||
// hash
|
||||
assert.Equal(t, n.Hash(), n2.Hash())
|
||||
|
||||
// n grab
|
||||
assert.Len(t, n.GetTags().Value, 2)
|
||||
assert.Equal(t, "a thing", n.GetSummary().Value)
|
||||
assert.Equal(t, "another thing", n.GetDescription().Value)
|
||||
assert.Equal(t, "https://pb33f.io/docs", n.GetExternalDocs().Value.(*base.ExternalDoc).URL.Value)
|
||||
assert.Equal(t, "sleepyMornings", n.GetOperationId().Value)
|
||||
assert.Len(t, n.GetParameters().Value, 1)
|
||||
assert.Len(t, n.GetSecurity().Value, 1)
|
||||
assert.True(t, n.GetDeprecated().Value)
|
||||
assert.Len(t, n.GetExtensions(), 1)
|
||||
assert.Len(t, n.GetServers().Value.([]low.ValueReference[*Server]), 1)
|
||||
assert.Len(t, n.GetCallbacks().Value, 1)
|
||||
assert.Len(t, n.GetResponses().Value.(*Responses).Codes, 1)
|
||||
assert.Nil(t, n.FindSecurityRequirement("I do not exist"))
|
||||
|
||||
}
|
||||
|
||||
@@ -109,11 +109,11 @@ func CompareLinks(l, r *v3.Link) *LinkChanges {
|
||||
// parameters
|
||||
lValues := make(map[string]low.ValueReference[string])
|
||||
rValues := make(map[string]low.ValueReference[string])
|
||||
for i := range l.Parameters.Value {
|
||||
lValues[i.Value] = l.Parameters.Value[i]
|
||||
for i := range l.Parameters {
|
||||
lValues[i.Value] = l.Parameters[i]
|
||||
}
|
||||
for i := range r.Parameters.Value {
|
||||
rValues[i.Value] = r.Parameters.Value[i]
|
||||
for i := range r.Parameters {
|
||||
rValues[i.Value] = r.Parameters[i]
|
||||
}
|
||||
for k := range lValues {
|
||||
if _, ok := rValues[k]; !ok {
|
||||
|
||||
Reference in New Issue
Block a user