From 3f6c371cc644ac1a44b539bc2dc1ad5656c1b4ce Mon Sep 17 00:00:00 2001 From: nic-chen Date: Thu, 10 Dec 2020 15:38:03 +0800 Subject: [PATCH 1/6] fix: PATCH method bug --- api/go.mod | 1 + api/go.sum | 4 + api/internal/handler/ssl/ssl.go | 44 +++--- api/internal/utils/json_patch.go | 53 +++++++ api/internal/utils/json_patch_test.go | 211 ++++++++++++++++++++++++++ api/test/e2e/ssl_test.go | 57 ++++++- 6 files changed, 346 insertions(+), 24 deletions(-) create mode 100644 api/internal/utils/json_patch.go create mode 100644 api/internal/utils/json_patch_test.go diff --git a/api/go.mod b/api/go.mod index 3c483718f7..b67cd955b1 100644 --- a/api/go.mod +++ b/api/go.mod @@ -11,6 +11,7 @@ require ( github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible + github.com/evanphx/json-patch/v5 v5.1.0 github.com/gin-contrib/pprof v1.3.0 github.com/gin-contrib/sessions v0.0.3 github.com/gin-contrib/static v0.0.0-20200916080430-d45d9a37d28e diff --git a/api/go.sum b/api/go.sum index 80c6f95448..67988630eb 100644 --- a/api/go.sum +++ b/api/go.sum @@ -22,6 +22,9 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= +github.com/evanphx/json-patch/v5 v5.1.0 h1:B0aXl1o/1cP8NbviYiBMkcHBtUjIJ1/Ccg6b+SwCLQg= +github.com/evanphx/json-patch/v5 v5.1.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/gin-contrib/pprof v1.3.0 h1:G9eK6HnbkSqDZBYbzG4wrjCsA4e+cvYAHUZw6W+W9K0= github.com/gin-contrib/pprof v1.3.0/go.mod h1:waMjT1H9b179t3CxuG1cV3DHpga6ybizwfBaM5OXaB0= github.com/gin-contrib/sessions v0.0.3 h1:PoBXki+44XdJdlgDqDrY5nDVe3Wk7wDV/UCOuLP6fBI= @@ -77,6 +80,7 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+ github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= github.com/gorilla/sessions v1.1.3 h1:uXoZdcdA5XdXF3QzuSlheVRUvjl+1rKY7zBXL68L9RU= github.com/gorilla/sessions v1.1.3/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= diff --git a/api/internal/handler/ssl/ssl.go b/api/internal/handler/ssl/ssl.go index 08ed05b176..927e3b04ce 100644 --- a/api/internal/handler/ssl/ssl.go +++ b/api/internal/handler/ssl/ssl.go @@ -27,7 +27,6 @@ import ( "reflect" "strings" - "github.com/api7/go-jsonpatch" "github.com/gin-gonic/gin" "github.com/shiningrush/droplet" "github.com/shiningrush/droplet/data" @@ -38,6 +37,7 @@ import ( "github.com/apisix/manager-api/internal/core/entity" "github.com/apisix/manager-api/internal/core/store" "github.com/apisix/manager-api/internal/handler" + "github.com/apisix/manager-api/internal/utils" "github.com/apisix/manager-api/internal/utils/consts" ) @@ -62,13 +62,13 @@ func (h *Handler) ApplyRoute(r *gin.Engine) { wrapper.InputType(reflect.TypeOf(UpdateInput{})))) r.PUT("/apisix/admin/ssl/:id", wgin.Wraps(h.Update, wrapper.InputType(reflect.TypeOf(UpdateInput{})))) - r.PATCH("/apisix/admin/ssl/:id", wgin.Wraps(h.Patch, - wrapper.InputType(reflect.TypeOf(UpdateInput{})))) r.DELETE("/apisix/admin/ssl/:ids", wgin.Wraps(h.BatchDelete, wrapper.InputType(reflect.TypeOf(BatchDelete{})))) r.POST("/apisix/admin/check_ssl_cert", wgin.Wraps(h.Validate, wrapper.InputType(reflect.TypeOf(entity.SSL{})))) + r.PATCH("/apisix/admin/ssl/:id", consts.ErrorWrapper(Patch)) + r.POST("/apisix/admin/check_ssl_exists", consts.ErrorWrapper(Exist)) } @@ -182,40 +182,44 @@ func (h *Handler) Update(c droplet.Context) (interface{}, error) { return nil, nil } -func (h *Handler) Patch(c droplet.Context) (interface{}, error) { - input := c.Input().(*UpdateInput) - arr := strings.Split(input.ID, "/") +func Patch(c *gin.Context) (interface{}, error) { + reqBody, _ := c.GetRawData() + ID := c.Param("id") + + arr := strings.Split(ID, "/") var subPath string if len(arr) > 1 { - input.ID = arr[0] + ID = arr[0] subPath = arr[1] } - stored, err := h.sslStore.Get(input.ID) + sslStore := store.GetStore(store.HubKeySsl) + stored, err := sslStore.Get(ID) if err != nil { return handler.SpecCodeResponse(err), err } - var patch jsonpatch.Patch + var res []byte + jsonBytes, err := json.Marshal(stored) + if err != nil { + return handler.SpecCodeResponse(err), err + } if subPath != "" { - patch = jsonpatch.Patch{ - Operations: []jsonpatch.PatchOperation{ - {Op: jsonpatch.Replace, Path: subPath, Value: c.Input()}, - }, - } + res, err = utils.PatchJson(jsonBytes, subPath, string(reqBody)) } else { - patch, err = jsonpatch.MakePatch(stored, input.SSL) - if err != nil { - return handler.SpecCodeResponse(err), err - } + res, err = utils.MergeJson(jsonBytes, reqBody) + } + if err != nil { + return handler.SpecCodeResponse(err), err } - err = patch.Apply(&stored) + var ssl entity.SSL + err = json.Unmarshal(res, &ssl) if err != nil { return handler.SpecCodeResponse(err), err } - if err := h.sslStore.Update(c.Context(), &stored, false); err != nil { + if err := sslStore.Update(c, &ssl, false); err != nil { return handler.SpecCodeResponse(err), err } diff --git a/api/internal/utils/json_patch.go b/api/internal/utils/json_patch.go new file mode 100644 index 0000000000..c095f34297 --- /dev/null +++ b/api/internal/utils/json_patch.go @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 utils + +import jsonpatch "github.com/evanphx/json-patch/v5" + +func MergeJson(doc, patch []byte) ([]byte, error) { + out, err := jsonpatch.MergePatch(doc, patch) + + if err != nil { + return nil, err + } + return out, nil +} + +func PatchJson(doc []byte, path, val string) ([]byte, error) { + patch := []byte(`[ { "op": "replace", "path": "` + path + `", "value": ` + val + `}]`) + obj, err := jsonpatch.DecodePatch(patch) + if err != nil { + return nil, err + } + + out, err := obj.Apply(doc) + + if err != nil { + // try to add if field not exist + patch = []byte(`[ { "op": "add", "path": "` + path + `", "value": ` + val + `}]`) + obj, err = jsonpatch.DecodePatch(patch) + if err != nil { + return nil, err + } + out, err = obj.Apply(doc) + if err != nil { + return nil, err + } + } + + return out, nil +} diff --git a/api/internal/utils/json_patch_test.go b/api/internal/utils/json_patch_test.go new file mode 100644 index 0000000000..238f1cd547 --- /dev/null +++ b/api/internal/utils/json_patch_test.go @@ -0,0 +1,211 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 utils + +import ( + "bytes" + "encoding/json" + "reflect" + "testing" +) + +func compareJSON(a, b string) bool { + var objA, objB interface{} + json.Unmarshal([]byte(a), &objA) + json.Unmarshal([]byte(b), &objB) + + return reflect.DeepEqual(objA, objB) +} + +func formatJSON(j string) string { + buf := new(bytes.Buffer) + + json.Indent(buf, []byte(j), "", " ") + + return buf.String() +} + +func TestMergeJson(t *testing.T) { + Cases := []struct { + doc, patch, result, desc string + }{ + { + desc: `simple merge`, + doc: `{ + "id": "1", + "status": 1, + "key": "fake key", + "cert": "fake cert", + "create_time": 1, + "update_time": 2 + }`, + patch: `{ + "id": "1", + "status": 0, + "key": "fake key1", + "cert": "fake cert1" + }`, + result: `{ + "id": "1", + "status": 0, + "key": "fake key1", + "cert": "fake cert1", + "create_time": 1, + "update_time": 2 + }`, + }, + { + desc: `array merge`, + doc: `{ + "uri": "/index.html", + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "39.97.63.215", + "port": 80, + "weight" : 1 + }] + } + }`, + patch: `{ + "upstream": { + "nodes": [{ + "host": "39.97.63.216", + "port": 80, + "weight" : 1 + },{ + "host": "39.97.63.217", + "port": 80, + "weight" : 1 + }] + } + }`, + result: `{ + "uri": "/index.html", + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "39.97.63.216", + "port": 80, + "weight" : 1 + },{ + "host": "39.97.63.217", + "port": 80, + "weight" : 1 + }] + } + }`, + }, + } + for _, c := range Cases { + out, err := MergeJson([]byte(c.doc), []byte(c.patch)) + + if err != nil { + t.Errorf("Unable to merge patch: %s", err) + } + + if !compareJSON(string(out), c.result) { + t.Errorf("Merge failed. Expected:\n%s\n\nActual:\n%s", + formatJSON(c.result), formatJSON(string(out))) + } + } +} + +func TestPatchJson(t *testing.T) { + Cases := []struct { + doc, path, value, result, desc string + }{ + { + desc: "patch array", + doc: `{ + "uri": "/index.html", + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "39.97.63.215", + "port": 80, + "weight" : 1 + }] + } + }`, + path: `/upstream/nodes`, + value: `[{ + "host": "39.97.63.216", + "port": 80, + "weight" : 1 + },{ + "host": "39.97.63.217", + "port": 80, + "weight" : 1 + }]`, + result: `{ + "uri": "/index.html", + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "39.97.63.216", + "port": 80, + "weight" : 1 + },{ + "host": "39.97.63.217", + "port": 80, + "weight" : 1 + }] + } + }`, + }, + { + desc: "patch field that not exists", + doc: `{ + "uri": "/index.html", + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "39.97.63.215", + "port": 80, + "weight" : 1 + }] + } + }`, + path: `/upstream/labels`, + value: `{"app": "test"}`, + result: `{ + "uri": "/index.html", + "upstream": { + "type": "roundrobin", + "nodes": [{ + "host": "39.97.63.215", + "port": 80, + "weight" : 1 + }], + "labels": {"app": "test"} + } + }`, + }, + } + for _, c := range Cases { + out, err := PatchJson([]byte(c.doc), c.path, c.value) + if err != nil { + t.Errorf("Unable to patch: %s", err) + } + + if !compareJSON(string(out), c.result) { + t.Errorf("Patch failed. Expected:\n%s\n\nActual:\n%s", + formatJSON(c.result), formatJSON(string(out))) + } + } +} diff --git a/api/test/e2e/ssl_test.go b/api/test/e2e/ssl_test.go index 85a332e36b..6b8ddc3a53 100644 --- a/api/test/e2e/ssl_test.go +++ b/api/test/e2e/ssl_test.go @@ -112,10 +112,13 @@ func TestSSL_Basic(t *testing.T) { Sleep: sleepTime, }, { - caseDesc: "delete ssl", - Object: ManagerApiExpect(t), - Method: http.MethodDelete, - Path: "/apisix/admin/ssl/1", + caseDesc: "disable SSL", + Object: ManagerApiExpect(t), + Method: http.MethodPatch, + Path: "/apisix/admin/ssl/1", + Body: `{ + "status": 0 + }`, Headers: map[string]string{"Authorization": token}, ExpectStatus: http.StatusOK, }, @@ -125,6 +128,52 @@ func TestSSL_Basic(t *testing.T) { testCaseCheck(tc) } + // try again after disable SSL, make a HTTPS request + // If use the test framework, errors will cause failure, so we need to make a separate https request for testing. + time.Sleep(sleepTime) + _, err = http.Get("https://www.test2.com:9443") + assert.NotNil(t, err) + assert.EqualError(t, err, "Get https://www.test2.com:9443: remote error: tls: internal error") + + // enable SSL again + tests = []HttpTestCase{ + { + caseDesc: "enable SSL", + Object: ManagerApiExpect(t), + Method: http.MethodPatch, + Path: "/apisix/admin/ssl/1", + Body: `{ + "status": 1 + }`, + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + }, + { + caseDesc: "hit the route using HTTPS, make sure enable successful", + Object: APISIXHTTPSExpect(t), + Method: http.MethodGet, + Path: "/hello_", + Headers: map[string]string{"Host": "www.test2.com"}, + ExpectStatus: http.StatusOK, + ExpectBody: "hello world\n", + Sleep: sleepTime, + }, + } + for _, tc := range tests { + testCaseCheck(tc) + } + + // delete SSL + delSSL := HttpTestCase{ + caseDesc: "delete SSL", + Object: ManagerApiExpect(t), + Method: http.MethodDelete, + Path: "/apisix/admin/ssl/1", + Headers: map[string]string{"Authorization": token}, + ExpectStatus: http.StatusOK, + } + testCaseCheck(delSSL) + // try again after deleting SSL, make a HTTPS request // If use the test framework, errors will cause failure, so we need to make a separate https request for testing. time.Sleep(sleepTime) From 1e736e7ed1dda0427a6c250ca494dc3221ddd001 Mon Sep 17 00:00:00 2001 From: nic-chen Date: Thu, 10 Dec 2020 16:23:27 +0800 Subject: [PATCH 2/6] test: use sub path patch in e2e test --- api/internal/handler/ssl/ssl.go | 23 +++-------------------- api/internal/utils/json_patch.go | 24 +++++++++++++++++++++++- api/test/e2e/ssl_test.go | 13 +++++-------- 3 files changed, 31 insertions(+), 29 deletions(-) diff --git a/api/internal/handler/ssl/ssl.go b/api/internal/handler/ssl/ssl.go index 927e3b04ce..1ce7851b55 100644 --- a/api/internal/handler/ssl/ssl.go +++ b/api/internal/handler/ssl/ssl.go @@ -68,6 +68,7 @@ func (h *Handler) ApplyRoute(r *gin.Engine) { wrapper.InputType(reflect.TypeOf(entity.SSL{})))) r.PATCH("/apisix/admin/ssl/:id", consts.ErrorWrapper(Patch)) + r.PATCH("/apisix/admin/ssl/:id/*path", consts.ErrorWrapper(Patch)) r.POST("/apisix/admin/check_ssl_exists", consts.ErrorWrapper(Exist)) } @@ -185,13 +186,7 @@ func (h *Handler) Update(c droplet.Context) (interface{}, error) { func Patch(c *gin.Context) (interface{}, error) { reqBody, _ := c.GetRawData() ID := c.Param("id") - - arr := strings.Split(ID, "/") - var subPath string - if len(arr) > 1 { - ID = arr[0] - subPath = arr[1] - } + subPath := c.Param("path") sslStore := store.GetStore(store.HubKeySsl) stored, err := sslStore.Get(ID) @@ -199,19 +194,7 @@ func Patch(c *gin.Context) (interface{}, error) { return handler.SpecCodeResponse(err), err } - var res []byte - jsonBytes, err := json.Marshal(stored) - if err != nil { - return handler.SpecCodeResponse(err), err - } - if subPath != "" { - res, err = utils.PatchJson(jsonBytes, subPath, string(reqBody)) - } else { - res, err = utils.MergeJson(jsonBytes, reqBody) - } - if err != nil { - return handler.SpecCodeResponse(err), err - } + res, err := utils.MakePatch(stored, subPath, reqBody) var ssl entity.SSL err = json.Unmarshal(res, &ssl) diff --git a/api/internal/utils/json_patch.go b/api/internal/utils/json_patch.go index c095f34297..4013aa0b33 100644 --- a/api/internal/utils/json_patch.go +++ b/api/internal/utils/json_patch.go @@ -16,7 +16,10 @@ */ package utils -import jsonpatch "github.com/evanphx/json-patch/v5" +import ( + "encoding/json" + jsonpatch "github.com/evanphx/json-patch/v5" +) func MergeJson(doc, patch []byte) ([]byte, error) { out, err := jsonpatch.MergePatch(doc, patch) @@ -51,3 +54,22 @@ func PatchJson(doc []byte, path, val string) ([]byte, error) { return out, nil } + +func MakePatch(obj interface{}, subPath string, reqBody []byte) ([]byte, error) { + var res []byte + jsonBytes, err := json.Marshal(obj) + if err != nil { + return res, err + } + + if subPath != "" { + res, err = PatchJson(jsonBytes, subPath, string(reqBody)) + } else { + res, err = MergeJson(jsonBytes, reqBody) + } + + if err != nil { + return res, err + } + return res, nil +} diff --git a/api/test/e2e/ssl_test.go b/api/test/e2e/ssl_test.go index 6b8ddc3a53..5290fa3288 100644 --- a/api/test/e2e/ssl_test.go +++ b/api/test/e2e/ssl_test.go @@ -138,13 +138,11 @@ func TestSSL_Basic(t *testing.T) { // enable SSL again tests = []HttpTestCase{ { - caseDesc: "enable SSL", - Object: ManagerApiExpect(t), - Method: http.MethodPatch, - Path: "/apisix/admin/ssl/1", - Body: `{ - "status": 1 - }`, + caseDesc: "enable SSL", + Object: ManagerApiExpect(t), + Method: http.MethodPatch, + Path: "/apisix/admin/ssl/1/status", + Body: `1`, Headers: map[string]string{"Authorization": token}, ExpectStatus: http.StatusOK, }, @@ -191,5 +189,4 @@ func TestSSL_Basic(t *testing.T) { ExpectStatus: http.StatusOK, } testCaseCheck(delRoute) - } From 46a507b441d48f37afc6a9bfede73bcc41856fb8 Mon Sep 17 00:00:00 2001 From: nic-chen Date: Thu, 10 Dec 2020 16:49:18 +0800 Subject: [PATCH 3/6] fix: lint --- api/internal/handler/ssl/ssl.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/internal/handler/ssl/ssl.go b/api/internal/handler/ssl/ssl.go index 1ce7851b55..12a3876204 100644 --- a/api/internal/handler/ssl/ssl.go +++ b/api/internal/handler/ssl/ssl.go @@ -195,6 +195,9 @@ func Patch(c *gin.Context) (interface{}, error) { } res, err := utils.MakePatch(stored, subPath, reqBody) + if err != nil { + return handler.SpecCodeResponse(err), err + } var ssl entity.SSL err = json.Unmarshal(res, &ssl) From 0b8aa420188c593f7e176954ca037f2189df8605 Mon Sep 17 00:00:00 2001 From: nic-chen Date: Fri, 11 Dec 2020 14:26:59 +0800 Subject: [PATCH 4/6] fix: naming stype --- api/internal/handler/ssl/ssl.go | 2 +- api/internal/utils/json_patch.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/internal/handler/ssl/ssl.go b/api/internal/handler/ssl/ssl.go index 12a3876204..f6d2795d75 100644 --- a/api/internal/handler/ssl/ssl.go +++ b/api/internal/handler/ssl/ssl.go @@ -194,7 +194,7 @@ func Patch(c *gin.Context) (interface{}, error) { return handler.SpecCodeResponse(err), err } - res, err := utils.MakePatch(stored, subPath, reqBody) + res, err := utils.MergePatch(stored, subPath, reqBody) if err != nil { return handler.SpecCodeResponse(err), err } diff --git a/api/internal/utils/json_patch.go b/api/internal/utils/json_patch.go index 4013aa0b33..d6bcd1d285 100644 --- a/api/internal/utils/json_patch.go +++ b/api/internal/utils/json_patch.go @@ -55,7 +55,7 @@ func PatchJson(doc []byte, path, val string) ([]byte, error) { return out, nil } -func MakePatch(obj interface{}, subPath string, reqBody []byte) ([]byte, error) { +func MergePatch(obj interface{}, subPath string, reqBody []byte) ([]byte, error) { var res []byte jsonBytes, err := json.Marshal(obj) if err != nil { From f99ab09f8311c61ebc14b38da8d57f6627dae751 Mon Sep 17 00:00:00 2001 From: nic-chen Date: Fri, 11 Dec 2020 15:42:59 +0800 Subject: [PATCH 5/6] fix: according to review --- api/internal/utils/json_patch_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/api/internal/utils/json_patch_test.go b/api/internal/utils/json_patch_test.go index 238f1cd547..17ea3c1562 100644 --- a/api/internal/utils/json_patch_test.go +++ b/api/internal/utils/json_patch_test.go @@ -40,7 +40,7 @@ func formatJSON(j string) string { } func TestMergeJson(t *testing.T) { - Cases := []struct { + cases := []struct { doc, patch, result, desc string }{ { @@ -111,7 +111,7 @@ func TestMergeJson(t *testing.T) { }`, }, } - for _, c := range Cases { + for _, c := range cases { out, err := MergeJson([]byte(c.doc), []byte(c.patch)) if err != nil { @@ -126,7 +126,7 @@ func TestMergeJson(t *testing.T) { } func TestPatchJson(t *testing.T) { - Cases := []struct { + cases := []struct { doc, path, value, result, desc string }{ { @@ -169,7 +169,7 @@ func TestPatchJson(t *testing.T) { }`, }, { - desc: "patch field that not exists", + desc: "patch field that non existent", doc: `{ "uri": "/index.html", "upstream": { @@ -197,7 +197,7 @@ func TestPatchJson(t *testing.T) { }`, }, } - for _, c := range Cases { + for _, c := range cases { out, err := PatchJson([]byte(c.doc), c.path, c.value) if err != nil { t.Errorf("Unable to patch: %s", err) From 12a929880543bfbd0857ab6af9c84cca471c72d5 Mon Sep 17 00:00:00 2001 From: nic-chen Date: Fri, 11 Dec 2020 15:59:58 +0800 Subject: [PATCH 6/6] fix: style --- api/internal/utils/json_patch_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/internal/utils/json_patch_test.go b/api/internal/utils/json_patch_test.go index 17ea3c1562..8dd25404e1 100644 --- a/api/internal/utils/json_patch_test.go +++ b/api/internal/utils/json_patch_test.go @@ -44,7 +44,7 @@ func TestMergeJson(t *testing.T) { doc, patch, result, desc string }{ { - desc: `simple merge`, + desc: "simple merge", doc: `{ "id": "1", "status": 1,