From 02d91db85a1009bc2e25e34fe971bfd4cb5d9648 Mon Sep 17 00:00:00 2001 From: setiadijoe Date: Wed, 23 Jun 2021 10:20:22 +0700 Subject: [PATCH 1/6] #57 add full path on images and decode images object --- .env.example | 1 + config/model.go | 11 +++++----- endpoint/endpoint.go | 8 +++---- mocks/testcases/get-detail-user-post.go | 5 ++++- mocks/testcases/get-list-user-post.go | 4 ++-- model/usecase_response.go | 28 ++++++++++++------------- transport/grpc/transport.go | 7 +++++-- usecase/parser.go | 13 +++++++++++- 8 files changed, 48 insertions(+), 29 deletions(-) diff --git a/.env.example b/.env.example index 936c7f6..a6dbb08 100644 --- a/.env.example +++ b/.env.example @@ -2,6 +2,7 @@ APP_ENV=local APP_GRPC_PORT=3000 APP_HTTP_PORT=3001 APP_DEBUG=true +APP_STORAGE_PUBLIC_URL= DB_HOST=localhost DB_PORT=3306 diff --git a/config/model.go b/config/model.go index 4966b79..68018e2 100644 --- a/config/model.go +++ b/config/model.go @@ -10,9 +10,10 @@ type DB struct { } type Config struct { - AppGRPCPort int `env:"APP_GRPC_PORT,required"` - AppHTTPPort int `env:"APP_HTTP_PORT,required"` - AppEnv string `env:"APP_ENV,required"` - Debug bool `env:"APP_DEBUG,required"` - DB *DB + AppGRPCPort int `env:"APP_GRPC_PORT,required"` + AppHTTPPort int `env:"APP_HTTP_PORT,required"` + AppEnv string `env:"APP_ENV,required"` + Debug bool `env:"APP_DEBUG,required"` + AppStoragePublicURL string `env:"APP_STORAGE_PUBLIC_URL,required"` + DB *DB } diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index 4b6890b..8e64c42 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -16,10 +16,10 @@ import ( func MakeGetListUserPost(ctx context.Context, usecase usecase.UsecaseI) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (response interface{}, err error) { req := request.(*GetListUserPostRequest) - cASC := strings.Compare(helper.GetStringFromPointer(req.SortBy), "ASC") - cDESC := strings.Compare(helper.GetStringFromPointer(req.SortBy), "DESC") - if req.SortBy != nil && (cASC*cDESC == 1) { - return nil, errors.New("must_between_ASC_DESC") + cASC := strings.Compare(helper.GetStringFromPointer(req.OrderBy), "ASC") + cDESC := strings.Compare(helper.GetStringFromPointer(req.OrderBy), "DESC") + if req.OrderBy != nil && (cASC*cDESC == 1) { + return nil, errors.New("order_must_between_ASC_DESC") } // TODO: for get metadata from headers grpc needs to update when using authorization resp, err := usecase.GetListPost(ctx, &model.GetListRequest{ diff --git a/mocks/testcases/get-detail-user-post.go b/mocks/testcases/get-detail-user-post.go index 122dcdc..833bf4a 100644 --- a/mocks/testcases/get-detail-user-post.go +++ b/mocks/testcases/get-detail-user-post.go @@ -19,12 +19,15 @@ type ResponseGetDetailUsecase struct { } var ( + images = []map[string]interface{}{ + {"path": "general"}, + } userpostResponse = &model.UserPostResponse{ ID: 1, Title: "title", Tag: helper.SetPointerString("tag"), ImagePath: "test", - Images: "test", + Images: images, LastUserPostCommentID: helper.SetPointerInt64(1), LastComment: comment, LikesCount: 0, diff --git a/mocks/testcases/get-list-user-post.go b/mocks/testcases/get-list-user-post.go index cec9434..2d6dab6 100644 --- a/mocks/testcases/get-list-user-post.go +++ b/mocks/testcases/get-list-user-post.go @@ -164,7 +164,7 @@ var ( Title: "title", Tag: helper.SetPointerString("tag"), ImagePath: "test", - Images: "test", + Images: images, LastUserPostCommentID: helper.SetPointerInt64(1), LastComment: comment, LikesCount: 0, @@ -179,7 +179,7 @@ var ( Title: "test title", Tag: helper.SetPointerString("tag"), ImagePath: "test", - Images: "test", + Images: images, LastUserPostCommentID: helper.SetPointerInt64(1), LastComment: comment, LikesCount: 0, diff --git a/model/usecase_response.go b/model/usecase_response.go index b3d1333..4ced441 100644 --- a/model/usecase_response.go +++ b/model/usecase_response.go @@ -5,20 +5,20 @@ import ( ) type UserPostResponse struct { - ID int64 `json:"id"` - Title string `json:"title"` - Tag *string `json:"tags,omitempty"` - ImagePath string `json:"image_path,omitempty"` - Images string `json:"images"` - LastUserPostCommentID *int64 `json:"last_user_post_comment_id,omitempty"` - LastComment *Comment `json:"last_comment,omitempty"` - LikesCount int64 `json:"likes_count"` - IsLiked bool `json:"is_liked"` - CommentCounts int64 `json:"comment_counts"` - Status int64 `json:"status"` - Actor *Actor `json:"actor"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID int64 `json:"id"` + Title string `json:"title"` + Tag *string `json:"tags,omitempty"` + ImagePath string `json:"image_path,omitempty"` + Images []map[string]interface{} `json:"images"` + LastUserPostCommentID *int64 `json:"last_user_post_comment_id,omitempty"` + LastComment *Comment `json:"last_comment,omitempty"` + LikesCount int64 `json:"likes_count"` + IsLiked bool `json:"is_liked"` + CommentCounts int64 `json:"comment_counts"` + Status int64 `json:"status"` + Actor *Actor `json:"actor"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type UserPostWithMetadata struct { diff --git a/transport/grpc/transport.go b/transport/grpc/transport.go index b3a27ac..2887ebd 100644 --- a/transport/grpc/transport.go +++ b/transport/grpc/transport.go @@ -2,6 +2,7 @@ package grpc import ( "context" + "encoding/json" "github.com/sapawarga/userpost-service/endpoint" "github.com/sapawarga/userpost-service/helper" @@ -96,12 +97,13 @@ func encodeGetListUserPost(ctx context.Context, r interface{}) (interface{}, err resultData := make([]*transportUserPost.UserPost, 0) for _, v := range data { + images, _ := json.Marshal(v.Images) result := &transportUserPost.UserPost{ Id: v.ID, Title: v.Title, Tag: helper.GetStringFromPointer(v.Tag), ImagePath: v.ImagePath, - Images: v.Images, + Images: string(images), LastUserPostCommentId: helper.GetInt64FromPointer(v.LastUserPostCommentID), LikesCount: v.LikesCount, CommentCounts: v.CommentCounts, @@ -175,12 +177,13 @@ func encodedUserPostDetail(ctx context.Context, r interface{}) (interface{}, err actorUserPost := encodeActor(ctx, resp.Actor) + images, _ := json.Marshal(resp.Images) userDetail := &transportUserPost.UserPost{ Id: resp.ID, Title: resp.Title, Tag: helper.GetStringFromPointer(resp.Tag), ImagePath: resp.ImagePath, - Images: resp.Images, + Images: string(images), LastUserPostCommentId: helper.GetInt64FromPointer(resp.LastUserPostCommentID), LastComment: lastComment, LikesCount: resp.LikesCount, diff --git a/usecase/parser.go b/usecase/parser.go index 9722306..df4fc13 100644 --- a/usecase/parser.go +++ b/usecase/parser.go @@ -2,21 +2,32 @@ package usecase import ( "context" + "encoding/json" + "fmt" kitlog "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" + "github.com/sapawarga/userpost-service/config" "github.com/sapawarga/userpost-service/helper" "github.com/sapawarga/userpost-service/model" ) func (p *Post) getDetailOfUserPost(ctx context.Context, post *model.PostResponse) (*model.UserPostResponse, error) { logger := kitlog.With(p.logger, "method", "getDetailOfUserPost") + cfg, _ := config.NewConfig() + images := make([]map[string]interface{}, 0) + if err := json.Unmarshal([]byte(post.Images.String), &images); err != nil { + images = nil + } + for _, v := range images { + v["path"] = fmt.Sprintf("%s/%s", cfg.AppStoragePublicURL, v) + } userPost := &model.UserPostResponse{ ID: post.ID, Title: post.Title, Tag: helper.SetPointerString(post.Tag.String), ImagePath: post.ImagePath.String, - Images: post.Images.String, + Images: images, LikesCount: post.LikesCount, CommentCounts: post.CommentCounts, Status: post.Status, From 2a40720480d63a57898e9b487d24fe4ead418098 Mon Sep 17 00:00:00 2001 From: setiadijoe Date: Wed, 23 Jun 2021 11:29:36 +0700 Subject: [PATCH 2/6] #57 add role label for detail actor --- config/config.go | 2 ++ model/usecase_response.go | 34 +++++++++++++++++++++++++--------- repository/mysql/userpost.go | 2 +- usecase/parser.go | 23 ++++++++++++----------- 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/config/config.go b/config/config.go index 00cff4a..fd8968e 100644 --- a/config/config.go +++ b/config/config.go @@ -17,6 +17,7 @@ func NewConfig() (defConfig *Config, err error) { appGRPCPort, _ := strconv.Atoi(os.Getenv(`APP_GRPC_PORT`)) appHTTPPort, _ := strconv.Atoi(os.Getenv(`APP_HTTP_PORT`)) debugString := os.Getenv(`APP_DEBUG`) + appStoragePublicURL := os.Getenv(`APP_STORAGE_PUBLIC_URL`) debug := false if debugString == "true" { @@ -39,6 +40,7 @@ func NewConfig() (defConfig *Config, err error) { defConfig.AppGRPCPort = appGRPCPort defConfig.AppHTTPPort = appHTTPPort defConfig.Debug = debug + defConfig.AppStoragePublicURL = appStoragePublicURL if dbHost == "" || dbPort == 0 || dbUser == "" || dbName == "" || driverName == "" { err = fmt.Errorf("[CONFIG][Critical] Please check section DB on %s", envFileName) diff --git a/model/usecase_response.go b/model/usecase_response.go index 4ced441..e35f6da 100644 --- a/model/usecase_response.go +++ b/model/usecase_response.go @@ -43,13 +43,29 @@ type Comment struct { } type Actor struct { - ID int64 `json:"id"` - Name string `json:"name"` - PhotoURL string `json:"photo_url,omitempty"` - Role int64 `json:"role,omitempty"` - Regency string `json:"regency,omitempty"` - District string `json:"district,omitempty"` - Village string `json:"village,omitempty"` - RW string `json:"rw,omitempty"` - Status int64 `json:"status,omitempty"` + ID int64 `json:"id"` + Name string `json:"name"` + PhotoURL string `json:"photo_url,omitempty"` + Role int64 `json:"role,omitempty"` + RoleLabel string `json:"role_label,omitempty"` + Regency string `json:"regency,omitempty"` + District string `json:"district,omitempty"` + Village string `json:"village,omitempty"` + RW string `json:"rw,omitempty"` + Status int64 `json:"status,omitempty"` +} + +var RoleLabel = map[int64]string{ + 10: "user", + 49: "trainer", + 50: "staffRW", + 60: "staffKel", + 70: "staffKec", + 80: "staffKabKota", + 88: "staffOPD", + 89: "staffSaberhoax", + 90: "staffProv", + 91: "pimpinan", + 99: "admin", + 100: "service_account", } diff --git a/repository/mysql/userpost.go b/repository/mysql/userpost.go index dcbce26..785efca 100644 --- a/repository/mysql/userpost.go +++ b/repository/mysql/userpost.go @@ -33,7 +33,7 @@ func (r *UserPost) GetListPost(ctx context.Context, request *model.UserPostReque params = append(params, request.Offset, request.Limit) } if request.OrderBy != nil && request.SortBy != nil { - query.WriteString(fmt.Sprintf(" ORDER BY %s %s", *request.OrderBy, *request.SortBy)) + query.WriteString(fmt.Sprintf(" ORDER BY %s %s", *request.SortBy, *request.OrderBy)) } if ctx != nil { err = r.conn.SelectContext(ctx, &result, query.String(), params...) diff --git a/usecase/parser.go b/usecase/parser.go index df4fc13..e34dc84 100644 --- a/usecase/parser.go +++ b/usecase/parser.go @@ -20,13 +20,13 @@ func (p *Post) getDetailOfUserPost(ctx context.Context, post *model.PostResponse images = nil } for _, v := range images { - v["path"] = fmt.Sprintf("%s/%s", cfg.AppStoragePublicURL, v) + v["path"] = fmt.Sprintf("%s/%s", cfg.AppStoragePublicURL, v["path"]) } userPost := &model.UserPostResponse{ ID: post.ID, Title: post.Title, Tag: helper.SetPointerString(post.Tag.String), - ImagePath: post.ImagePath.String, + ImagePath: fmt.Sprintf("%s/%s", cfg.AppStoragePublicURL, post.ImagePath.String), Images: images, LikesCount: post.LikesCount, CommentCounts: post.CommentCounts, @@ -62,15 +62,16 @@ func (p *Post) getDetailOfUserPost(ctx context.Context, post *model.PostResponse func (p *Post) parsingUserResponse(ctx context.Context, user *model.UserResponse) *model.Actor { return &model.Actor{ - ID: user.ID, - Name: user.Name.String, - PhotoURL: user.PhotoURL.String, - Role: user.Role.Int64, - Regency: user.Regency.String, - District: user.District.String, - Village: user.Village.String, - RW: user.RW.String, - Status: user.Status, + ID: user.ID, + Name: user.Name.String, + PhotoURL: user.PhotoURL.String, + Role: user.Role.Int64, + RoleLabel: model.RoleLabel[user.Role.Int64], + Regency: user.Regency.String, + District: user.District.String, + Village: user.Village.String, + RW: user.RW.String, + Status: user.Status, } } From 30b0c09e86f669fa6b29a10ac4acfe0eb540a21c Mon Sep 17 00:00:00 2001 From: setiadijoe Date: Wed, 23 Jun 2021 11:41:38 +0700 Subject: [PATCH 3/6] #57 update testcase response --- mocks/testcases/get-list-user-post.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/mocks/testcases/get-list-user-post.go b/mocks/testcases/get-list-user-post.go index 2d6dab6..19f8e15 100644 --- a/mocks/testcases/get-list-user-post.go +++ b/mocks/testcases/get-list-user-post.go @@ -128,15 +128,16 @@ var ( Status: 10, } actor = &model.Actor{ - ID: 1, - Name: "John Doe", - PhotoURL: "www.instagram.com/htm-medium=?p9878y2y3", - Role: 99, - Regency: "regency", - District: "district", - Village: "village", - RW: "rw", - Status: 10, + ID: 1, + Name: "John Doe", + PhotoURL: "www.instagram.com/htm-medium=?p9878y2y3", + Role: 99, + RoleLabel: model.RoleLabel[int64(99)], + Regency: "regency", + District: "district", + Village: "village", + RW: "rw", + Status: 10, } metadataResponse = helper.SetPointerInt64(2) commentResponse = &model.CommentResponse{ From 0fa64651236d0953d7198029e7f2a1f0e499cb49 Mon Sep 17 00:00:00 2001 From: setiadijoe Date: Wed, 23 Jun 2021 12:11:30 +0700 Subject: [PATCH 4/6] #57 create checker of orderby --- endpoint/endpoint.go | 6 ++---- endpoint/request.go | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index 8e64c42..4218b52 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -3,7 +3,6 @@ package endpoint import ( "context" "encoding/json" - "strings" "errors" @@ -16,9 +15,8 @@ import ( func MakeGetListUserPost(ctx context.Context, usecase usecase.UsecaseI) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (response interface{}, err error) { req := request.(*GetListUserPostRequest) - cASC := strings.Compare(helper.GetStringFromPointer(req.OrderBy), "ASC") - cDESC := strings.Compare(helper.GetStringFromPointer(req.OrderBy), "DESC") - if req.OrderBy != nil && (cASC*cDESC == 1) { + orderBy := helper.GetStringFromPointer(req.OrderBy) + if req.OrderBy != nil && isOrder(orderBy) == -1 { return nil, errors.New("order_must_between_ASC_DESC") } // TODO: for get metadata from headers grpc needs to update when using authorization diff --git a/endpoint/request.go b/endpoint/request.go index 92aa23f..2e3ff74 100644 --- a/endpoint/request.go +++ b/endpoint/request.go @@ -69,3 +69,18 @@ func validationImages(in []*Image) validation.RuleFunc { return err } } + +var ordering = map[int]string{ + 0: "ASC", + 1: "DESC", +} + +func isOrder(val string) int { + for i := range ordering { + if ordering[i] == val { + return i + } + } + + return -1 +} From 3aa2b2d19374dc7e6d4b8b4c5caaf7c52634d0ff Mon Sep 17 00:00:00 2001 From: setiadijoe Date: Wed, 23 Jun 2021 13:04:48 +0700 Subject: [PATCH 5/6] #57 using boolean and rename function --- endpoint/endpoint.go | 2 +- endpoint/request.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/endpoint/endpoint.go b/endpoint/endpoint.go index 4218b52..436c2d6 100644 --- a/endpoint/endpoint.go +++ b/endpoint/endpoint.go @@ -16,7 +16,7 @@ func MakeGetListUserPost(ctx context.Context, usecase usecase.UsecaseI) endpoint return func(ctx context.Context, request interface{}) (response interface{}, err error) { req := request.(*GetListUserPostRequest) orderBy := helper.GetStringFromPointer(req.OrderBy) - if req.OrderBy != nil && isOrder(orderBy) == -1 { + if req.OrderBy != nil && !isOrderValid(orderBy) { return nil, errors.New("order_must_between_ASC_DESC") } // TODO: for get metadata from headers grpc needs to update when using authorization diff --git a/endpoint/request.go b/endpoint/request.go index 2e3ff74..0e711e8 100644 --- a/endpoint/request.go +++ b/endpoint/request.go @@ -75,12 +75,12 @@ var ordering = map[int]string{ 1: "DESC", } -func isOrder(val string) int { +func isOrderValid(val string) bool { for i := range ordering { if ordering[i] == val { - return i + return true } } - return -1 + return false } From c8e64389a7802c6a5d6389bdeb3097395a59f76b Mon Sep 17 00:00:00 2001 From: setiadijoe Date: Wed, 23 Jun 2021 13:32:02 +0700 Subject: [PATCH 6/6] #57 update function isOrderValid --- endpoint/request.go | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/endpoint/request.go b/endpoint/request.go index 0e711e8..6174845 100644 --- a/endpoint/request.go +++ b/endpoint/request.go @@ -1,6 +1,8 @@ package endpoint import ( + "strings" + "github.com/go-ozzo/ozzo-validation/is" validation "github.com/go-ozzo/ozzo-validation/v4" "github.com/sapawarga/userpost-service/helper" @@ -70,17 +72,6 @@ func validationImages(in []*Image) validation.RuleFunc { } } -var ordering = map[int]string{ - 0: "ASC", - 1: "DESC", -} - func isOrderValid(val string) bool { - for i := range ordering { - if ordering[i] == val { - return true - } - } - - return false + return strings.EqualFold(val, "ASC") || strings.EqualFold(val, "DESC") }