Skip to content

Commit

Permalink
feat: engine, distinguish between null and omitted input variables (w…
Browse files Browse the repository at this point in the history
…undergraph#494)

* feat: engine, distinguish between null and omitted input variables

* Update graphql_datasource.go

disable linter for import with generics

* chore: fix typo

* chore: update ci

* chore: fix linter issues

* chore: pr remarks

* chore: pr remarks

---------

Co-authored-by: Sergiy Petrunin <[email protected]>
  • Loading branch information
YuriBuerov and Sergiy Petrunin authored Feb 8, 2023
1 parent 849c309 commit d1a653a
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 54 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GOLANG_CI_VERSION = "v1.45.0"
GOLANG_CI_VERSION_SHORT = "1.45.0"
GOLANG_CI_VERSION = "v1.51.1"
GOLANG_CI_VERSION_SHORT = "1.51.1"
HAS_GOLANG_CI_LINT := $(shell command -v /tmp/ci/golangci-lint;)
INSTALLED_VERSION := $(shell command -v /tmp/ci/golangci-lint version;)
HAS_CORRECT_VERSION := $(shell command -v if [[ $(INSTALLED_VERSION) == *$(GOLANG_CI_VERSION_SHORT)* ]]; echo "OK" fi)
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ require (
github.com/go-zookeeper/zk v1.0.2
github.com/gobwas/ws v1.0.4
github.com/golang/mock v1.4.1
github.com/google/go-cmp v0.5.6
github.com/google/go-cmp v0.5.8
github.com/gorilla/websocket v1.5.0
github.com/hashicorp/golang-lru v0.5.4
github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334
Expand All @@ -37,6 +37,7 @@ require (
github.com/vektah/gqlparser/v2 v2.4.6
go.uber.org/atomic v1.9.0
go.uber.org/zap v1.18.1
golang.org/x/exp v0.0.0-20230203172020-98cc5a0785f9
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
gopkg.in/yaml.v2 v2.4.0
nhooyr.io/websocket v1.8.7
Expand Down Expand Up @@ -106,7 +107,7 @@ require (
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
golang.org/x/sys v0.0.0-20220405210540-1e041c57c461 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
Expand Down
12 changes: 7 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
Expand Down Expand Up @@ -333,6 +333,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20230203172020-98cc5a0785f9 h1:frX3nT9RkKybPnjyI+yvZh6ZucTZatCCEm9D47sZ2zo=
golang.org/x/exp v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
Expand Down Expand Up @@ -372,8 +374,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220405210540-1e041c57c461 h1:kHVeDEnfKn3T238CvrUcz6KeEsFHVaKh4kMTt6Wsysg=
golang.org/x/sys v0.0.0-20220405210540-1e041c57c461/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand All @@ -394,8 +396,8 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
10 changes: 2 additions & 8 deletions pkg/astvalidation/operation_rule_field_selection_merging.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,10 @@ func (f *fieldSelectionMergingVisitor) EnterField(ref int) {
if f.pathCacheIndex != len(f.pathCache)-1 {
path = f.pathCache[f.pathCacheIndex][:len(f.Path)]
f.pathCacheIndex++
for i := 0; i < len(f.Path); i++ {
path[i] = f.Path[i]
}
} else {
path = make(ast.Path, len(f.Path))
copy(path, f.Path)
}
copy(path, f.Path)

f.nonScalarRequirements = append(f.nonScalarRequirements, nonScalarRequirement{
path: path,
Expand Down Expand Up @@ -197,13 +194,10 @@ func (f *fieldSelectionMergingVisitor) EnterField(ref int) {
if f.pathCacheIndex != len(f.pathCache)-1 {
path = f.pathCache[f.pathCacheIndex][:len(f.Path)]
f.pathCacheIndex++
for i := 0; i < len(f.Path); i++ {
path[i] = f.Path[i]
}
} else {
path = make(ast.Path, len(f.Path))
copy(path, f.Path)
}
copy(path, f.Path)

f.scalarRequirements = append(f.scalarRequirements, scalarRequirement{
path: path,
Expand Down
35 changes: 21 additions & 14 deletions pkg/engine/datasource/graphql_datasource/graphql_datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (

"github.com/buger/jsonparser"
"github.com/tidwall/sjson"
"golang.org/x/exp/slices"

"github.com/wundergraph/graphql-go-tools/internal/pkg/unsafebytes"
"github.com/wundergraph/graphql-go-tools/pkg/ast"
"github.com/wundergraph/graphql-go-tools/pkg/astnormalization"
"github.com/wundergraph/graphql-go-tools/pkg/astparser"
Expand Down Expand Up @@ -1327,7 +1329,7 @@ type Source struct {
httpClient *http.Client
}

func (s *Source) compactAndUnNullVariables(input []byte) []byte {
func (s *Source) compactAndUnNullVariables(input []byte, undefinedVariables []string) []byte {
variables, _, _, err := jsonparser.Get(input, "body", "variables")
if err != nil {
return input
Expand All @@ -1342,31 +1344,34 @@ func (s *Source) compactAndUnNullVariables(input []byte) []byte {
}

removeNullVariables := httpclient.IsInputFlagSet(input, httpclient.UNNULLVARIABLES)
variables = s.cleanupVariables(variables, removeNullVariables)
variables = s.cleanupVariables(variables, removeNullVariables, undefinedVariables)

input, _ = jsonparser.Set(input, variables, "body", "variables")
return input
}

// cleanupVariables removes null variables and empty objects from the input if removeNullVariables is true
// otherwise returns the input as is
func (s *Source) cleanupVariables(variables []byte, removeNullVariables bool) []byte {
func (s *Source) cleanupVariables(variables []byte, removeNullVariables bool, undefinedVariables []string) []byte {
cp := make([]byte, len(variables))
copy(cp, variables)

if removeNullVariables {
// remove null variables from JSON: {"a":null,"b":1} -> {"b":1}
err := jsonparser.ObjectEach(variables, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
if dataType == jsonparser.Null {
cp = jsonparser.Delete(cp, string(key))
// remove null variables from JSON: {"a":null,"b":1} -> {"b":1}
err := jsonparser.ObjectEach(variables, func(key []byte, value []byte, dataType jsonparser.ValueType, offset int) error {
if dataType == jsonparser.Null {
stringKey := unsafebytes.BytesToString(key)
if removeNullVariables || slices.Contains(undefinedVariables, stringKey) {
cp = jsonparser.Delete(cp, stringKey)
}
return nil
})
if err != nil {
return variables
}
return nil
})
if err != nil {
return variables
}

// remove empty objects
// remove empty objects
if removeNullVariables {
cp = s.removeEmptyObjects(cp)
}

Expand Down Expand Up @@ -1404,7 +1409,9 @@ func (s *Source) replaceEmptyObject(variables []byte) ([]byte, bool) {
}

func (s *Source) Load(ctx context.Context, input []byte, writer io.Writer) (err error) {
input = s.compactAndUnNullVariables(input)
undefinedVariables := httpclient.CtxGetUndefinedVariables(ctx)

input = s.compactAndUnNullVariables(input, undefinedVariables)
return httpclient.Do(s.httpClient, ctx, input, writer)
}

Expand Down
55 changes: 37 additions & 18 deletions pkg/engine/datasource/graphql_datasource/graphql_datasource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8111,13 +8111,13 @@ func runTestOnTestDefinition(operation, operationName string, expectedPlan plan.
}

func TestSource_Load(t *testing.T) {
t.Run("unnull_variables", func(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
_, _ = fmt.Fprint(w, string(body))
}))
defer ts.Close()
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
_, _ = fmt.Fprint(w, string(body))
}))
defer ts.Close()

t.Run("unnull_variables", func(t *testing.T) {
var (
src = &Source{httpClient: &http.Client{}}
serverUrl = ts.URL
Expand Down Expand Up @@ -8146,91 +8146,110 @@ func TestSource_Load(t *testing.T) {
assert.Equal(t, `{"variables":{"a":null,"b":"b","c":{}}}`, buf.String())
})
})
t.Run("remove undefined variables", func(t *testing.T) {
var (
src = &Source{httpClient: &http.Client{}}
serverUrl = ts.URL
variables = []byte(`{"a":null,"b":null, "c": null}`)
)
t.Run("should remove undefined variables and leave null variables", func(t *testing.T) {
var input []byte
input = httpclient.SetInputBodyWithPath(input, variables, "variables")
input = httpclient.SetInputURL(input, []byte(serverUrl))
buf := bytes.NewBuffer(nil)

undefinedVariables := []string{"a", "c"}
ctx := httpclient.CtxSetUndefinedVariables(context.Background(), undefinedVariables)

require.NoError(t, src.Load(ctx, input, buf))
assert.Equal(t, `{"variables":{"b":null}}`, buf.String())
})
})
}

func TestUnNullVariables(t *testing.T) {
t.Run("should not unnull variables if not enabled", func(t *testing.T) {
t.Run("two variables, one null", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"a":null,"b":true}}}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"a":null,"b":true}}}`), []string{})
expected := `{"body":{"variables":{"a":null,"b":true}}}`
assert.Equal(t, expected, string(out))
})
})

t.Run("variables with whitespace and empty objects", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"email":null,"firstName": "FirstTest", "lastName":"LastTest","phone":123456,"preferences":{ "notifications":{}},"password":"password"}},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"email":null,"firstName": "FirstTest", "lastName":"LastTest","phone":123456,"preferences":{ "notifications":{}},"password":"password"}},"unnull_variables":true}`), []string{})
expected := `{"body":{"variables":{"firstName":"FirstTest","lastName":"LastTest","phone":123456,"password":"password"}},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})

t.Run("empty variables", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{}},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{}},"unnull_variables":true}`), []string{})
expected := `{"body":{"variables":{}},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})

t.Run("null inside an array", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"list":["a",null,"b"]}},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"list":["a",null,"b"]}},"unnull_variables":true}`), []string{})
expected := `{"body":{"variables":{"list":["a",null,"b"]}},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})

t.Run("complex null inside nested objects and arrays", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"a":null, "b": {"key":null, "nested": {"nestedkey": null}}, "arr": ["1", null, "3"], "d": {"nested_arr":["4",null,"6"]}}},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"a":null, "b": {"key":null, "nested": {"nestedkey": null}}, "arr": ["1", null, "3"], "d": {"nested_arr":["4",null,"6"]}}},"unnull_variables":true}`), []string{})
expected := `{"body":{"variables":{"b":{"key":null,"nested":{"nestedkey":null}},"arr":["1",null,"3"],"d":{"nested_arr":["4",null,"6"]}}},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})

t.Run("two variables, one null", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"a":null,"b":true}},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"a":null,"b":true}},"unnull_variables":true}`), []string{})
expected := `{"body":{"variables":{"b":true}},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})

t.Run("two variables, one null reverse", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"a":true,"b":null}},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"a":true,"b":null}},"unnull_variables":true}`), []string{})
expected := `{"body":{"variables":{"a":true}},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})

t.Run("null variables", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":null},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":null},"unnull_variables":true}`), []string{})
expected := `{"body":{"variables":null},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})

t.Run("ignore null inside non variables", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"foo":null},"body":"query {foo(bar: null){baz}}"},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"foo":null},"body":"query {foo(bar: null){baz}}"},"unnull_variables":true}`), []string{})
expected := `{"body":{"variables":{},"body":"query {foo(bar: null){baz}}"},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})

t.Run("ignore null in variable name", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"not_null":1,"null":2,"not_null2":3}},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"variables":{"not_null":1,"null":2,"not_null2":3}},"unnull_variables":true}`), []string{})
expected := `{"body":{"variables":{"not_null":1,"null":2,"not_null2":3}},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})

t.Run("variables missing", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"query":"{foo}"},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"query":"{foo}"},"unnull_variables":true}`), []string{})
expected := `{"body":{"query":"{foo}"},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})

t.Run("variables null", func(t *testing.T) {
s := &Source{}
out := s.compactAndUnNullVariables([]byte(`{"body":{"query":"{foo}","variables":null},"unnull_variables":true}`))
out := s.compactAndUnNullVariables([]byte(`{"body":{"query":"{foo}","variables":null},"unnull_variables":true}`), []string{})
expected := `{"body":{"query":"{foo}","variables":null},"unnull_variables":true}`
assert.Equal(t, expected, string(out))
})
Expand Down
14 changes: 14 additions & 0 deletions pkg/engine/datasource/httpclient/httpclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package httpclient

import (
"bytes"
"context"
"encoding/json"
"io"

Expand All @@ -14,6 +15,8 @@ import (
"github.com/wundergraph/graphql-go-tools/pkg/lexer/literal"
)

type ctxKey string

const (
PATH = "path"
URL = "url"
Expand All @@ -28,6 +31,8 @@ const (
SCHEME = "scheme"
HOST = "host"
UNNULLVARIABLES = "unnull_variables"

removeUndefinedVariables ctxKey = "remove_undefined_variables"
)

var (
Expand All @@ -45,6 +50,15 @@ var (
}
)

func CtxSetUndefinedVariables(ctx context.Context, undefinedVariables []string) context.Context {
return context.WithValue(ctx, removeUndefinedVariables, undefinedVariables)
}

func CtxGetUndefinedVariables(ctx context.Context) []string {
undefinedVariables, _ := ctx.Value(removeUndefinedVariables).([]string)
return undefinedVariables
}

func wrapQuotesIfString(b []byte) []byte {

if bytes.HasPrefix(b, []byte("$$")) && bytes.HasSuffix(b, []byte("$$")) {
Expand Down
6 changes: 3 additions & 3 deletions pkg/engine/datasource/httpclient/httpclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"bytes"
"compress/gzip"
"context"
"io/ioutil"
"io"
"net/http"
"net/http/httptest"
"net/http/httputil"
Expand Down Expand Up @@ -162,7 +162,7 @@ func TestHttpClientDo(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte("ok"))
assert.NoError(t, err)
actualBody, err := ioutil.ReadAll(r.Body)
actualBody, err := io.ReadAll(r.Body)
assert.NoError(t, err)
assert.Equal(t, string(body), string(actualBody))
}))
Expand All @@ -179,7 +179,7 @@ func TestHttpClientDo(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
acceptEncoding := r.Header.Get("Accept-Encoding")
assert.Equal(t, "gzip", acceptEncoding)
actualBody, err := ioutil.ReadAll(r.Body)
actualBody, err := io.ReadAll(r.Body)
assert.NoError(t, err)
assert.Equal(t, string(body), string(actualBody))
gzipWriter := gzip.NewWriter(w)
Expand Down
Loading

0 comments on commit d1a653a

Please sign in to comment.