From 25ba22f650c577ba622c2be40083ee423e630126 Mon Sep 17 00:00:00 2001 From: Ruidy Nemausat Date: Tue, 14 Jul 2020 18:46:39 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=AE=F0=9F=8F=BD=E2=80=8D=E2=99=80?= =?UTF-8?q?=EF=B8=8F=20validate=20Product?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 8 +++++++- go.sum | 23 +++++++++++++++++++++++ products/handlers/products.go | 10 ++++++++++ products/models/product.go | 28 +++++++++++++++++++++++++--- products/models/product_test.go | 18 ++++++++++++++++++ 5 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 products/models/product_test.go diff --git a/go.mod b/go.mod index e2e6b12..0526df3 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,10 @@ module github.com/rjNemo/go-micro go 1.14 -require github.com/gorilla/mux v1.7.4 +require ( + github.com/go-playground/universal-translator v0.17.0 // indirect + github.com/go-playground/validator v9.31.0+incompatible + github.com/gorilla/mux v1.7.4 + github.com/leodido/go-urn v1.2.0 // indirect + gopkg.in/go-playground/assert.v1 v1.2.1 // indirect +) diff --git a/go.sum b/go.sum index abb0613..cb0af1e 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,25 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator v9.31.0+incompatible h1:UA72EPEogEnq76ehGdEDp4Mit+3FDh548oRqwVgNsHA= +github.com/go-playground/validator v9.31.0+incompatible/go.mod h1:yrEkQXlcI+PugkyDjY2bRrL/UBU4f3rvrgkN3V8JEig= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/products/handlers/products.go b/products/handlers/products.go index 99fd51d..d7eed1b 100644 --- a/products/handlers/products.go +++ b/products/handlers/products.go @@ -79,10 +79,20 @@ func (p *Products) ProductValidationMiddleware(next http.Handler) http.Handler { // deserialize JSON to product err := newProd.FromJSON(r.Body) if err != nil { + p.logger.Printf("Error deserializing %v", err) errMsg := fmt.Sprintf("Unable to decode data: %s\n", err) http.Error(w, errMsg, http.StatusBadRequest) return } + // validate the product + err = newProd.Validate() + if err != nil { + p.logger.Printf("Error deserializing %v", err) + errMsg := fmt.Sprintf("Validation error: %s\n", err) + http.Error(w, errMsg, http.StatusBadRequest) + return + } + // add product to the context ctx := context.WithValue(r.Context(), KeyProduct{}, newProd) req := r.WithContext(ctx) diff --git a/products/models/product.go b/products/models/product.go index b9919dd..79203f0 100644 --- a/products/models/product.go +++ b/products/models/product.go @@ -3,15 +3,18 @@ package models import ( "encoding/json" "io" + "regexp" + + "github.com/go-playground/validator" ) // Product defines the structure of a product type Product struct { ID int `json:"id"` //TODO: use uuid - Name string `json:"name"` + Name string `json:"name" validate:"required"` Description string `json:"description"` - Price float32 `json:"price"` // TODO: use int - SKU string `json:"sku"` + Price float32 `json:"price" validate:"gt=0"` // TODO: use int + SKU string `json:"sku" validate:"required,sku"` CreatedOn string `json:"-"` UpdatedOn string `json:"-"` DeletedOn string `json:"-"` @@ -21,3 +24,22 @@ type Product struct { func (p *Product) FromJSON(r io.Reader) error { return json.NewDecoder(r).Decode(p) } + +// Validate checks object validity +func (p *Product) Validate() error { + validate := validator.New() + validate.RegisterValidation("sku", validateSKU) + return validate.Struct(p) +} + +func validateSKU(fl validator.FieldLevel) bool { + // sku is of format abc-efgh-ijklm + re := regexp.MustCompile("[a-z]+-[a-z]+-[a-z]+") + matches := re.FindAllString(fl.Field().String(), -1) + + if len(matches) != 1 { + return false + } + + return true +} diff --git a/products/models/product_test.go b/products/models/product_test.go new file mode 100644 index 0000000..2aca6f5 --- /dev/null +++ b/products/models/product_test.go @@ -0,0 +1,18 @@ +package models + +import "testing" + +func TestValidation(t *testing.T) { + p := &Product{ + Name: "Frappe", + Price: 1.1, + SKU: "a-adfg-fdds", + } + + err := p.Validate() + + if err != nil { + t.Error(err) + + } +}