mirror of
https://github.com/raseels-repos/golang-saas-starter-kit.git
synced 2025-06-10 23:57:45 +02:00
Fix unittests
This commit is contained in:
parent
b3d30a019e
commit
1d69ea88a3
@ -2,6 +2,9 @@ package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
@ -45,7 +48,7 @@ func (a *Account) Read(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
b, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as boolean for included-archived param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
includeArchived = b
|
||||
}
|
||||
@ -55,7 +58,10 @@ func (a *Account) Read(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case account.ErrNotFound:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusNotFound))
|
||||
|
||||
fmt.Println("HERE!!!!! account.ErrNotFound")
|
||||
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusNotFound))
|
||||
default:
|
||||
return errors.Wrapf(err, "ID: %s", params["id"])
|
||||
}
|
||||
@ -78,9 +84,10 @@ func (a *Account) Read(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /accounts [patch]
|
||||
func (a *Account) Update(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
@ -89,23 +96,23 @@ func (a *Account) Update(ctx context.Context, w http.ResponseWriter, r *http.Req
|
||||
}
|
||||
|
||||
var req account.AccountUpdateRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
|
||||
err := account.Update(ctx, claims, a.MasterDB, req, v.Now)
|
||||
err = account.Update(ctx, claims, a.MasterDB, req, v.Now)
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case account.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "Id: %s Account: %+v", req.ID, &req)
|
||||
|
@ -2,6 +2,8 @@ package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -51,7 +53,7 @@ func (p *Project) Find(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
if v := r.URL.Query().Get("where"); v != "" {
|
||||
where, args, err := web.ExtractWhereArgs(v)
|
||||
if err != nil {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
req.Where = &where
|
||||
req.Args = args
|
||||
@ -72,7 +74,7 @@ func (p *Project) Find(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
l, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as int for limit param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
ul := uint(l)
|
||||
req.Limit = &ul
|
||||
@ -83,7 +85,7 @@ func (p *Project) Find(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
l, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as int for offset param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
ul := uint(l)
|
||||
req.Limit = &ul
|
||||
@ -94,14 +96,14 @@ func (p *Project) Find(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
b, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as boolean for included-archived param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
req.IncludedArchived = b
|
||||
}
|
||||
|
||||
//if err := web.Decode(r, &req); err != nil {
|
||||
// if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
// err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
// err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
// }
|
||||
// return web.RespondJsonError(ctx, w, err)
|
||||
//}
|
||||
@ -144,7 +146,7 @@ func (p *Project) Read(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
b, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as boolean for included-archived param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
includeArchived = b
|
||||
}
|
||||
@ -154,7 +156,7 @@ func (p *Project) Read(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case project.ErrNotFound:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusNotFound))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusNotFound))
|
||||
default:
|
||||
return errors.Wrapf(err, "ID: %s", params["id"])
|
||||
}
|
||||
@ -178,20 +180,20 @@ func (p *Project) Read(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /projects [post]
|
||||
func (p *Project) Create(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req project.ProjectCreateRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
@ -201,11 +203,11 @@ func (p *Project) Create(ctx context.Context, w http.ResponseWriter, r *http.Req
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case project.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
return errors.Wrapf(err, "Project: %+v", &req)
|
||||
}
|
||||
@ -228,34 +230,34 @@ func (p *Project) Create(ctx context.Context, w http.ResponseWriter, r *http.Req
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /projects [patch]
|
||||
func (p *Project) Update(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req project.ProjectUpdateRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
|
||||
err := project.Update(ctx, claims, p.MasterDB, req, v.Now)
|
||||
err = project.Update(ctx, claims, p.MasterDB, req, v.Now)
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case project.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "ID: %s Update: %+v", req.ID, req)
|
||||
@ -279,34 +281,34 @@ func (p *Project) Update(ctx context.Context, w http.ResponseWriter, r *http.Req
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /projects/archive [patch]
|
||||
func (p *Project) Archive(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req project.ProjectArchiveRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
|
||||
err := project.Archive(ctx, claims, p.MasterDB, req, v.Now)
|
||||
err = project.Archive(ctx, claims, p.MasterDB, req, v.Now)
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case project.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "Id: %s", req.ID)
|
||||
@ -330,21 +332,21 @@ func (p *Project) Archive(ctx context.Context, w http.ResponseWriter, r *http.Re
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /projects/{id} [delete]
|
||||
func (p *Project) Delete(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := project.Delete(ctx, claims, p.MasterDB, params["id"])
|
||||
err = project.Delete(ctx, claims, p.MasterDB, params["id"])
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case project.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "Id: %s", params["id"])
|
||||
|
@ -2,6 +2,8 @@ package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"net/http"
|
||||
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/account"
|
||||
@ -32,18 +34,18 @@ type Signup struct {
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /signup [post]
|
||||
func (c *Signup) Signup(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Claims are optional as authentication is not required ATM for this method.
|
||||
claims, _ := ctx.Value(auth.Key).(auth.Claims)
|
||||
claims, _ := auth.ClaimsFromContext(ctx)
|
||||
|
||||
var req signup.SignupRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
@ -52,11 +54,11 @@ func (c *Signup) Signup(ctx context.Context, w http.ResponseWriter, r *http.Requ
|
||||
if err != nil {
|
||||
switch errors.Cause(err) {
|
||||
case account.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := err.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "Signup: %+v", &req)
|
||||
|
@ -2,6 +2,8 @@ package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -55,7 +57,7 @@ func (u *User) Find(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
||||
if v := r.URL.Query().Get("where"); v != "" {
|
||||
where, args, err := web.ExtractWhereArgs(v)
|
||||
if err != nil {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
req.Where = &where
|
||||
req.Args = args
|
||||
@ -76,7 +78,7 @@ func (u *User) Find(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
||||
l, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as int for limit param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
ul := uint(l)
|
||||
req.Limit = &ul
|
||||
@ -87,7 +89,7 @@ func (u *User) Find(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
||||
l, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as int for offset param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
ul := uint(l)
|
||||
req.Limit = &ul
|
||||
@ -98,14 +100,14 @@ func (u *User) Find(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
||||
b, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as boolean for included-archived param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
req.IncludedArchived = b
|
||||
}
|
||||
|
||||
//if err := web.Decode(r, &req); err != nil {
|
||||
// if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
// err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
// err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
// }
|
||||
// return web.RespondJsonError(ctx, w, err)
|
||||
//}
|
||||
@ -148,7 +150,7 @@ func (u *User) Read(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
||||
b, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as boolean for included-archived param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
includeArchived = b
|
||||
}
|
||||
@ -158,7 +160,7 @@ func (u *User) Read(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user.ErrNotFound:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusNotFound))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusNotFound))
|
||||
default:
|
||||
return errors.Wrapf(err, "ID: %s", params["id"])
|
||||
}
|
||||
@ -181,20 +183,20 @@ func (u *User) Read(ctx context.Context, w http.ResponseWriter, r *http.Request,
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /users [post]
|
||||
func (u *User) Create(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req user.UserCreateRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
@ -204,11 +206,11 @@ func (u *User) Create(ctx context.Context, w http.ResponseWriter, r *http.Reques
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "User: %+v", &req)
|
||||
@ -232,34 +234,34 @@ func (u *User) Create(ctx context.Context, w http.ResponseWriter, r *http.Reques
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /users [patch]
|
||||
func (u *User) Update(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req user.UserUpdateRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
|
||||
err := user.Update(ctx, claims, u.MasterDB, req, v.Now)
|
||||
err = user.Update(ctx, claims, u.MasterDB, req, v.Now)
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "Id: %s User: %+v", req.ID, &req)
|
||||
@ -283,36 +285,36 @@ func (u *User) Update(ctx context.Context, w http.ResponseWriter, r *http.Reques
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /users/password [patch]
|
||||
func (u *User) UpdatePassword(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req user.UserUpdatePasswordRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
|
||||
err := user.UpdatePassword(ctx, claims, u.MasterDB, req, v.Now)
|
||||
err = user.UpdatePassword(ctx, claims, u.MasterDB, req, v.Now)
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user.ErrNotFound:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusNotFound))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusNotFound))
|
||||
case user.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "Id: %s User: %+v", req.ID, &req)
|
||||
@ -336,34 +338,34 @@ func (u *User) UpdatePassword(ctx context.Context, w http.ResponseWriter, r *htt
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /users/archive [patch]
|
||||
func (u *User) Archive(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req user.UserArchiveRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
|
||||
err := user.Archive(ctx, claims, u.MasterDB, req, v.Now)
|
||||
err = user.Archive(ctx, claims, u.MasterDB, req, v.Now)
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "Id: %s", req.ID)
|
||||
@ -387,21 +389,21 @@ func (u *User) Archive(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /users/{id} [delete]
|
||||
func (u *User) Delete(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := user.Delete(ctx, claims, u.MasterDB, params["id"])
|
||||
err = user.Delete(ctx, claims, u.MasterDB, params["id"])
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "Id: %s", params["id"])
|
||||
@ -425,14 +427,14 @@ func (u *User) Delete(ctx context.Context, w http.ResponseWriter, r *http.Reques
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /users/switch-account/{account_id} [patch]
|
||||
func (u *User) SwitchAccount(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tkn, err := user.SwitchAccount(ctx, u.MasterDB, u.TokenGenerator, claims, params["account_id"], sessionTtl, v.Now)
|
||||
@ -440,11 +442,11 @@ func (u *User) SwitchAccount(ctx context.Context, w http.ResponseWriter, r *http
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user.ErrAuthenticationFailure:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusUnauthorized))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusUnauthorized))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrap(err, "switch account")
|
||||
@ -468,15 +470,15 @@ func (u *User) SwitchAccount(ctx context.Context, w http.ResponseWriter, r *http
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /oauth/token [post]
|
||||
func (u *User) Token(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
email, pass, ok := r.BasicAuth()
|
||||
if !ok {
|
||||
err := errors.New("must provide email and password in Basic auth")
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusUnauthorized))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusUnauthorized))
|
||||
}
|
||||
|
||||
// Optional to include scope.
|
||||
@ -487,11 +489,11 @@ func (u *User) Token(ctx context.Context, w http.ResponseWriter, r *http.Request
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user.ErrAuthenticationFailure:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusUnauthorized))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusUnauthorized))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrap(err, "authenticating")
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/auth"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/user_account"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/pkg/errors"
|
||||
@ -50,7 +52,7 @@ func (u *UserAccount) Find(ctx context.Context, w http.ResponseWriter, r *http.R
|
||||
if v := r.URL.Query().Get("where"); v != "" {
|
||||
where, args, err := web.ExtractWhereArgs(v)
|
||||
if err != nil {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
req.Where = &where
|
||||
req.Args = args
|
||||
@ -71,7 +73,7 @@ func (u *UserAccount) Find(ctx context.Context, w http.ResponseWriter, r *http.R
|
||||
l, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as int for limit param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
ul := uint(l)
|
||||
req.Limit = &ul
|
||||
@ -82,7 +84,7 @@ func (u *UserAccount) Find(ctx context.Context, w http.ResponseWriter, r *http.R
|
||||
l, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as int for offset param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
ul := uint(l)
|
||||
req.Limit = &ul
|
||||
@ -93,14 +95,14 @@ func (u *UserAccount) Find(ctx context.Context, w http.ResponseWriter, r *http.R
|
||||
b, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as boolean for included-archived param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
req.IncludedArchived = b
|
||||
}
|
||||
|
||||
//if err := web.Decode(r, &req); err != nil {
|
||||
// if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
// err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
// err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
// }
|
||||
// return web.RespondJsonError(ctx, w, err)
|
||||
//}
|
||||
@ -143,7 +145,7 @@ func (u *UserAccount) Read(ctx context.Context, w http.ResponseWriter, r *http.R
|
||||
b, err := strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
err = errors.WithMessagef(err, "unable to parse %s as boolean for included-archived param", v)
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
includeArchived = b
|
||||
}
|
||||
@ -153,7 +155,7 @@ func (u *UserAccount) Read(ctx context.Context, w http.ResponseWriter, r *http.R
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user_account.ErrNotFound:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusNotFound))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusNotFound))
|
||||
default:
|
||||
return errors.Wrapf(err, "ID: %s", params["id"])
|
||||
}
|
||||
@ -177,20 +179,20 @@ func (u *UserAccount) Read(ctx context.Context, w http.ResponseWriter, r *http.R
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /user_accounts [post]
|
||||
func (u *UserAccount) Create(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req user_account.UserAccountCreateRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
@ -200,11 +202,11 @@ func (u *UserAccount) Create(ctx context.Context, w http.ResponseWriter, r *http
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user_account.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "User Account: %+v", &req)
|
||||
@ -228,34 +230,34 @@ func (u *UserAccount) Create(ctx context.Context, w http.ResponseWriter, r *http
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /user_accounts [patch]
|
||||
func (u *UserAccount) Update(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req user_account.UserAccountUpdateRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
|
||||
err := user_account.Update(ctx, claims, u.MasterDB, req, v.Now)
|
||||
err = user_account.Update(ctx, claims, u.MasterDB, req, v.Now)
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user_account.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "UserID: %s AccountID: %s User Account: %+v", req.UserID, req.AccountID, &req)
|
||||
@ -279,34 +281,34 @@ func (u *UserAccount) Update(ctx context.Context, w http.ResponseWriter, r *http
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /user_accounts/archive [patch]
|
||||
func (u *UserAccount) Archive(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
v, ok := ctx.Value(web.KeyValues).(*web.Values)
|
||||
if !ok {
|
||||
return web.NewShutdownError("web value missing from context")
|
||||
v, err := webcontext.ContextValues(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req user_account.UserAccountArchiveRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
|
||||
err := user_account.Archive(ctx, claims, u.MasterDB, req, v.Now)
|
||||
err = user_account.Archive(ctx, claims, u.MasterDB, req, v.Now)
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user_account.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "UserID: %s AccountID: %s User Account: %+v", req.UserID, req.AccountID, &req)
|
||||
@ -330,29 +332,29 @@ func (u *UserAccount) Archive(ctx context.Context, w http.ResponseWriter, r *htt
|
||||
// @Failure 500 {object} web.ErrorResponse
|
||||
// @Router /user_accounts [delete]
|
||||
func (u *UserAccount) Delete(ctx context.Context, w http.ResponseWriter, r *http.Request, params map[string]string) error {
|
||||
claims, ok := ctx.Value(auth.Key).(auth.Claims)
|
||||
if !ok {
|
||||
return errors.New("claims missing from context")
|
||||
claims, err := auth.ClaimsFromContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var req user_account.UserAccountDeleteRequest
|
||||
if err := web.Decode(r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*web.Error); !ok {
|
||||
err = web.NewRequestError(err, http.StatusBadRequest)
|
||||
if err := web.Decode(ctx, r, &req); err != nil {
|
||||
if _, ok := errors.Cause(err).(*weberror.Error); !ok {
|
||||
err = weberror.NewError(ctx, err, http.StatusBadRequest)
|
||||
}
|
||||
return web.RespondJsonError(ctx, w, err)
|
||||
}
|
||||
|
||||
err := user_account.Delete(ctx, claims, u.MasterDB, req)
|
||||
err = user_account.Delete(ctx, claims, u.MasterDB, req)
|
||||
if err != nil {
|
||||
cause := errors.Cause(err)
|
||||
switch cause {
|
||||
case user_account.ErrForbidden:
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusForbidden))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusForbidden))
|
||||
default:
|
||||
_, ok := cause.(validator.ValidationErrors)
|
||||
if ok {
|
||||
return web.RespondJsonError(ctx, w, web.NewRequestError(err, http.StatusBadRequest))
|
||||
return web.RespondJsonError(ctx, w, weberror.NewError(ctx, err, http.StatusBadRequest))
|
||||
}
|
||||
|
||||
return errors.Wrapf(err, "UserID: %s, AccountID: %s", req.UserID, req.AccountID)
|
||||
|
@ -443,7 +443,7 @@ func main() {
|
||||
if cfg.HTTP.Host != "" {
|
||||
api := http.Server{
|
||||
Addr: cfg.HTTP.Host,
|
||||
Handler: handlers.API(shutdown, log, masterDb, redisClient, authenticator, serviceMiddlewares...),
|
||||
Handler: handlers.API(shutdown, log, cfg.Env, masterDb, redisClient, authenticator, serviceMiddlewares...),
|
||||
ReadTimeout: cfg.HTTP.ReadTimeout,
|
||||
WriteTimeout: cfg.HTTP.WriteTimeout,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
@ -460,7 +460,7 @@ func main() {
|
||||
if cfg.HTTPS.Host != "" {
|
||||
api := http.Server{
|
||||
Addr: cfg.HTTPS.Host,
|
||||
Handler: handlers.API(shutdown, log, masterDb, redisClient, authenticator, serviceMiddlewares...),
|
||||
Handler: handlers.API(shutdown, log, cfg.Env, masterDb, redisClient, authenticator, serviceMiddlewares...),
|
||||
ReadTimeout: cfg.HTTPS.ReadTimeout,
|
||||
WriteTimeout: cfg.HTTPS.WriteTimeout,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
@ -115,7 +116,7 @@ func TestAccountCRUDAdmin(t *testing.T) {
|
||||
t.Fatalf("\t%s\tDecode expected failed.", tests.Failed)
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected result.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected result.", tests.Success)
|
||||
@ -144,17 +145,17 @@ func TestAccountCRUDAdmin(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("account %s not found: Entity not found", randID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -182,17 +183,17 @@ func TestAccountCRUDAdmin(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("account %s not found: Entity not found", tr.ForbiddenAccount.ID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -329,7 +330,7 @@ func TestAccountCRUDUser(t *testing.T) {
|
||||
t.Fatalf("\t%s\tDecode expected failed.", tests.Failed)
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected result.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected result.", tests.Success)
|
||||
@ -358,17 +359,17 @@ func TestAccountCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("account %s not found: Entity not found", randID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -396,17 +397,17 @@ func TestAccountCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("account %s not found: Entity not found", tr.ForbiddenAccount.ID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -438,17 +439,14 @@ func TestAccountCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -490,20 +488,27 @@ func TestAccountUpdate(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "status", Error: "Key: 'AccountUpdateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "status", Error: "Key: 'AccountUpdateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
||||
{
|
||||
Field: "status",
|
||||
Value: invalidStatus.String(),
|
||||
Tag: "oneof",
|
||||
Error: "status must be one of [active pending disabled]",
|
||||
Display: "status must be one of [active pending disabled]",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/auth"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/tests"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/project"
|
||||
"github.com/pborman/uuid"
|
||||
)
|
||||
@ -90,7 +91,7 @@ func TestProjectCRUDAdmin(t *testing.T) {
|
||||
t.Fatalf("\t%s\tDecode expected failed.", tests.Failed)
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
if len(expectedMap) == 0 {
|
||||
printResultMap(ctx, w.Body.Bytes()) // used to help format expectedMap
|
||||
}
|
||||
@ -156,17 +157,17 @@ func TestProjectCRUDAdmin(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("project %s not found: Entity not found", randID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -195,17 +196,17 @@ func TestProjectCRUDAdmin(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("project %s not found: Entity not found", forbiddenProject.ID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -340,17 +341,15 @@ func TestProjectCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -416,17 +415,17 @@ func TestProjectCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("project %s not found: Entity not found", randID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -455,17 +454,17 @@ func TestProjectCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("project %s not found: Entity not found", forbiddenProject.ID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -497,17 +496,15 @@ func TestProjectCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -537,17 +534,15 @@ func TestProjectCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -575,17 +570,15 @@ func TestProjectCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -626,20 +619,27 @@ func TestProjectCreate(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "status", Error: "Key: 'ProjectCreateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "status", Error: "Key: 'ProjectCreateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
||||
{
|
||||
Field: "status",
|
||||
Value: invalidStatus.String(),
|
||||
Tag: "oneof",
|
||||
Error: "status must be one of [active disabled]",
|
||||
Display: "status must be one of [active disabled]",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -681,20 +681,27 @@ func TestProjectUpdate(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "status", Error: "Key: 'ProjectUpdateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "status", Error: "Key: 'ProjectUpdateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
||||
{
|
||||
Field: "status",
|
||||
Value: invalidStatus.String(),
|
||||
Tag: "oneof",
|
||||
Error: "status must be one of [active disabled]",
|
||||
Display: "status must be one of [active disabled]",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -716,12 +723,14 @@ func TestProjectArchive(t *testing.T) {
|
||||
{
|
||||
expectedStatus := http.StatusBadRequest
|
||||
|
||||
invalidId := "a"
|
||||
|
||||
rt := requestTest{
|
||||
fmt.Sprintf("Archive %d w/role %s using invalid data", expectedStatus, tr.Role),
|
||||
http.MethodPatch,
|
||||
"/v1/projects/archive",
|
||||
project.ProjectArchiveRequest{
|
||||
ID: "a",
|
||||
ID: invalidId,
|
||||
},
|
||||
tr.Token,
|
||||
tr.Claims,
|
||||
@ -736,20 +745,27 @@ func TestProjectArchive(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "id", Error: "Key: 'ProjectArchiveRequest.id' Error:Field validation for 'id' failed on the 'uuid' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "id", Error: "Key: 'ProjectArchiveRequest.id' Error:Field validation for 'id' failed on the 'uuid' tag"},
|
||||
{
|
||||
Field: "id",
|
||||
Value: invalidId,
|
||||
Tag: "uuid",
|
||||
Error: "id must be a valid UUID",
|
||||
Display: "id must be a valid UUID",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -779,17 +795,17 @@ func TestProjectArchive(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: project.ErrForbidden.Error(),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -811,10 +827,12 @@ func TestProjectDelete(t *testing.T) {
|
||||
{
|
||||
expectedStatus := http.StatusBadRequest
|
||||
|
||||
invalidId := "a"
|
||||
|
||||
rt := requestTest{
|
||||
fmt.Sprintf("Delete %d w/role %s using invalid data", expectedStatus, tr.Role),
|
||||
http.MethodDelete,
|
||||
"/v1/projects/a",
|
||||
"/v1/projects/" + invalidId,
|
||||
nil,
|
||||
tr.Token,
|
||||
tr.Claims,
|
||||
@ -829,20 +847,27 @@ func TestProjectDelete(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "id", Error: "Key: 'id' Error:Field validation for 'id' failed on the 'uuid' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "id", Error: "Key: 'id' Error:Field validation for 'id' failed on the 'uuid' tag"},
|
||||
{
|
||||
Field: "id",
|
||||
Value: invalidId,
|
||||
Tag: "uuid",
|
||||
Error: "id must be a valid UUID",
|
||||
Display: "id must be a valid UUID",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -870,17 +895,17 @@ func TestProjectDelete(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: project.ErrForbidden.Error(),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/auth"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/tests"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/signup"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/user"
|
||||
"github.com/pborman/uuid"
|
||||
@ -37,7 +38,8 @@ func mockSignupRequest() signup.SignupRequest {
|
||||
Zipcode: "99686",
|
||||
},
|
||||
User: signup.SignupUser{
|
||||
Name: "Lee Brown",
|
||||
FirstName: "Lee",
|
||||
LastName: "Brown",
|
||||
Email: uuid.NewRandom().String() + "@geeksinthewoods.com",
|
||||
Password: "akTechFr0n!ier",
|
||||
PasswordConfirm: "akTechFr0n!ier",
|
||||
@ -114,7 +116,8 @@ func TestSignup(t *testing.T) {
|
||||
expectedMap := map[string]interface{}{
|
||||
"user": map[string]interface{}{
|
||||
"id": actual.User.ID,
|
||||
"name": req.User.Name,
|
||||
"first_name": req.User.FirstName,
|
||||
"last_name": req.User.LastName,
|
||||
"email": req.User.Email,
|
||||
"timezone": actual.User.Timezone,
|
||||
"created_at": web.NewTimeResponse(ctx, actual.User.CreatedAt.Value),
|
||||
@ -149,7 +152,7 @@ func TestSignup(t *testing.T) {
|
||||
t.Fatalf("\t%s\tDecode expected failed.", tests.Failed)
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
if len(expectedMap) == 0 {
|
||||
printResultMap(ctx, w.Body.Bytes()) // used to help format expectedMap
|
||||
}
|
||||
@ -180,17 +183,17 @@ func TestSignup(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "decode request body failed: EOF",
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "decode request body failed",
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -221,21 +224,36 @@ func TestSignup(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "name", Error: "Key: 'SignupRequest.account.name' Error:Field validation for 'name' failed on the 'required' tag"},
|
||||
{Field: "email", Error: "Key: 'SignupRequest.user.email' Error:Field validation for 'email' failed on the 'required' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "name", Error: "Key: 'SignupRequest.account.name' Error:Field validation for 'name' failed on the 'required' tag"},
|
||||
//{Field: "email", Error: "Key: 'SignupRequest.user.email' Error:Field validation for 'email' failed on the 'required' tag"},
|
||||
|
||||
{
|
||||
Field: "name",
|
||||
Value: "",
|
||||
Tag: "required",
|
||||
Error: "Name is a required field",
|
||||
Display: "Name is a required field",
|
||||
},
|
||||
{
|
||||
Field: "email",
|
||||
Value: "",
|
||||
Tag: "required",
|
||||
Error: "email is a required field",
|
||||
Display: "email is a required field",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@ -19,6 +20,7 @@ import (
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/auth"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/tests"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/signup"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/user"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/user_account"
|
||||
@ -81,7 +83,7 @@ func testMain(m *testing.M) int {
|
||||
|
||||
log := test.Log
|
||||
log.SetOutput(ioutil.Discard)
|
||||
a = handlers.API(shutdown, log, test.MasterDB, nil, authenticator)
|
||||
a = handlers.API(shutdown, log, webcontext.Env_Dev, test.MasterDB, nil, authenticator)
|
||||
|
||||
// Create a new account directly business logic. This creates an
|
||||
// initial account and user that we will use for admin validated endpoints.
|
||||
@ -122,7 +124,8 @@ func testMain(m *testing.M) int {
|
||||
|
||||
// Create a regular user to use when calling regular validated endpoints.
|
||||
userReq := user.UserCreateRequest{
|
||||
Name: "Lucas Brown",
|
||||
FirstName: "Lucas",
|
||||
LastName: "Brown",
|
||||
Email: uuid.NewRandom().String() + "@geeksinthewoods.com",
|
||||
Password: "akTechFr0n!ier",
|
||||
PasswordConfirm: "akTechFr0n!ier",
|
||||
@ -204,7 +207,7 @@ func executeRequestTest(t *testing.T, tt requestTest, ctx context.Context) (*htt
|
||||
}
|
||||
|
||||
if tt.error != nil {
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tBody : %s\n", w.Body.String())
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/auth"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/tests"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/user"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/user_account"
|
||||
"github.com/pborman/uuid"
|
||||
@ -105,7 +106,7 @@ func TestUserAccountCRUDAdmin(t *testing.T) {
|
||||
t.Fatalf("\t%s\tDecode expected failed.", tests.Failed)
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
if len(expectedMap) == 0 {
|
||||
printResultMap(ctx, w.Body.Bytes()) // used to help format expectedMap
|
||||
}
|
||||
@ -171,17 +172,17 @@ func TestUserAccountCRUDAdmin(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("user account %s not found: Entity not found", randID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -210,17 +211,17 @@ func TestUserAccountCRUDAdmin(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("user account %s not found: Entity not found", forbiddenUserAccount.ID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -363,17 +364,15 @@ func TestUserAccountCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -439,17 +438,17 @@ func TestUserAccountCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("user account %s not found: Entity not found", randID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -478,17 +477,17 @@ func TestUserAccountCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("user account %s not found: Entity not found", forbiddenUserAccount.ID),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -521,17 +520,17 @@ func TestUserAccountCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: account.ErrForbidden.Error(),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -562,17 +561,15 @@ func TestUserAccountCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -603,17 +600,15 @@ func TestUserAccountCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -657,20 +652,27 @@ func TestUserAccountCreate(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "status", Error: "Key: 'UserAccountCreateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "status", Error: "Key: 'UserAccountCreateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
||||
{
|
||||
Field: "status",
|
||||
Value: invalidStatus.String(),
|
||||
Tag: "oneof",
|
||||
Error: "status must be one of [active invited disabled]",
|
||||
Display: "status must be one of [active invited disabled]",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -713,20 +715,27 @@ func TestUserAccountUpdate(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "status", Error: "Key: 'UserAccountUpdateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "status", Error: "Key: 'UserAccountUpdateRequest.status' Error:Field validation for 'status' failed on the 'oneof' tag"},
|
||||
{
|
||||
Field: "status",
|
||||
Value: invalidStatus.String(),
|
||||
Tag: "oneof",
|
||||
Error: "status must be one of [active invited disabled]",
|
||||
Display: "status must be one of [active invited disabled]",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -745,15 +754,15 @@ func TestUserAccountArchive(t *testing.T) {
|
||||
// Test archive with invalid data.
|
||||
{
|
||||
expectedStatus := http.StatusBadRequest
|
||||
|
||||
req := user_account.UserAccountArchiveRequest{
|
||||
UserID: "foo",
|
||||
AccountID: "bar",
|
||||
}
|
||||
rt := requestTest{
|
||||
fmt.Sprintf("Archive %d w/role %s using invalid data", expectedStatus, tr.Role),
|
||||
http.MethodPatch,
|
||||
"/v1/user_accounts/archive",
|
||||
user_account.UserAccountArchiveRequest{
|
||||
UserID: "foo",
|
||||
AccountID: "bar",
|
||||
},
|
||||
req,
|
||||
tr.Token,
|
||||
tr.Claims,
|
||||
expectedStatus,
|
||||
@ -767,21 +776,35 @@ func TestUserAccountArchive(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "user_id", Error: "Key: 'UserAccountArchiveRequest.user_id' Error:Field validation for 'user_id' failed on the 'uuid' tag"},
|
||||
{Field: "account_id", Error: "Key: 'UserAccountArchiveRequest.account_id' Error:Field validation for 'account_id' failed on the 'uuid' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "user_id", Error: "Key: 'UserAccountArchiveRequest.user_id' Error:Field validation for 'user_id' failed on the 'uuid' tag"},
|
||||
//{Field: "account_id", Error: "Key: 'UserAccountArchiveRequest.account_id' Error:Field validation for 'account_id' failed on the 'uuid' tag"},
|
||||
{
|
||||
Field: "user_id",
|
||||
Value: req.UserID,
|
||||
Tag: "uuid",
|
||||
Error: "user_id must be a valid UUID",
|
||||
Display: "user_id must be a valid UUID",
|
||||
},
|
||||
{
|
||||
Field: "account_id",
|
||||
Value: req.AccountID,
|
||||
Tag: "uuid",
|
||||
Error: "account_id must be a valid UUID",
|
||||
Display: "account_id must be a valid UUID",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -813,17 +836,17 @@ func TestUserAccountArchive(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: user_account.ErrForbidden.Error(),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -866,21 +889,35 @@ func TestUserAccountDelete(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "user_id", Error: "Key: 'UserAccountDeleteRequest.user_id' Error:Field validation for 'user_id' failed on the 'uuid' tag"},
|
||||
{Field: "account_id", Error: "Key: 'UserAccountDeleteRequest.account_id' Error:Field validation for 'account_id' failed on the 'uuid' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "user_id", Error: "Key: 'UserAccountDeleteRequest.user_id' Error:Field validation for 'user_id' failed on the 'uuid' tag"},
|
||||
//{Field: "account_id", Error: "Key: 'UserAccountDeleteRequest.account_id' Error:Field validation for 'account_id' failed on the 'uuid' tag"},
|
||||
{
|
||||
Field: "user_id",
|
||||
Value: req.UserID,
|
||||
Tag: "uuid",
|
||||
Error: "user_id must be a valid UUID",
|
||||
Display: "user_id must be a valid UUID",
|
||||
},
|
||||
{
|
||||
Field: "account_id",
|
||||
Value: req.AccountID,
|
||||
Tag: "uuid",
|
||||
Error: "account_id must be a valid UUID",
|
||||
Display: "account_id must be a valid UUID",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -912,17 +949,17 @@ func TestUserAccountDelete(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: user_account.ErrForbidden.Error(),
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/auth"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/tests"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/user"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/user_account"
|
||||
"github.com/pborman/uuid"
|
||||
@ -25,7 +26,8 @@ type mockUser struct {
|
||||
|
||||
func mockUserCreateRequest() user.UserCreateRequest {
|
||||
return user.UserCreateRequest{
|
||||
Name: "Lee Brown",
|
||||
FirstName: "Lee",
|
||||
LastName: "Brown",
|
||||
Email: uuid.NewRandom().String() + "@geeksinthewoods.com",
|
||||
Password: "akTechFr0n!ier",
|
||||
PasswordConfirm: "akTechFr0n!ier",
|
||||
@ -101,7 +103,8 @@ func TestUserCRUDAdmin(t *testing.T) {
|
||||
"email": req.Email,
|
||||
"timezone": actual.Timezone,
|
||||
"created_at": web.NewTimeResponse(ctx, actual.CreatedAt.Value),
|
||||
"name": req.Name,
|
||||
"first_name": req.FirstName,
|
||||
"last_name": req.LastName,
|
||||
}
|
||||
|
||||
var expected user.UserResponse
|
||||
@ -187,13 +190,13 @@ func TestUserCRUDAdmin(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("user %s not found: Entity not found", randID),
|
||||
}
|
||||
|
||||
@ -225,13 +228,13 @@ func TestUserCRUDAdmin(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("user %s not found: Entity not found", tr.ForbiddenUser.ID),
|
||||
}
|
||||
|
||||
@ -251,8 +254,8 @@ func TestUserCRUDAdmin(t *testing.T) {
|
||||
http.MethodPatch,
|
||||
"/v1/users",
|
||||
user.UserUpdateRequest{
|
||||
ID: created.ID,
|
||||
Name: &newName,
|
||||
ID: created.ID,
|
||||
FirstName: &newName,
|
||||
},
|
||||
tr.Token,
|
||||
tr.Claims,
|
||||
@ -415,6 +418,7 @@ func TestUserCRUDAdmin(t *testing.T) {
|
||||
"access_token": actual["access_token"],
|
||||
"token_type": actual["token_type"],
|
||||
"expiry": actual["expiry"],
|
||||
"ttl": actual["ttl"],
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
@ -471,15 +475,13 @@ func TestUserCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
@ -547,13 +549,13 @@ func TestUserCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("user %s not found: Entity not found", randID),
|
||||
}
|
||||
|
||||
@ -585,13 +587,13 @@ func TestUserCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: fmt.Sprintf("user %s not found: Entity not found", tr.ForbiddenUser.ID),
|
||||
}
|
||||
|
||||
@ -611,8 +613,8 @@ func TestUserCRUDUser(t *testing.T) {
|
||||
http.MethodPatch,
|
||||
"/v1/users",
|
||||
user.UserUpdateRequest{
|
||||
ID: created.ID,
|
||||
Name: &newName,
|
||||
ID: created.ID,
|
||||
FirstName: &newName,
|
||||
},
|
||||
tr.Token,
|
||||
tr.Claims,
|
||||
@ -627,13 +629,13 @@ func TestUserCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: user.ErrForbidden.Error(),
|
||||
}
|
||||
|
||||
@ -670,13 +672,13 @@ func TestUserCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: user.ErrForbidden.Error(),
|
||||
}
|
||||
|
||||
@ -710,15 +712,13 @@ func TestUserCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
@ -748,15 +748,13 @@ func TestUserCRUDUser(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: mid.ErrForbidden.Error(),
|
||||
}
|
||||
expected := mid.ErrorForbidden(ctx).(*weberror.Error).Display(ctx)
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
@ -807,6 +805,7 @@ func TestUserCRUDUser(t *testing.T) {
|
||||
"access_token": actual["access_token"],
|
||||
"token_type": actual["token_type"],
|
||||
"expiry": actual["expiry"],
|
||||
"ttl": actual["ttl"],
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
@ -864,16 +863,23 @@ func TestUserCreate(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "email", Error: "Key: 'UserCreateRequest.email' Error:Field validation for 'email' failed on the 'email' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "email", Error: "Key: 'UserCreateRequest.email' Error:Field validation for 'email' failed on the 'email' tag"},
|
||||
{
|
||||
Field: "email",
|
||||
Value: req.Email,
|
||||
Tag: "email",
|
||||
Error: "email must be a valid email address",
|
||||
Display: "email must be a valid email address",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -919,16 +925,23 @@ func TestUserUpdate(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "email", Error: "Key: 'UserUpdateRequest.email' Error:Field validation for 'email' failed on the 'email' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "email", Error: "Key: 'UserUpdateRequest.email' Error:Field validation for 'email' failed on the 'email' tag"},
|
||||
{
|
||||
Field: "email",
|
||||
Value: invalidEmail,
|
||||
Tag: "email",
|
||||
Error: "email must be a valid email address",
|
||||
Display: "email must be a valid email address",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -956,6 +969,8 @@ func TestUserUpdatePassword(t *testing.T) {
|
||||
expectedStatus := http.StatusBadRequest
|
||||
|
||||
newPass := uuid.NewRandom().String()
|
||||
diffPass := "different"
|
||||
|
||||
rt := requestTest{
|
||||
fmt.Sprintf("Update password %d w/role %s using invalid data", expectedStatus, tr.Role),
|
||||
http.MethodPatch,
|
||||
@ -963,7 +978,7 @@ func TestUserUpdatePassword(t *testing.T) {
|
||||
user.UserUpdatePasswordRequest{
|
||||
ID: created.ID,
|
||||
Password: newPass,
|
||||
PasswordConfirm: "different",
|
||||
PasswordConfirm: diffPass,
|
||||
},
|
||||
tr.Token,
|
||||
tr.Claims,
|
||||
@ -978,16 +993,23 @@ func TestUserUpdatePassword(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "password_confirm", Error: "Key: 'UserUpdatePasswordRequest.password_confirm' Error:Field validation for 'password_confirm' failed on the 'eqfield' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "password_confirm", Error: "Key: 'UserUpdatePasswordRequest.password_confirm' Error:Field validation for 'password_confirm' failed on the 'eqfield' tag"},
|
||||
{
|
||||
Field: "password_confirm",
|
||||
Value: diffPass,
|
||||
Tag: "eqfield",
|
||||
Error: "password_confirm must be equal to Password",
|
||||
Display: "password_confirm must be equal to Password",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -1011,12 +1033,14 @@ func TestUserArchive(t *testing.T) {
|
||||
{
|
||||
expectedStatus := http.StatusBadRequest
|
||||
|
||||
invalidId := "a"
|
||||
|
||||
rt := requestTest{
|
||||
fmt.Sprintf("Archive %d w/role %s using invalid data", expectedStatus, tr.Role),
|
||||
http.MethodPatch,
|
||||
"/v1/users/archive",
|
||||
user.UserArchiveRequest{
|
||||
ID: "a",
|
||||
ID: invalidId,
|
||||
},
|
||||
tr.Token,
|
||||
tr.Claims,
|
||||
@ -1031,16 +1055,23 @@ func TestUserArchive(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "id", Error: "Key: 'UserArchiveRequest.id' Error:Field validation for 'id' failed on the 'uuid' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "id", Error: "Key: 'UserArchiveRequest.id' Error:Field validation for 'id' failed on the 'uuid' tag"},
|
||||
{
|
||||
Field: "id",
|
||||
Value: invalidId,
|
||||
Tag: "uuid",
|
||||
Error: "id must be a valid UUID",
|
||||
Display: "id must be a valid UUID",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -1074,13 +1105,13 @@ func TestUserArchive(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: user.ErrForbidden.Error(),
|
||||
}
|
||||
|
||||
@ -1104,10 +1135,12 @@ func TestUserDelete(t *testing.T) {
|
||||
{
|
||||
expectedStatus := http.StatusBadRequest
|
||||
|
||||
invalidId := "345345"
|
||||
|
||||
rt := requestTest{
|
||||
fmt.Sprintf("Delete %d w/role %s using invalid data", expectedStatus, tr.Role),
|
||||
http.MethodDelete,
|
||||
"/v1/users/345345",
|
||||
fmt.Sprintf("/v1/users/%s", invalidId),
|
||||
nil,
|
||||
tr.Token,
|
||||
tr.Claims,
|
||||
@ -1122,16 +1155,23 @@ func TestUserDelete(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "id", Error: "Key: 'id' Error:Field validation for 'id' failed on the 'uuid' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
//{Field: "id", Error: "Key: 'id' Error:Field validation for 'id' failed on the 'uuid' tag"},
|
||||
{
|
||||
Field: "id",
|
||||
Value: invalidId,
|
||||
Tag: "uuid",
|
||||
Error: "id must be a valid UUID",
|
||||
Display: "id must be a valid UUID",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -1163,13 +1203,13 @@ func TestUserDelete(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: user.ErrForbidden.Error(),
|
||||
}
|
||||
|
||||
@ -1193,10 +1233,12 @@ func TestUserSwitchAccount(t *testing.T) {
|
||||
{
|
||||
expectedStatus := http.StatusBadRequest
|
||||
|
||||
invalidAccountId := "sf"
|
||||
|
||||
rt := requestTest{
|
||||
fmt.Sprintf("Switch account %d w/role %s using invalid data", expectedStatus, tr.Role),
|
||||
http.MethodPatch,
|
||||
"/v1/users/switch-account/sf",
|
||||
"/v1/users/switch-account/" + invalidAccountId,
|
||||
nil,
|
||||
tr.Token,
|
||||
tr.Claims,
|
||||
@ -1211,20 +1253,26 @@ func TestUserSwitchAccount(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
Error: "field validation error",
|
||||
Fields: []web.FieldError{
|
||||
{Field: "account_id", Error: "Key: 'account_id' Error:Field validation for 'account_id' failed on the 'uuid' tag"},
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "Field validation error",
|
||||
Fields: []weberror.FieldError{
|
||||
{
|
||||
Field: "account_id",
|
||||
Value: invalidAccountId,
|
||||
Tag: "uuid",
|
||||
Error: "account_id must be a valid UUID",
|
||||
Display: "account_id must be a valid UUID",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
if diff := cmpDiff(t, expected, actual); diff {
|
||||
t.Fatalf("\t%s\tReceived expected error.", tests.Failed)
|
||||
}
|
||||
t.Logf("\t%s\tReceived expected error.", tests.Success)
|
||||
@ -1252,13 +1300,13 @@ func TestUserSwitchAccount(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: user.ErrAuthenticationFailure.Error(),
|
||||
}
|
||||
|
||||
@ -1295,13 +1343,13 @@ func TestUserToken(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: "must provide email and password in Basic auth",
|
||||
}
|
||||
|
||||
@ -1342,13 +1390,13 @@ func TestUserToken(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: user.ErrAuthenticationFailure.Error(),
|
||||
}
|
||||
|
||||
@ -1390,13 +1438,13 @@ func TestUserToken(t *testing.T) {
|
||||
}
|
||||
t.Logf("\t%s\tReceived valid status code of %d.", tests.Success, w.Code)
|
||||
|
||||
var actual web.ErrorResponse
|
||||
var actual weberror.ErrorResponse
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &actual); err != nil {
|
||||
t.Logf("\t\tGot error : %+v", err)
|
||||
t.Fatalf("\t%s\tDecode response body failed.", tests.Failed)
|
||||
}
|
||||
|
||||
expected := web.ErrorResponse{
|
||||
expected := weberror.ErrorResponse{
|
||||
Error: user.ErrAuthenticationFailure.Error(),
|
||||
}
|
||||
|
||||
@ -1450,6 +1498,7 @@ func TestUserToken(t *testing.T) {
|
||||
"access_token": actual["access_token"],
|
||||
"token_type": actual["token_type"],
|
||||
"expiry": actual["expiry"],
|
||||
"ttl": actual["ttl"],
|
||||
}
|
||||
|
||||
if diff := cmpDiff(t, actual, expected); diff {
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
tmplLayoutBase = "base.tmpl"
|
||||
tmplLayoutBase = "base.gohtml"
|
||||
tmplContentErrorGeneric = "error-generic.gohtml"
|
||||
)
|
||||
|
||||
|
@ -2,11 +2,11 @@ package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/geonames"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/account"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/geonames"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/auth"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext"
|
||||
@ -104,5 +104,5 @@ func (h *Signup) Step1(ctx context.Context, w http.ResponseWriter, r *http.Reque
|
||||
data["validationDefaults"] = verr.(*weberror.Error)
|
||||
}
|
||||
|
||||
return h.Renderer.Render(ctx, w, r, tmplLayoutBase, "signup-step1.tmpl", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data)
|
||||
return h.Renderer.Render(ctx, w, r, tmplLayoutBase, "signup-step1.gohtml", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data)
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ func (h *User) Login(ctx context.Context, w http.ResponseWriter, r *http.Request
|
||||
data["validationDefaults"] = verr.(*weberror.Error)
|
||||
}
|
||||
|
||||
return h.Renderer.Render(ctx, w, r, tmplLayoutBase, "user-login.tmpl", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data)
|
||||
return h.Renderer.Render(ctx, w, r, tmplLayoutBase, "user-login.gohtml", web.MIMETextHTMLCharsetUTF8, http.StatusOK, data)
|
||||
}
|
||||
|
||||
// handleSessionToken persists the access token to the session for request authentication.
|
||||
|
@ -12,7 +12,6 @@ import (
|
||||
"github.com/pborman/uuid"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
|
||||
"gopkg.in/go-playground/validator.v9"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -262,23 +261,17 @@ func Create(ctx context.Context, claims auth.Claims, dbConn *sqlx.DB, req Accoun
|
||||
span, ctx := tracer.StartSpanFromContext(ctx, "internal.account.Create")
|
||||
defer span.Finish()
|
||||
|
||||
// Validation email address is unique in the database.
|
||||
v := webcontext.Validator()
|
||||
|
||||
// Validation account name is unique in the database.
|
||||
uniq, err := UniqueName(ctx, dbConn, req.Name, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f := func(fl validator.FieldLevel) bool {
|
||||
if fl.Field().String() == "invalid" {
|
||||
return false
|
||||
}
|
||||
return uniq
|
||||
}
|
||||
|
||||
v := webcontext.Validator()
|
||||
v.RegisterValidation("unique", f)
|
||||
ctx = context.WithValue(ctx, webcontext.KeyTagUnique, uniq)
|
||||
|
||||
// Validate the request.
|
||||
err = v.Struct(req)
|
||||
err = v.StructCtx(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -371,24 +364,19 @@ func Update(ctx context.Context, claims auth.Claims, dbConn *sqlx.DB, req Accoun
|
||||
|
||||
v := webcontext.Validator()
|
||||
|
||||
// Validation name is unique in the database.
|
||||
if req.Name != nil {
|
||||
// Validation account name is unique in the database.
|
||||
uniq, err := UniqueName(ctx, dbConn, *req.Name, req.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f := func(fl validator.FieldLevel) bool {
|
||||
if fl.Field().String() == "invalid" {
|
||||
return false
|
||||
}
|
||||
|
||||
return uniq
|
||||
}
|
||||
v.RegisterValidation("unique", f)
|
||||
ctx = context.WithValue(ctx, webcontext.KeyTagUnique, uniq)
|
||||
} else {
|
||||
ctx = context.WithValue(ctx, webcontext.KeyTagUnique, true)
|
||||
}
|
||||
|
||||
// Validate the request.
|
||||
err := v.Struct(req)
|
||||
err := v.StructCtx(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ func testMain(m *testing.M) int {
|
||||
|
||||
// TestFindRequestQuery validates findRequestQuery
|
||||
func TestFindRequestQuery(t *testing.T) {
|
||||
where := "name = ? or address1 = ?"
|
||||
where := "first_name = ? or address1 = ?"
|
||||
var (
|
||||
limit uint = 12
|
||||
offset uint = 34
|
||||
@ -41,7 +41,7 @@ func TestFindRequestQuery(t *testing.T) {
|
||||
req := AccountFindRequest{
|
||||
Where: &where,
|
||||
Args: []interface{}{
|
||||
"lee brown",
|
||||
"lee",
|
||||
"103 East Main St.",
|
||||
},
|
||||
Order: []string{
|
||||
@ -51,7 +51,7 @@ func TestFindRequestQuery(t *testing.T) {
|
||||
Limit: &limit,
|
||||
Offset: &offset,
|
||||
}
|
||||
expected := "SELECT " + accountMapColumns + " FROM " + accountTableName + " WHERE (name = ? or address1 = ?) ORDER BY id asc, created_at desc LIMIT 12 OFFSET 34"
|
||||
expected := "SELECT " + accountMapColumns + " FROM " + accountTableName + " WHERE (first_name = ? or address1 = ?) ORDER BY id asc, created_at desc LIMIT 12 OFFSET 34"
|
||||
|
||||
res, args := findRequestQuery(req)
|
||||
|
||||
@ -223,7 +223,8 @@ func TestCreateValidation(t *testing.T) {
|
||||
// of type interface validator.ValidationErrorsTranslations
|
||||
var errStr string
|
||||
if err != nil {
|
||||
errStr = err.Error()
|
||||
errStr = strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
}
|
||||
var expectStr string
|
||||
if tt.error != nil {
|
||||
@ -293,8 +294,11 @@ func TestCreateValidationNameUnique(t *testing.T) {
|
||||
t.Fatalf("\t%s\tCreate failed.", tests.Failed)
|
||||
}
|
||||
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Logf("\t\tGot : %+v", err)
|
||||
errStr := strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
|
||||
if errStr != expectedErr.Error() {
|
||||
t.Logf("\t\tGot : %+v", errStr)
|
||||
t.Logf("\t\tWant: %+v", expectedErr)
|
||||
t.Fatalf("\t%s\tCreate failed.", tests.Failed)
|
||||
}
|
||||
@ -431,7 +435,8 @@ func TestUpdateValidation(t *testing.T) {
|
||||
// of type interface validator.ValidationErrorsTranslations
|
||||
var errStr string
|
||||
if err != nil {
|
||||
errStr = err.Error()
|
||||
errStr = strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
}
|
||||
var expectStr string
|
||||
if tt.error != nil {
|
||||
@ -501,8 +506,11 @@ func TestUpdateValidationNameUnique(t *testing.T) {
|
||||
t.Fatalf("\t%s\tUpdate failed.", tests.Failed)
|
||||
}
|
||||
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Logf("\t\tGot : %+v", err)
|
||||
errStr := strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
|
||||
if errStr != expectedErr.Error() {
|
||||
t.Logf("\t\tGot : %+v", errStr)
|
||||
t.Logf("\t\tWant: %+v", expectedErr)
|
||||
t.Fatalf("\t%s\tUpdate failed.", tests.Failed)
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package saasSwagger
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/weberror"
|
||||
"github.com/pborman/uuid"
|
||||
"html/template"
|
||||
"net/http"
|
||||
@ -74,7 +75,7 @@ func SaasWrapHandler(confs ...func(c *Config)) web.Handler {
|
||||
prefix = matches[1]
|
||||
} else if len(matches) > 0 {
|
||||
err := errors.WithMessagef(ErrNotFound, "page %s not found", r.RequestURI)
|
||||
return web.NewRequestError(err, http.StatusNotFound)
|
||||
return weberror.NewError(ctx, err, http.StatusNotFound)
|
||||
}
|
||||
|
||||
// Default to index page.
|
||||
@ -92,7 +93,7 @@ func SaasWrapHandler(confs ...func(c *Config)) web.Handler {
|
||||
case "doc.json":
|
||||
doc, err := swag.ReadDoc()
|
||||
if err != nil {
|
||||
return web.NewRequestError(err, http.StatusInternalServerError)
|
||||
return weberror.NewError(ctx, err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// Replace the dynamic placeholder {RANDOM_UUID}
|
||||
|
@ -3,6 +3,7 @@ package tests
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
@ -12,7 +13,6 @@ import (
|
||||
"time"
|
||||
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/docker"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web"
|
||||
"geeks-accelerator/oss/saas-starter-kit/internal/schema"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/jmoiron/sqlx"
|
||||
@ -94,7 +94,7 @@ func New() *Test {
|
||||
}
|
||||
|
||||
// Execute the migrations
|
||||
if err = schema.Migrate(masterDB, log); err != nil {
|
||||
if err = schema.Migrate(masterDB, log, true); err != nil {
|
||||
log.Fatalf("main : Migrate : %v", err)
|
||||
}
|
||||
log.Printf("main : Migrate : Completed")
|
||||
@ -126,10 +126,10 @@ func Recover(t *testing.T) {
|
||||
|
||||
// Context returns an app level context for testing.
|
||||
func Context() context.Context {
|
||||
values := web.Values{
|
||||
values := webcontext.Values{
|
||||
TraceID: uint64(time.Now().UnixNano()),
|
||||
Now: time.Now(),
|
||||
}
|
||||
|
||||
return context.WithValue(context.Background(), web.KeyValues, &values)
|
||||
return context.WithValue(context.Background(), webcontext.KeyValues, &values)
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ const (
|
||||
)
|
||||
|
||||
// RespondJsonError sends an error formatted as JSON response back to the client.
|
||||
func RespondJsonError(ctx context.Context, w http.ResponseWriter, err error) error {
|
||||
func RespondJsonError(ctx context.Context, w http.ResponseWriter, er error) error {
|
||||
|
||||
// Set the status code for the request logger middleware.
|
||||
// If the context is missing this value, request the service
|
||||
@ -41,9 +41,13 @@ func RespondJsonError(ctx context.Context, w http.ResponseWriter, err error) err
|
||||
return err
|
||||
}
|
||||
|
||||
// If the error was of the type *Error, the handler has
|
||||
// a specific status code and error to return.
|
||||
webErr := weberror.NewError(ctx, err, v.StatusCode).(*weberror.Error)
|
||||
webErr, ok := er.(*weberror.Error)
|
||||
if !ok {
|
||||
// If the error was of the type *Error, the handler has
|
||||
// a specific status code and error to return.
|
||||
webErr = weberror.NewError(ctx, er, v.StatusCode).(*weberror.Error)
|
||||
}
|
||||
|
||||
v.StatusCode = webErr.Status
|
||||
|
||||
return RespondJson(ctx, w, webErr.Display(ctx), webErr.Status)
|
||||
|
@ -34,7 +34,10 @@ func ContextWithTranslator(ctx context.Context, translator ut.Translator) contex
|
||||
|
||||
// ContextTranslator returns the universal context from a context.
|
||||
func ContextTranslator(ctx context.Context) ut.Translator {
|
||||
return ctx.Value(KeyTranslate).(ut.Translator)
|
||||
if t, ok := ctx.Value(KeyTranslate).(ut.Translator); ok {
|
||||
return t
|
||||
}
|
||||
return uniTrans.GetFallback()
|
||||
}
|
||||
|
||||
// validate holds the settings and caches for validating request struct values.
|
||||
@ -122,6 +125,10 @@ func init() {
|
||||
|
||||
}
|
||||
|
||||
type ctxKeyTagUnique int
|
||||
|
||||
const KeyTagUnique ctxKeyTagUnique = 1
|
||||
|
||||
// newValidator inits a new validator with custom settings.
|
||||
func newValidator() *validator.Validate {
|
||||
var v = validator.New()
|
||||
@ -139,10 +146,18 @@ func newValidator() *validator.Validate {
|
||||
|
||||
// Empty method that can be overwritten in business logic packages to prevent web.Decode from failing.
|
||||
f := func(fl validator.FieldLevel) bool {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
v.RegisterValidation("unique", f)
|
||||
|
||||
fctx := func(ctx context.Context, fl validator.FieldLevel) bool {
|
||||
if fl.Field().String() == "invalid" {
|
||||
return false
|
||||
}
|
||||
return ctx.Value(KeyTagUnique).(bool)
|
||||
}
|
||||
v.RegisterValidationCtx("unique", fctx)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@ package weberror
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@ -44,7 +43,7 @@ func NewValidationError(ctx context.Context, err error) (error, bool) {
|
||||
fieldErr = strings.Replace(fieldErr, "}}", "", -1)
|
||||
|
||||
field := FieldError{
|
||||
Field: verror.Field(),
|
||||
Field: fieldName,
|
||||
Value: verror.Value(),
|
||||
Tag: verror.Tag(),
|
||||
Error: fieldErr,
|
||||
@ -52,12 +51,12 @@ func NewValidationError(ctx context.Context, err error) (error, bool) {
|
||||
Display: fieldErr,
|
||||
}
|
||||
|
||||
switch verror.Tag() {
|
||||
case "required":
|
||||
field.Display = fmt.Sprintf("%s is required.", localName)
|
||||
case "unique":
|
||||
field.Display = fmt.Sprintf("%s must be unique.", localName)
|
||||
}
|
||||
//switch verror.Tag() {
|
||||
//case "required":
|
||||
// field.Display = fmt.Sprintf("%s is required.", localName)
|
||||
//case "unique":
|
||||
// field.Display = fmt.Sprintf("%s must be unique.", localName)
|
||||
//}
|
||||
|
||||
/*
|
||||
fmt.Println("field", field.Error)
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
// initSchema runs before any migrations are executed. This happens when no other migrations
|
||||
// have previously been executed.
|
||||
func initSchema(db *sqlx.DB, log *log.Logger) func(*sqlx.DB) error {
|
||||
func initSchema(db *sqlx.DB, log *log.Logger, isUnittest bool) func(*sqlx.DB) error {
|
||||
f := func(db *sqlx.DB) error {
|
||||
return nil
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
|
||||
// migrationList returns a list of migrations to be executed. If the id of the
|
||||
// migration already exists in the migrations table it will be skipped.
|
||||
func migrationList(db *sqlx.DB, log *log.Logger) []*sqlxmigrate.Migration {
|
||||
func migrationList(db *sqlx.DB, log *log.Logger, isUnittest bool) []*sqlxmigrate.Migration {
|
||||
return []*sqlxmigrate.Migration{
|
||||
// Create table users.
|
||||
{
|
||||
@ -249,18 +249,22 @@ func migrationList(db *sqlx.DB, log *log.Logger) []*sqlxmigrate.Migration {
|
||||
return errors.WithMessagef(err, "Failed to prepare sql query '%s'", q)
|
||||
}
|
||||
|
||||
resChan := make(chan interface{})
|
||||
go geonames.LoadGeonames(context.Background(), resChan)
|
||||
if isUnittest {
|
||||
|
||||
for r := range resChan {
|
||||
switch v := r.(type) {
|
||||
case geonames.Geoname:
|
||||
_, err = stmt.Exec(v.CountryCode, v.PostalCode, v.PlaceName, v.StateName, v.StateCode, v.CountyName, v.CountyCode, v.CommunityName, v.CommunityCode, v.Latitude, v.Longitude, v.Accuracy)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
} else {
|
||||
resChan := make(chan interface{})
|
||||
go geonames.LoadGeonames(context.Background(), resChan)
|
||||
|
||||
for r := range resChan {
|
||||
switch v := r.(type) {
|
||||
case geonames.Geoname:
|
||||
_, err = stmt.Exec(v.CountryCode, v.PostalCode, v.PlaceName, v.StateName, v.StateCode, v.CountyName, v.CountyCode, v.CommunityName, v.CommunityCode, v.Latitude, v.Longitude, v.Accuracy)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
case error:
|
||||
return v
|
||||
}
|
||||
case error:
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,9 +291,35 @@ func migrationList(db *sqlx.DB, log *log.Logger) []*sqlxmigrate.Migration {
|
||||
ID: "20190731-02d",
|
||||
Migrate: func(tx *sql.Tx) error {
|
||||
|
||||
prep := []string{
|
||||
`DROP TABLE IF EXISTS countryinfo`,
|
||||
`CREATE TABLE countryinfo (
|
||||
schemas := []string{
|
||||
// Countries...
|
||||
`DROP TABLE IF EXISTS countries`,
|
||||
`CREATE TABLE countries(
|
||||
code char(2) not null constraint countries_pkey primary key,
|
||||
iso_alpha3 char(3),
|
||||
name character varying(50),
|
||||
capital character varying(50),
|
||||
currency_code char(3),
|
||||
currency_name CHAR(20),
|
||||
phone character varying(20),
|
||||
postal_code_format character varying(200),
|
||||
postal_code_regex character varying(200))`,
|
||||
}
|
||||
|
||||
for _, q := range schemas {
|
||||
_, err := db.Exec(q)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to execute sql query '%s'", q)
|
||||
}
|
||||
}
|
||||
|
||||
if isUnittest {
|
||||
// `insert into countries(code, iso_alpha3, name, capital, currency_code, currency_name, phone, postal_code_format, postal_code_regex)
|
||||
|
||||
} else {
|
||||
prep := []string{
|
||||
`DROP TABLE IF EXISTS countryinfo`,
|
||||
`CREATE TABLE countryinfo (
|
||||
iso_alpha2 char(2),
|
||||
iso_alpha3 char(3),
|
||||
iso_numeric integer,
|
||||
@ -309,38 +339,108 @@ func migrationList(db *sqlx.DB, log *log.Logger) []*sqlxmigrate.Migration {
|
||||
geonameId int,
|
||||
neighbours character varying(50),
|
||||
equivalent_fips_code character varying(3))`,
|
||||
}
|
||||
}
|
||||
|
||||
for _, q := range prep {
|
||||
_, err := db.Exec(q)
|
||||
for _, q := range prep {
|
||||
_, err := db.Exec(q)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to execute sql query '%s'", q)
|
||||
}
|
||||
}
|
||||
|
||||
u := "http://download.geonames.org/export/dump/countryInfo.txt"
|
||||
resp, err := pester.Get(u)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to execute sql query '%s'", q)
|
||||
return errors.WithMessagef(err, "Failed to read country info from '%s'", u)
|
||||
}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
u := "http://download.geonames.org/export/dump/countryInfo.txt"
|
||||
resp, err := pester.Get(u)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read country info from '%s'", u)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
var prevLine string
|
||||
var stmt *sql.Stmt
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
var prevLine string
|
||||
var stmt *sql.Stmt
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
// Skip comments.
|
||||
if strings.HasPrefix(line, "#") {
|
||||
prevLine = line
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip comments.
|
||||
if strings.HasPrefix(line, "#") {
|
||||
prevLine = line
|
||||
continue
|
||||
}
|
||||
// Pull the last comment to load the fields.
|
||||
if stmt == nil {
|
||||
prevLine = strings.TrimPrefix(prevLine, "#")
|
||||
r := csv.NewReader(strings.NewReader(prevLine))
|
||||
r.Comma = '\t' // Use tab-delimited instead of comma <---- here!
|
||||
r.FieldsPerRecord = -1
|
||||
|
||||
// Pull the last comment to load the fields.
|
||||
if stmt == nil {
|
||||
prevLine = strings.TrimPrefix(prevLine, "#")
|
||||
r := csv.NewReader(strings.NewReader(prevLine))
|
||||
lines, err := r.ReadAll()
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
var columns []string
|
||||
|
||||
for _, fn := range lines[0] {
|
||||
var cn string
|
||||
switch fn {
|
||||
case "ISO":
|
||||
cn = "iso_alpha2"
|
||||
case "ISO3":
|
||||
cn = "iso_alpha3"
|
||||
case "ISO-Numeric":
|
||||
cn = "iso_numeric"
|
||||
case "fips":
|
||||
cn = "fips_code"
|
||||
case "Country":
|
||||
cn = "country"
|
||||
case "Capital":
|
||||
cn = "capital"
|
||||
case "Area(in sq km)":
|
||||
cn = "areainsqkm"
|
||||
case "Population":
|
||||
cn = "population"
|
||||
case "Continent":
|
||||
cn = "continent"
|
||||
case "tld":
|
||||
cn = "tld"
|
||||
case "CurrencyCode":
|
||||
cn = "currency_code"
|
||||
case "CurrencyName":
|
||||
cn = "currency_name"
|
||||
case "Phone":
|
||||
cn = "phone"
|
||||
case "Postal Code Format":
|
||||
cn = "postal_format"
|
||||
case "Postal Code Regex":
|
||||
cn = "postal_regex"
|
||||
case "Languages":
|
||||
cn = "languages"
|
||||
case "geonameid":
|
||||
cn = "geonameId"
|
||||
case "neighbours":
|
||||
cn = "neighbours"
|
||||
case "EquivalentFipsCode":
|
||||
cn = "equivalent_fips_code"
|
||||
default:
|
||||
return errors.Errorf("Failed to map column %s", fn)
|
||||
}
|
||||
columns = append(columns, cn)
|
||||
}
|
||||
|
||||
placeholders := []string{}
|
||||
for i := 0; i < len(columns); i++ {
|
||||
placeholders = append(placeholders, "?")
|
||||
}
|
||||
|
||||
q := "insert into countryinfo (" + strings.Join(columns, ",") + ") values(" + strings.Join(placeholders, ",") + ")"
|
||||
q = db.Rebind(q)
|
||||
stmt, err = db.Prepare(q)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to prepare sql query '%s'", q)
|
||||
}
|
||||
}
|
||||
|
||||
r := csv.NewReader(strings.NewReader(line))
|
||||
r.Comma = '\t' // Use tab-delimited instead of comma <---- here!
|
||||
r.FieldsPerRecord = -1
|
||||
|
||||
@ -348,117 +448,36 @@ func migrationList(db *sqlx.DB, log *log.Logger) []*sqlxmigrate.Migration {
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
var columns []string
|
||||
|
||||
for _, fn := range lines[0] {
|
||||
var cn string
|
||||
switch fn {
|
||||
case "ISO":
|
||||
cn = "iso_alpha2"
|
||||
case "ISO3":
|
||||
cn = "iso_alpha3"
|
||||
case "ISO-Numeric":
|
||||
cn = "iso_numeric"
|
||||
case "fips":
|
||||
cn = "fips_code"
|
||||
case "Country":
|
||||
cn = "country"
|
||||
case "Capital":
|
||||
cn = "capital"
|
||||
case "Area(in sq km)":
|
||||
cn = "areainsqkm"
|
||||
case "Population":
|
||||
cn = "population"
|
||||
case "Continent":
|
||||
cn = "continent"
|
||||
case "tld":
|
||||
cn = "tld"
|
||||
case "CurrencyCode":
|
||||
cn = "currency_code"
|
||||
case "CurrencyName":
|
||||
cn = "currency_name"
|
||||
case "Phone":
|
||||
cn = "phone"
|
||||
case "Postal Code Format":
|
||||
cn = "postal_format"
|
||||
case "Postal Code Regex":
|
||||
cn = "postal_regex"
|
||||
case "Languages":
|
||||
cn = "languages"
|
||||
case "geonameid":
|
||||
cn = "geonameId"
|
||||
case "neighbours":
|
||||
cn = "neighbours"
|
||||
case "EquivalentFipsCode":
|
||||
cn = "equivalent_fips_code"
|
||||
default:
|
||||
return errors.Errorf("Failed to map column %s", fn)
|
||||
for _, row := range lines {
|
||||
var args []interface{}
|
||||
for _, v := range row {
|
||||
args = append(args, v)
|
||||
}
|
||||
columns = append(columns, cn)
|
||||
}
|
||||
|
||||
placeholders := []string{}
|
||||
for i := 0; i < len(columns); i++ {
|
||||
placeholders = append(placeholders, "?")
|
||||
}
|
||||
|
||||
q := "insert into countryinfo (" + strings.Join(columns, ",") + ") values(" + strings.Join(placeholders, ",") + ")"
|
||||
q = db.Rebind(q)
|
||||
stmt, err = db.Prepare(q)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to prepare sql query '%s'", q)
|
||||
_, err = stmt.Exec(args...)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r := csv.NewReader(strings.NewReader(line))
|
||||
r.Comma = '\t' // Use tab-delimited instead of comma <---- here!
|
||||
r.FieldsPerRecord = -1
|
||||
|
||||
lines, err := r.ReadAll()
|
||||
if err != nil {
|
||||
if err := scanner.Err(); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
for _, row := range lines {
|
||||
var args []interface{}
|
||||
for _, v := range row {
|
||||
args = append(args, v)
|
||||
}
|
||||
|
||||
_, err = stmt.Exec(args...)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
queries := []string{
|
||||
// Countries...
|
||||
`DROP TABLE IF EXISTS countries`,
|
||||
`CREATE TABLE countries(
|
||||
code char(2) not null constraint countries_pkey primary key,
|
||||
iso_alpha3 char(3),
|
||||
name character varying(50),
|
||||
capital character varying(50),
|
||||
currency_code char(3),
|
||||
currency_name CHAR(20),
|
||||
phone character varying(20),
|
||||
postal_code_format character varying(200),
|
||||
postal_code_regex character varying(200))`,
|
||||
`insert into countries(code, iso_alpha3, name, capital, currency_code, currency_name, phone, postal_code_format, postal_code_regex)
|
||||
queries := []string{
|
||||
`insert into countries(code, iso_alpha3, name, capital, currency_code, currency_name, phone, postal_code_format, postal_code_regex)
|
||||
select iso_alpha2, iso_alpha3, country, capital, currency_code, currency_name, phone, postal_format, postal_regex
|
||||
from countryinfo`,
|
||||
`DROP TABLE IF EXISTS countryinfo`,
|
||||
}
|
||||
`DROP TABLE IF EXISTS countryinfo`,
|
||||
}
|
||||
|
||||
for _, q := range queries {
|
||||
_, err := db.Exec(q)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to execute sql query '%s'", q)
|
||||
for _, q := range queries {
|
||||
_, err := db.Exec(q)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to execute sql query '%s'", q)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -488,48 +507,52 @@ func migrationList(db *sqlx.DB, log *log.Logger) []*sqlxmigrate.Migration {
|
||||
}
|
||||
}
|
||||
|
||||
u := "http://download.geonames.org/export/dump/timeZones.txt"
|
||||
resp, err := pester.Get(u)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to read timezones info from '%s'", u)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if isUnittest {
|
||||
|
||||
q := "insert into country_timezones (country_code,timezone_id) values(?, ?)"
|
||||
q = db.Rebind(q)
|
||||
stmt, err := db.Prepare(q)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to prepare sql query '%s'", q)
|
||||
}
|
||||
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
// Skip comments.
|
||||
if strings.HasPrefix(line, "CountryCode") {
|
||||
continue
|
||||
}
|
||||
|
||||
r := csv.NewReader(strings.NewReader(line))
|
||||
r.Comma = '\t' // Use tab-delimited instead of comma <---- here!
|
||||
r.FieldsPerRecord = -1
|
||||
|
||||
lines, err := r.ReadAll()
|
||||
} else {
|
||||
u := "http://download.geonames.org/export/dump/timeZones.txt"
|
||||
resp, err := pester.Get(u)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
return errors.WithMessagef(err, "Failed to read timezones info from '%s'", u)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
q := "insert into country_timezones (country_code,timezone_id) values(?, ?)"
|
||||
q = db.Rebind(q)
|
||||
stmt, err := db.Prepare(q)
|
||||
if err != nil {
|
||||
return errors.WithMessagef(err, "Failed to prepare sql query '%s'", q)
|
||||
}
|
||||
|
||||
for _, row := range lines {
|
||||
_, err = stmt.Exec(row[0], row[1])
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
// Skip comments.
|
||||
if strings.HasPrefix(line, "CountryCode") {
|
||||
continue
|
||||
}
|
||||
|
||||
r := csv.NewReader(strings.NewReader(line))
|
||||
r.Comma = '\t' // Use tab-delimited instead of comma <---- here!
|
||||
r.FieldsPerRecord = -1
|
||||
|
||||
lines, err := r.ReadAll()
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return errors.WithStack(err)
|
||||
for _, row := range lines {
|
||||
_, err = stmt.Exec(row[0], row[1])
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -7,15 +7,15 @@ import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
func Migrate(masterDb *sqlx.DB, log *log.Logger) error {
|
||||
func Migrate(masterDb *sqlx.DB, log *log.Logger, isUnittest bool) error {
|
||||
// Load list of Schema migrations and init new sqlxmigrate client
|
||||
migrations := migrationList(masterDb, log)
|
||||
migrations := migrationList(masterDb, log, isUnittest)
|
||||
m := sqlxmigrate.New(masterDb, sqlxmigrate.DefaultOptions, migrations)
|
||||
m.SetLogger(log)
|
||||
|
||||
// Append any schema that need to be applied if this is a fresh migration
|
||||
// ie. the migrations database table does not exist.
|
||||
m.InitSchema(initSchema(masterDb, log))
|
||||
m.InitSchema(initSchema(masterDb, log, isUnittest))
|
||||
|
||||
// Execute the migrations
|
||||
return m.Migrate()
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
|
||||
"gopkg.in/go-playground/validator.v9"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -278,23 +277,17 @@ func Create(ctx context.Context, claims auth.Claims, dbConn *sqlx.DB, req UserCr
|
||||
span, ctx := tracer.StartSpanFromContext(ctx, "internal.user.Create")
|
||||
defer span.Finish()
|
||||
|
||||
v := webcontext.Validator()
|
||||
|
||||
// Validation email address is unique in the database.
|
||||
uniq, err := UniqueEmail(ctx, dbConn, req.Email, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f := func(fl validator.FieldLevel) bool {
|
||||
if fl.Field().String() == "invalid" {
|
||||
return false
|
||||
}
|
||||
return uniq
|
||||
}
|
||||
|
||||
v := webcontext.Validator()
|
||||
v.RegisterValidation("unique", f)
|
||||
ctx = context.WithValue(ctx, webcontext.KeyTagUnique, uniq)
|
||||
|
||||
// Validate the request.
|
||||
err = v.Struct(req)
|
||||
err = v.StructCtx(ctx, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -394,21 +387,18 @@ func Update(ctx context.Context, claims auth.Claims, dbConn *sqlx.DB, req UserUp
|
||||
|
||||
// Validation email address is unique in the database.
|
||||
if req.Email != nil {
|
||||
// Validation email address is unique in the database.
|
||||
uniq, err := UniqueEmail(ctx, dbConn, *req.Email, req.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f := func(fl validator.FieldLevel) bool {
|
||||
if fl.Field().String() == "invalid" {
|
||||
return false
|
||||
}
|
||||
return uniq
|
||||
}
|
||||
v.RegisterValidation("unique", f)
|
||||
ctx = context.WithValue(ctx, webcontext.KeyTagUnique, uniq)
|
||||
} else {
|
||||
ctx = context.WithValue(ctx, webcontext.KeyTagUnique, true)
|
||||
}
|
||||
|
||||
// Validate the request.
|
||||
err := v.Struct(req)
|
||||
err := v.StructCtx(ctx, req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -437,10 +427,10 @@ func Update(ctx context.Context, claims auth.Claims, dbConn *sqlx.DB, req UserUp
|
||||
|
||||
var fields []string
|
||||
if req.FirstName != nil {
|
||||
fields = append(fields, query.Assign("name", req.FirstName))
|
||||
fields = append(fields, query.Assign("first_name", req.FirstName))
|
||||
}
|
||||
if req.LastName != nil {
|
||||
fields = append(fields, query.Assign("name", req.LastName))
|
||||
fields = append(fields, query.Assign("last_name", req.LastName))
|
||||
}
|
||||
if req.Email != nil {
|
||||
fields = append(fields, query.Assign("email", req.Email))
|
||||
|
@ -152,7 +152,8 @@ func TestCreateValidation(t *testing.T) {
|
||||
errors.New("Key: 'UserCreateRequest.first_name' Error:Field validation for 'first_name' failed on the 'required' tag\n" +
|
||||
"Key: 'UserCreateRequest.last_name' Error:Field validation for 'last_name' failed on the 'required' tag\n" +
|
||||
"Key: 'UserCreateRequest.email' Error:Field validation for 'email' failed on the 'required' tag\n" +
|
||||
"Key: 'UserCreateRequest.password' Error:Field validation for 'password' failed on the 'required' tag"),
|
||||
"Key: 'UserCreateRequest.password' Error:Field validation for 'password' failed on the 'required' tag\n" +
|
||||
"Key: 'UserCreateRequest.password_confirm' Error:Field validation for 'password_confirm' failed on the 'required' tag"),
|
||||
},
|
||||
{"Valid Email",
|
||||
UserCreateRequest{
|
||||
@ -224,15 +225,16 @@ func TestCreateValidation(t *testing.T) {
|
||||
// of type interface validator.ValidationErrorsTranslations
|
||||
var errStr string
|
||||
if err != nil {
|
||||
errStr = err.Error()
|
||||
errStr = strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
}
|
||||
var expectStr string
|
||||
if tt.error != nil {
|
||||
expectStr = tt.error.Error()
|
||||
}
|
||||
if errStr != expectStr {
|
||||
t.Logf("\t\tGot : %+v", err)
|
||||
t.Logf("\t\tWant: %+v", tt.error)
|
||||
t.Logf("\t\tGot : %+v", errStr)
|
||||
t.Logf("\t\tWant: %+v", expectStr)
|
||||
t.Fatalf("\t%s\tCreate failed.", tests.Failed)
|
||||
}
|
||||
}
|
||||
@ -290,8 +292,11 @@ func TestCreateValidationEmailUnique(t *testing.T) {
|
||||
t.Fatalf("\t%s\tCreate failed.", tests.Failed)
|
||||
}
|
||||
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Logf("\t\tGot : %+v", err)
|
||||
errStr := strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
|
||||
if errStr != expectedErr.Error() {
|
||||
t.Logf("\t\tGot : %+v", errStr)
|
||||
t.Logf("\t\tWant: %+v", expectedErr)
|
||||
t.Fatalf("\t%s\tCreate failed.", tests.Failed)
|
||||
}
|
||||
@ -422,15 +427,16 @@ func TestUpdateValidation(t *testing.T) {
|
||||
// of type interface validator.ValidationErrorsTranslations
|
||||
var errStr string
|
||||
if err != nil {
|
||||
errStr = err.Error()
|
||||
errStr = strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
}
|
||||
var expectStr string
|
||||
if tt.error != nil {
|
||||
expectStr = tt.error.Error()
|
||||
}
|
||||
if errStr != expectStr {
|
||||
t.Logf("\t\tGot : %+v", err)
|
||||
t.Logf("\t\tWant: %+v", tt.error)
|
||||
t.Logf("\t\tGot : %+v", errStr)
|
||||
t.Logf("\t\tWant: %+v", expectStr)
|
||||
t.Fatalf("\t%s\tUpdate failed.", tests.Failed)
|
||||
}
|
||||
}
|
||||
@ -488,8 +494,11 @@ func TestUpdateValidationEmailUnique(t *testing.T) {
|
||||
t.Fatalf("\t%s\tUpdate failed.", tests.Failed)
|
||||
}
|
||||
|
||||
if err.Error() != expectedErr.Error() {
|
||||
t.Logf("\t\tGot : %+v", err)
|
||||
errStr := strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
|
||||
if errStr != expectedErr.Error() {
|
||||
t.Logf("\t\tGot : %+v", errStr)
|
||||
t.Logf("\t\tWant: %+v", expectedErr)
|
||||
t.Fatalf("\t%s\tUpdate failed.", tests.Failed)
|
||||
}
|
||||
@ -547,13 +556,19 @@ func TestUpdatePassword(t *testing.T) {
|
||||
|
||||
// Ensure validation is working by trying UpdatePassword with an empty request.
|
||||
expectedErr := errors.New("Key: 'UserUpdatePasswordRequest.id' Error:Field validation for 'id' failed on the 'required' tag\n" +
|
||||
"Key: 'UserUpdatePasswordRequest.password' Error:Field validation for 'password' failed on the 'required' tag")
|
||||
"Key: 'UserUpdatePasswordRequest.password' Error:Field validation for 'password' failed on the 'required' tag\n" +
|
||||
"Key: 'UserUpdatePasswordRequest.password_confirm' Error:Field validation for 'password_confirm' failed on the 'required' tag")
|
||||
err = UpdatePassword(ctx, auth.Claims{}, test.MasterDB, UserUpdatePasswordRequest{}, now)
|
||||
if err == nil {
|
||||
t.Logf("\t\tWant: %+v", expectedErr)
|
||||
t.Fatalf("\t%s\tUpdate failed.", tests.Failed)
|
||||
} else if err.Error() != expectedErr.Error() {
|
||||
t.Logf("\t\tGot : %+v", err)
|
||||
}
|
||||
|
||||
errStr := strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
|
||||
if errStr != expectedErr.Error() {
|
||||
t.Logf("\t\tGot : %+v", errStr)
|
||||
t.Logf("\t\tWant: %+v", expectedErr)
|
||||
t.Fatalf("\t%s\tValidation failed.", tests.Failed)
|
||||
}
|
||||
|
@ -232,15 +232,16 @@ func TestCreateValidation(t *testing.T) {
|
||||
// of type interface validator.ValidationErrorsTranslations
|
||||
var errStr string
|
||||
if err != nil {
|
||||
errStr = err.Error()
|
||||
errStr = strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
}
|
||||
var expectStr string
|
||||
if tt.error != nil {
|
||||
expectStr = tt.error.Error()
|
||||
}
|
||||
if errStr != expectStr {
|
||||
t.Logf("\t\tGot : %+v", err)
|
||||
t.Logf("\t\tWant: %+v", tt.error)
|
||||
t.Logf("\t\tGot : %+v", errStr)
|
||||
t.Logf("\t\tWant: %+v", expectStr)
|
||||
t.Fatalf("\t%s\tCreate user account failed.", tests.Failed)
|
||||
}
|
||||
}
|
||||
@ -411,15 +412,16 @@ func TestUpdateValidation(t *testing.T) {
|
||||
// of type interface validator.ValidationErrorsTranslations
|
||||
var errStr string
|
||||
if err != nil {
|
||||
errStr = err.Error()
|
||||
errStr = strings.Replace(err.Error(), "{{", "", -1)
|
||||
errStr = strings.Replace(errStr, "}}", "", -1)
|
||||
}
|
||||
var expectStr string
|
||||
if tt.error != nil {
|
||||
expectStr = tt.error.Error()
|
||||
}
|
||||
if errStr != expectStr {
|
||||
t.Logf("\t\tGot : %+v", err)
|
||||
t.Logf("\t\tWant: %+v", tt.error)
|
||||
t.Logf("\t\tGot : %+v", errStr)
|
||||
t.Logf("\t\tWant: %+v", expectStr)
|
||||
t.Fatalf("\t%s\tUpdate user account failed.", tests.Failed)
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ func main() {
|
||||
// Start Migrations
|
||||
|
||||
// Execute the migrations
|
||||
if err = schema.Migrate(masterDb, log); err != nil {
|
||||
if err = schema.Migrate(masterDb, log, false); err != nil {
|
||||
log.Fatalf("main : Migrate : %v", err)
|
||||
}
|
||||
log.Printf("main : Migrate : Completed")
|
||||
|
Loading…
x
Reference in New Issue
Block a user