Skip to content

Commit

Permalink
Merge pull request #14 from DoWithLogic/fix/fix-endpoint-and-unit-test
Browse files Browse the repository at this point in the history
fix: fix endpoint and unit test
  • Loading branch information
martinyonatann authored Oct 17, 2023
2 parents 0a3a63b + 616b28b commit 4282e86
Show file tree
Hide file tree
Showing 15 changed files with 227 additions and 72 deletions.
3 changes: 2 additions & 1 deletion config/config-local.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ database:

authentication:
key: DoWithLogic!@#
secret_key: s3cr#tK3y!@#
secret_key: s3cr#tK3y!@#v001
salt_key: s4ltK3y!@#ddv001
46 changes: 12 additions & 34 deletions internal/users/delivery/http/v1/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ package v1

import (
"context"
"errors"
"net/http"
"strconv"
"time"

"github.com/DoWithLogic/golang-clean-architecture/internal/users/dtos"
"github.com/DoWithLogic/golang-clean-architecture/internal/users/entities"
usecases "github.com/DoWithLogic/golang-clean-architecture/internal/users/usecase"
"github.com/DoWithLogic/golang-clean-architecture/pkg/middleware"
"github.com/DoWithLogic/golang-clean-architecture/pkg/otel/zerolog"
Expand Down Expand Up @@ -36,10 +33,6 @@ const (
BooleanTextFalse = "false"
)

var (
ErrInvalidIsActive = errors.New("invalid is_active")
)

func NewHandlers(uc usecases.Usecase, log *zerolog.Logger) Handlers {
return &handlers{uc, log}
}
Expand Down Expand Up @@ -121,18 +114,20 @@ func (h *handlers) UserDetail(c echo.Context) error {
func (h *handlers) UpdateUser(c echo.Context) error {
var (
ctx, cancel = context.WithTimeout(c.Request().Context(), time.Duration(30*time.Second))
identity = c.Get("identity").(*middleware.CustomClaims)
request dtos.UpdateUserRequest
)
defer cancel()

request.UserID = c.Get("identity").(entities.Identity).UserID

if err := c.Bind(&request); err != nil {
h.log.Z().Err(err).Msg("[handlers]UpdateUser.Bind")

return c.JSON(http.StatusBadRequest, response.NewResponseError(http.StatusBadRequest, response.MsgFailed, err.Error()))
}

request.UserID = identity.UserID
request.UpdateBy = identity.Email

if err := request.Validate(); err != nil {
h.log.Z().Err(err).Msg("[handlers]UpdateUser.Validate")

Expand All @@ -149,38 +144,21 @@ func (h *handlers) UpdateUser(c echo.Context) error {
func (h *handlers) UpdateUserStatus(c echo.Context) error {
var (
ctx, cancel = context.WithTimeout(c.Request().Context(), time.Duration(30*time.Second))
payload dtos.UpdateUserStatusPayload
identity = c.Get("identity").(*middleware.CustomClaims)
request = dtos.UpdateUserStatusRequest{UserID: identity.UserID, UpdateBy: identity.Email}
)
defer cancel()

userID, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
h.log.Z().Err(err).Msg("[handlers]UpdateUser.ParseParam")

return c.JSON(http.StatusBadRequest, response.NewResponseError(
http.StatusBadRequest,
response.MsgFailed,
err.Error()),
)
}

switch c.QueryParam("is_active") {
case BooleanTextFalse:
payload.IsActive = false
case BooleanTextTrue:
payload.IsActive = true
default:
return c.JSON(http.StatusBadRequest, response.NewResponseError(http.StatusBadRequest, response.MsgFailed, ErrInvalidIsActive.Error()))
if err := c.Bind(&request); err != nil {
return c.JSON(http.StatusBadRequest, response.NewResponseError(http.StatusBadRequest, response.MsgFailed, err.Error()))
}

argsUpdateUserStatus := entities.UpdateUserStatus{
UserID: userID,
IsActive: payload.IsActive,
if err := request.Validate(); err != nil {
return c.JSON(http.StatusBadRequest, response.NewResponseError(http.StatusBadRequest, response.MsgFailed, err.Error()))
}

err = h.uc.UpdateStatus(ctx, argsUpdateUserStatus)
if err != nil {
return c.JSON(http.StatusBadRequest, response.NewResponseError(http.StatusInternalServerError, response.MsgFailed, err.Error()))
if err := h.uc.UpdateStatus(ctx, request); err != nil {
return c.JSON(http.StatusInternalServerError, response.NewResponseError(http.StatusInternalServerError, response.MsgFailed, err.Error()))
}

return c.JSON(http.StatusOK, response.NewResponse(http.StatusOK, response.MsgSuccess, nil))
Expand Down
4 changes: 2 additions & 2 deletions internal/users/delivery/http/v1/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ func UserPrivateRoute(version *echo.Group, h Handlers, cfg config.Config) {
users.POST("", h.CreateUser)
users.POST("/login", h.Login)
users.GET("/detail", h.UserDetail, middleware.AuthorizeJWT(cfg))
users.PATCH("/:id", h.UpdateUser, middleware.AuthorizeJWT(cfg))
users.PUT("/:id", h.UpdateUserStatus, middleware.AuthorizeJWT(cfg))
users.PATCH("/update", h.UpdateUser, middleware.AuthorizeJWT(cfg))
users.PUT("/update/status", h.UpdateUserStatus, middleware.AuthorizeJWT(cfg))
}
7 changes: 6 additions & 1 deletion internal/users/dtos/user_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dtos
import (
"github.com/DoWithLogic/golang-clean-architecture/pkg/apperror"
"github.com/DoWithLogic/golang-clean-architecture/pkg/constant"
"github.com/invopop/validation"
)

type UpdateUserRequest struct {
Expand All @@ -12,6 +13,7 @@ type UpdateUserRequest struct {
UserType string `json:"user_type"`
Email string `json:"email"`
Password string `json:"password"`
UpdateBy string `json:"-"`
}

var ()
Expand All @@ -21,5 +23,8 @@ func (cup UpdateUserRequest) Validate() error {
return apperror.ErrInvalidUserType
}

return nil
return validation.ValidateStruct(&cup,
validation.Field(&cup.UserID, validation.NotNil),
validation.Field(&cup.UpdateBy, validation.NotNil),
)
}
17 changes: 14 additions & 3 deletions internal/users/dtos/user_update_status.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
package dtos

type UpdateUserStatusPayload struct {
UserID int64
IsActive bool
import "github.com/invopop/validation"

type UpdateUserStatusRequest struct {
UserID int64 `json:"-"`
Status int `json:"status"`
UpdateBy string `json:"-"`
}

func (ussp UpdateUserStatusRequest) Validate() error {
return validation.ValidateStruct(&ussp,
validation.Field(&ussp.UserID, validation.NotNil),
validation.Field(&ussp.UpdateBy, validation.NotNil),
validation.Field(&ussp.Status, validation.Required),
)
}
4 changes: 2 additions & 2 deletions internal/users/entities/user_update.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (

type UpdateUsers struct {
UserID int64
Fullname string
Email string
Fullname string
Password string
PhoneNumber string
UserType string
Expand All @@ -24,6 +24,6 @@ func NewUpdateUsers(data dtos.UpdateUserRequest) UpdateUsers {
PhoneNumber: data.PhoneNumber,
UserType: data.UserType,
UpdatedAt: time.Now(),
UpdatedBy: "martin",
UpdatedBy: data.UpdateBy,
}
}
15 changes: 10 additions & 5 deletions internal/users/entities/user_update_status.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package entities

import "time"
import (
"time"

"github.com/DoWithLogic/golang-clean-architecture/internal/users/dtos"
"github.com/DoWithLogic/golang-clean-architecture/pkg/constant"
)

type UpdateUserStatus struct {
UserID int64
Expand All @@ -9,11 +14,11 @@ type UpdateUserStatus struct {
UpdatedBy string
}

func NewUpdateUserStatus(payload UpdateUserStatus) UpdateUserStatus {
func NewUpdateUserStatus(req dtos.UpdateUserStatusRequest) UpdateUserStatus {
return UpdateUserStatus{
UserID: payload.UserID,
IsActive: payload.IsActive,
UserID: req.UserID,
IsActive: constant.MapStatus[req.Status],
UpdatedAt: time.Now(),
UpdatedBy: "martin",
UpdatedBy: req.UpdateBy,
}
}
2 changes: 1 addition & 1 deletion internal/users/entities/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ func NewCreateUser(data dtos.CreateUserRequest, cfg config.Config) Users {
UserType: constant.UserTypeRegular,
IsActive: true,
CreatedAt: time.Now(),
CreatedBy: constant.UserSystem,
CreatedBy: "SYSTEM",
}
}
1 change: 1 addition & 0 deletions internal/users/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ func (repo *repository) SaveNewUser(ctx context.Context, user entities.Users) (u

func (repo *repository) UpdateUserByID(ctx context.Context, user entities.UpdateUsers) error {
args := utils.Array{
user.Email, user.Email,
user.Fullname, user.Fullname,
user.PhoneNumber, user.PhoneNumber,
user.UserType, user.UserType,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
UPDATE users SET
email = CASE WHEN ? != '' THEN ? ELSE email END,
fullname = CASE WHEN ? != '' THEN ? ELSE fullname END,
phone_number = CASE WHEN ? != '' THEN ? ELSE phone_number END,
user_type = CASE WHEN ? != '' THEN ? ELSE user_type END,
Expand Down
12 changes: 4 additions & 8 deletions internal/users/usecase/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type (
Login(ctx context.Context, request dtos.UserLoginRequest) (response dtos.UserLoginResponse, httpCode int, err error)
Create(ctx context.Context, payload dtos.CreateUserRequest) (userID int64, httpCode int, err error)
PartialUpdate(ctx context.Context, data dtos.UpdateUserRequest) error
UpdateStatus(ctx context.Context, req entities.UpdateUserStatus) error
UpdateStatus(ctx context.Context, req dtos.UpdateUserStatusRequest) error
Detail(ctx context.Context, id int64) (detail dtos.UserDetailResponse, httpCode int, err error)
}

Expand All @@ -44,19 +44,15 @@ func (uc *usecase) Login(ctx context.Context, request dtos.UserLoginRequest) (re
return response, http.StatusInternalServerError, err
}

uc.log.Z().Err(nil).Str("decrypted_password", dataLogin.Password).Str("password", request.Password).Msg("[Login]")

if !strings.EqualFold(utils.Decrypt(dataLogin.Password, uc.cfg), request.Password) {
return response, http.StatusUnauthorized, apperror.ErrInvalidPassword
}

expiredAt := time.Now().Add(time.Minute * 15).Unix()

identityData := middleware.CustomClaims{
UserID: dataLogin.UserID,
Email: dataLogin.Email,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expiredAt,
ExpiresAt: time.Now().Add(time.Minute * 15).Unix(),
},
}

Expand All @@ -67,7 +63,7 @@ func (uc *usecase) Login(ctx context.Context, request dtos.UserLoginRequest) (re

response = dtos.UserLoginResponse{
AccessToken: token,
ExpiredAt: expiredAt,
ExpiredAt: utils.UnixToDuration(identityData.ExpiresAt),
}

return response, http.StatusOK, nil
Expand Down Expand Up @@ -111,7 +107,7 @@ func (uc *usecase) PartialUpdate(ctx context.Context, data dtos.UpdateUserReques
})
}

func (uc *usecase) UpdateStatus(ctx context.Context, req entities.UpdateUserStatus) error {
func (uc *usecase) UpdateStatus(ctx context.Context, req dtos.UpdateUserStatusRequest) error {
_, err := uc.repo.GetUserByID(ctx, req.UserID, entities.LockingOpt{})
if err != nil {
uc.log.Z().Err(err).Msg("[usecase]UpdateUserStatus.GetUserByID")
Expand Down
Loading

0 comments on commit 4282e86

Please sign in to comment.