From 71926b2197bdb9967d9e97ce7ddc0d3aaf8d1879 Mon Sep 17 00:00:00 2001 From: Muyao CHEN Date: Sat, 12 Oct 2024 23:30:36 +0200 Subject: [PATCH] feat: Use gin default validator --- go.mod | 3 +-- go.sum | 6 ++--- internal/howmuch/adapter/controller/user.go | 21 ++++++++++-------- internal/howmuch/model/user.go | 14 ++++++------ internal/howmuch/usecase/usecase/user.go | 12 +++++----- internal/howmuch/usecase/usecase/user_test.go | 12 +++++----- internal/pkg/test/request.go | 22 +++++++++++++++++++ 7 files changed, 55 insertions(+), 35 deletions(-) diff --git a/go.mod b/go.mod index 3dc2014..ca7de21 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module git.vinchent.xyz/vinchent/howmuch go 1.23.1 require ( - github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 github.com/fsnotify/fsnotify v1.7.0 github.com/gin-contrib/cors v1.7.2 github.com/gin-gonic/gin v1.10.0 @@ -31,7 +30,7 @@ require ( github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/go-playground/validator/v10 v10.22.1 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect diff --git a/go.sum b/go.sum index 0b108ad..71b959f 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= @@ -33,8 +31,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= -github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= +github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= diff --git a/internal/howmuch/adapter/controller/user.go b/internal/howmuch/adapter/controller/user.go index 60c3635..eda8947 100644 --- a/internal/howmuch/adapter/controller/user.go +++ b/internal/howmuch/adapter/controller/user.go @@ -29,7 +29,6 @@ import ( "git.vinchent.xyz/vinchent/howmuch/internal/howmuch/usecase/usecase" "git.vinchent.xyz/vinchent/howmuch/internal/pkg/core" "git.vinchent.xyz/vinchent/howmuch/internal/pkg/errno" - "github.com/asaskevich/govalidator" "github.com/gin-gonic/gin" ) @@ -58,22 +57,26 @@ func NewUserController(us usecase.User) User { } func (uc *UserController) Create(ctx core.Context) { - var params model.User + var params struct { + Email string `json:"email" binding:"required,email"` + FirstName string `json:"first_name" binding:"required"` + LastName string `json:"last_name" binding:"required"` + Password string `json:"password" binding:"required"` + } if err := ctx.Bind(¶ms); err != nil { core.WriteResponse(ctx, UserParamsErr, nil) return } - _, err := govalidator.ValidateStruct(params) - if err != nil { - errno := UserParamsErr - errno.Message = err.Error() - core.WriteResponse(ctx, errno, nil) - return + user := model.User{ + Email: params.Email, + FirstName: params.FirstName, + LastName: params.LastName, + Password: params.Password, } - _, err = uc.userUsecase.Create(ctx, ¶ms) + _, err := uc.userUsecase.Create(ctx, &user) if err != nil { core.WriteResponse(ctx, err, nil) return diff --git a/internal/howmuch/model/user.go b/internal/howmuch/model/user.go index 62083f2..ef28092 100644 --- a/internal/howmuch/model/user.go +++ b/internal/howmuch/model/user.go @@ -26,11 +26,11 @@ import "time" // User model type User struct { - ID int `json:"id"` - Email string `json:"email" valid:"email"` - FirstName string `json:"first_name" valid:"required"` - LastName string `json:"last_name" valid:"required"` - Password string `json:"password" valid:"required"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID int + Email string + FirstName string + LastName string + Password string + CreatedAt time.Time + UpdatedAt time.Time } diff --git a/internal/howmuch/usecase/usecase/user.go b/internal/howmuch/usecase/usecase/user.go index 0f3cb30..9144bcd 100644 --- a/internal/howmuch/usecase/usecase/user.go +++ b/internal/howmuch/usecase/usecase/user.go @@ -61,7 +61,7 @@ type userUsecase struct { type User interface { Create(ctx context.Context, u *model.User) (*model.User, error) - Exist(ctx context.Context, u *model.User) (bool, error) + Exist(ctx context.Context, u *model.User) error } func NewUserUsecase(r repo.UserRepository, d repo.DBRepository) User { @@ -113,23 +113,23 @@ func (uuc *userUsecase) Create(ctx context.Context, u *model.User) (*model.User, return user, nil } -func (uuc *userUsecase) Exist(ctx context.Context, u *model.User) (bool, error) { +func (uuc *userUsecase) Exist(ctx context.Context, u *model.User) error { got, err := uuc.userRepo.GetByEmail(ctx, u.Email) // Any query error? if err != nil { - return false, err + return err } // User exists? if got == nil { - return false, UserNotExist + return UserNotExist } // Password correct? err = bcrypt.CompareHashAndPassword([]byte(got.Password), []byte(u.Password)) if errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) { - return false, UserWrongPassword + return UserWrongPassword } - return true, nil + return nil } diff --git a/internal/howmuch/usecase/usecase/user_test.go b/internal/howmuch/usecase/usecase/user_test.go index dee5bb9..1ae3d5d 100644 --- a/internal/howmuch/usecase/usecase/user_test.go +++ b/internal/howmuch/usecase/usecase/user_test.go @@ -69,32 +69,30 @@ func TestUserExist(t *testing.T) { Name string User *model.User ExpErr error - ExpRes bool }{ {"user exists", &model.User{ Email: "a@b.c", Password: "strongHashed", - }, nil, true}, + }, nil}, {"query error", &model.User{ Email: "query@error.com", Password: "strongHashed", - }, repomock.UserTestDummyErr, false}, + }, repomock.UserTestDummyErr}, {"user doesn not exist", &model.User{ Email: "inexist@error.com", Password: "strongHashed", - }, UserNotExist, false}, + }, UserNotExist}, {"wrong password", &model.User{ Email: "a@b.c", Password: "wrongHashed", - }, UserWrongPassword, false}, + }, UserWrongPassword}, } for _, tst := range testCases { ctx := context.Background() userUsecase := NewUserUsecase(&repomock.TestUserRepository{}, &repomock.TestDBRepository{}) - got, err := userUsecase.Exist(ctx, tst.User) + err := userUsecase.Exist(ctx, tst.User) assert.ErrorIs(t, err, tst.ExpErr) - assert.Equal(t, tst.ExpRes, got) } } diff --git a/internal/pkg/test/request.go b/internal/pkg/test/request.go index 75bad4b..cd5e66e 100644 --- a/internal/pkg/test/request.go +++ b/internal/pkg/test/request.go @@ -1,3 +1,25 @@ +// MIT License +// +// Copyright (c) 2024 vinchent +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + package test import (