Skip to content

Commit

Permalink
feat: add server variable extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
geffersonFerraz committed Aug 28, 2024
1 parent 49a2921 commit 45c9c61
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 6 deletions.
9 changes: 6 additions & 3 deletions datamodel/high/v3/server_variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package v3
import (
"github.com/pb33f/libopenapi/datamodel/high"
low "github.com/pb33f/libopenapi/datamodel/low/v3"
"github.com/pb33f/libopenapi/orderedmap"
"gopkg.in/yaml.v3"
)

Expand All @@ -14,9 +15,10 @@ import (
// ServerVariable is an object representing a Server Variable for server URL template substitution.
// - https://spec.openapis.org/oas/v3.1.0#server-variable-object
type ServerVariable struct {
Enum []string `json:"enum,omitempty" yaml:"enum,omitempty"`
Default string `json:"default,omitempty" yaml:"default,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Enum []string `json:"enum,omitempty" yaml:"enum,omitempty"`
Default string `json:"default,omitempty" yaml:"default,omitempty"`
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Extensions *orderedmap.Map[string, *yaml.Node] `json:"-" yaml:"-"`
low *low.ServerVariable
}

Expand All @@ -33,6 +35,7 @@ func NewServerVariable(variable *low.ServerVariable) *ServerVariable {
v.Default = variable.Default.Value
v.Description = variable.Description.Value
v.Enum = enums
v.Extensions = high.ExtractExtensions(variable.Extensions)
return v
}

Expand Down
67 changes: 66 additions & 1 deletion datamodel/high/v3/server_variable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
package v3

import (
"github.com/stretchr/testify/assert"
"strings"
"testing"

"github.com/pb33f/libopenapi/orderedmap"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
)

func TestServerVariable_MarshalYAML(t *testing.T) {
Expand Down Expand Up @@ -41,3 +44,65 @@ description: money day`

assert.Equal(t, desired, strings.TrimSpace(string(svarRend)))
}

func TestServerVariableExtension_MarshalYAML(t *testing.T) {
createExtension := func(value interface{}) *yaml.Node {
node := &yaml.Node{}
err := node.Encode(value)
if err != nil {
// Trate o erro conforme necessário
}
return node
}

svar := &ServerVariable{
Extensions: orderedmap.New[string, *yaml.Node](),
}
transform := []map[string]interface{}{
{
"type": "translate",
"allowMissing": true,
"translations": []map[string]string{
{"from": "pt-br", "to": "en-us"},
},
},
}
svar.Extensions.Set("x-transforms", createExtension(transform))

desired := `x-transforms:
- allowMissing: true
translations:
- from: pt-br
to: en-us
type: translate`

svarRend, _ := svar.Render()

assert.Equal(t, desired, strings.TrimSpace(string(svarRend)))

// mutate

svar.Default = "es-mx"
transform = []map[string]interface{}{
{
"type": "translate",
"allowMissing": true,
"translations": []map[string]string{
{"from": "es-mx", "to": "en-us"},
},
},
}
svar.Extensions.Set("x-transforms", createExtension(transform))

desired = `default: es-mx
x-transforms:
- allowMissing: true
translations:
- from: es-mx
to: en-us
type: translate`

svarRend, _ = svar.Render()

assert.Equal(t, desired, strings.TrimSpace(string(svarRend)))
}
1 change: 1 addition & 0 deletions datamodel/low/v3/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func (s *Server) Build(ctx context.Context, keyNode, root *yaml.Node, _ *index.S
variable.Reference = new(low.Reference)
_ = low.BuildModel(varNode, &variable)
variable.Nodes = low.ExtractNodesRecursive(ctx, varNode)
variable.Extensions = low.ExtractExtensions(varNode)
if localKeyNode != nil {
variable.Nodes.Store(localKeyNode.Line, localKeyNode)
}
Expand Down
55 changes: 55 additions & 0 deletions datamodel/low/v3/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,61 @@ variables:
for v := range n.Variables.Value.ValuesFromOldest() {
assert.NotNil(t, v.Value.GetKeyNode())
assert.NotNil(t, v.Value.GetRootNode())
assert.Nil(t, v.Value.GetExtensions())
}
}

func TestServerWithVariableExtension_Build(t *testing.T) {
yml := `url: https://pb33f.io
description: high quality software for developers.
variables:
var1:
default: hello
description: a var
enum: [one, two]
x-transforms:
allowMissing: true`

var idxNode yaml.Node
_ = yaml.Unmarshal([]byte(yml), &idxNode)
idx := index.NewSpecIndex(&idxNode)

var n Server
err := low.BuildModel(idxNode.Content[0], &n)
assert.NoError(t, err)
assert.Nil(t, n.GetRootNode())

err = n.Build(context.Background(), nil, idxNode.Content[0], idx)
assert.NoError(t, err)
assert.NotNil(t, n.GetRootNode())
assert.Equal(t, "ec69dfcf68ad8988f3804e170ee6c4a7ad2e4ac51084796eea93168820827546",
low.GenerateHashString(&n))

assert.Equal(t, "https://pb33f.io", n.URL.Value)
assert.Equal(t, "high quality software for developers.", n.Description.Value)

variable := n.FindVariable("var1").Value
assert.Equal(t, "hello", variable.Default.Value)
assert.Equal(t, "a var", variable.Description.Value)

var_extensions := variable.Extensions.First()
assert.Equal(t, "x-transforms", var_extensions.Key().Value)
variable_pair := variable.Extensions.GetPair(var_extensions.Key())
assert.Equal(t, "allowMissing", variable_pair.Value.Value.Content[0].Value)
assert.Equal(t, "true", variable_pair.Value.Value.Content[1].Value)

// test var hash
s := n.FindVariable("var1")
assert.Equal(t, "00eef99ee4a7b746be7b4ccdece59c5a96222c6206f846fafed782c9f3f9b46b",
low.GenerateHashString(s.Value))

assert.Equal(t, 0, orderedmap.Len(n.GetExtensions()))

// check nodes on variables
for v := range n.Variables.Value.ValuesFromOldest() {
assert.NotNil(t, v.Value.GetKeyNode())
assert.NotNil(t, v.Value.GetRootNode())
assert.NotNil(t, v.Value.GetExtensions())
}
}

Expand Down
12 changes: 10 additions & 2 deletions datamodel/low/v3/server_variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package v3
import (
"crypto/sha256"
"fmt"
"github.com/pb33f/libopenapi/datamodel/low"
"gopkg.in/yaml.v3"
"sort"
"strings"

"github.com/pb33f/libopenapi/datamodel/low"
"github.com/pb33f/libopenapi/orderedmap"
"gopkg.in/yaml.v3"
)

// ServerVariable represents a low-level OpenAPI 3+ ServerVariable object.
Expand All @@ -20,6 +22,7 @@ type ServerVariable struct {
Enum []low.NodeReference[string]
Default low.NodeReference[string]
Description low.NodeReference[string]
Extensions *orderedmap.Map[low.KeyReference[string], low.ValueReference[*yaml.Node]]
KeyNode *yaml.Node
RootNode *yaml.Node
*low.Reference
Expand All @@ -36,6 +39,11 @@ func (s *ServerVariable) GetKeyNode() *yaml.Node {
return s.RootNode
}

// GetExtensions returns all extensions and satisfies the low.HasExtensions interface.
func (s *ServerVariable) GetExtensions() *orderedmap.Map[low.KeyReference[string], low.ValueReference[*yaml.Node]] {
return s.Extensions
}

// Hash will return a consistent SHA256 Hash of the ServerVariable object
func (s *ServerVariable) Hash() [32]byte {
var f []string
Expand Down

0 comments on commit 45c9c61

Please sign in to comment.