diff --git a/errcode/errcode.go b/errcode/errcode.go index a3968d9..43003b0 100644 --- a/errcode/errcode.go +++ b/errcode/errcode.go @@ -24,6 +24,8 @@ const ( PostUserInfosNotExist uint32 = 50005 PageNotExist uint32 = 60000 + + CommentNotExist uint32 = 70000 ) var msg = map[uint32]string{ @@ -45,6 +47,8 @@ var msg = map[uint32]string{ PostUserInfosNotExist: "post user info not exist", PageNotExist: "page not exist", + + CommentNotExist: "comment not exist", } func Wrap(e uint32) error { diff --git a/service/comment/rpc/internal/logic/get_logic.go b/service/comment/rpc/internal/logic/get_logic.go index 27317cf..621dfec 100644 --- a/service/comment/rpc/internal/logic/get_logic.go +++ b/service/comment/rpc/internal/logic/get_logic.go @@ -2,11 +2,15 @@ package logic import ( "context" + "errors" + "github.com/linehk/go-microservices-blogger/convert" + "github.com/linehk/go-microservices-blogger/errcode" "github.com/linehk/go-microservices-blogger/service/comment/rpc/comment" "github.com/linehk/go-microservices-blogger/service/comment/rpc/internal/svc" - + "github.com/linehk/go-microservices-blogger/service/comment/rpc/model" "github.com/zeromicro/go-zero/core/logx" + "google.golang.org/protobuf/types/known/timestamppb" ) type GetLogic struct { @@ -24,7 +28,57 @@ func NewGetLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetLogic { } func (l *GetLogic) Get(in *comment.GetReq) (*comment.Comment, error) { - // todo: add your logic here and delete this line + commentModel, err := l.svcCtx.CommentModel.FindOneByUuid(l.ctx, in.GetCommentId()) + if errors.Is(err, model.ErrNotFound) { + l.Error(errcode.Msg(errcode.CommentNotExist)) + return nil, errcode.Wrap(errcode.CommentNotExist) + } + if err != nil { + l.Error(errcode.Msg(errcode.Database)) + return nil, errcode.Wrap(errcode.Database) + } + return Get(l.ctx, l.svcCtx, l.Logger, commentModel) +} + +func Get(ctx context.Context, svcCtx *svc.ServiceContext, l logx.Logger, commentModel *model.Comment) (*comment.Comment, error) { + var commentResp comment.Comment + convert.Copy(&commentResp, commentModel) + commentResp.Kind = "blogger#comment" + commentResp.Id = commentModel.Uuid + commentResp.Post = &comment.Post{Id: commentModel.PostUuid.String} + commentResp.Blog = &comment.Blog{Id: commentModel.BlogUuid.String} + if commentModel.Published.Valid { + commentResp.Published = timestamppb.New(commentModel.Published.Time) + } + if commentModel.Updated.Valid { + commentResp.Updated = timestamppb.New(commentModel.Updated.Time) + } + + authorModel, err := svcCtx.AuthorModel.FindOneByCommentUuid(ctx, commentModel.Uuid) + if errors.Is(err, model.ErrNotFound) { + l.Error(errcode.Msg(errcode.AuthorNotExist)) + return nil, errcode.Wrap(errcode.AuthorNotExist) + } + if err != nil { + l.Error(errcode.Msg(errcode.Database)) + return nil, errcode.Wrap(errcode.Database) + } + + commentResp.Author = &comment.Author{} + convert.Copy(commentResp.Author, authorModel) + commentResp.Author.Id = authorModel.Uuid + authorImageModel, err := svcCtx.ImageModel.FindOneByAuthorUuid(ctx, authorModel.Uuid) + if errors.Is(err, model.ErrNotFound) { + l.Error(errcode.Msg(errcode.ImageNotExist)) + return nil, errcode.Wrap(errcode.ImageNotExist) + } + if err != nil { + l.Error(errcode.Msg(errcode.Database)) + return nil, errcode.Wrap(errcode.Database) + } + if authorImageModel.Url.Valid { + commentResp.Author.Image = &comment.Image{Url: authorImageModel.Url.String} + } - return &comment.Comment{}, nil + return &commentResp, nil } diff --git a/service/comment/rpc/internal/svc/service_context.go b/service/comment/rpc/internal/svc/service_context.go index ad1fffc..47e3b21 100644 --- a/service/comment/rpc/internal/svc/service_context.go +++ b/service/comment/rpc/internal/svc/service_context.go @@ -3,6 +3,7 @@ package svc import ( "github.com/linehk/go-microservices-blogger/service/comment/rpc/internal/config" "github.com/linehk/go-microservices-blogger/service/comment/rpc/model" + postmodel "github.com/linehk/go-microservices-blogger/service/post/rpc/model" "github.com/zeromicro/go-zero/core/stores/postgres" "github.com/zeromicro/go-zero/core/stores/redis" ) @@ -11,6 +12,8 @@ type ServiceContext struct { Config config.Config RedisClient *redis.Redis CommentModel model.CommentModel + AuthorModel postmodel.AuthorModel + ImageModel postmodel.ImageModel } func NewServiceContext(c config.Config) *ServiceContext { @@ -22,5 +25,7 @@ func NewServiceContext(c config.Config) *ServiceContext { Type: redis.NodeType, }), CommentModel: model.NewCommentModel(conn, c.Cache), + AuthorModel: postmodel.NewAuthorModel(conn, c.Cache), + ImageModel: postmodel.NewImageModel(conn, c.Cache), } } diff --git a/service/comment/rpc/internal/test/get_logic_test.go b/service/comment/rpc/internal/test/get_logic_test.go new file mode 100644 index 0000000..c228c01 --- /dev/null +++ b/service/comment/rpc/internal/test/get_logic_test.go @@ -0,0 +1,157 @@ +package test + +import ( + "context" + "database/sql" + "testing" + "time" + + "github.com/google/uuid" + "github.com/linehk/go-microservices-blogger/errcode" + "github.com/linehk/go-microservices-blogger/service/comment/rpc/comment" + "github.com/linehk/go-microservices-blogger/service/comment/rpc/internal/logic" + "github.com/linehk/go-microservices-blogger/service/comment/rpc/internal/svc" + "github.com/linehk/go-microservices-blogger/service/comment/rpc/model" + postmodel "github.com/linehk/go-microservices-blogger/service/post/rpc/model" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func TestGet(t *testing.T) { + ctrl := gomock.NewController(t) + ctx := context.Background() + commentRepo := model.NewMockCommentModel(ctrl) + authorRepo := postmodel.NewMockAuthorModel(ctrl) + imageRepo := postmodel.NewMockImageModel(ctrl) + logicService := logic.NewGetLogic(ctx, &svc.ServiceContext{ + CommentModel: commentRepo, + AuthorModel: authorRepo, + ImageModel: imageRepo, + }) + defer ctrl.Finish() + + blogUuid := uuid.NewString() + postUuid := uuid.NewString() + commentUuid := uuid.NewString() + getReq := &comment.GetReq{ + BlogId: blogUuid, + CommentId: commentUuid, + PostId: postUuid, + } + + status := "Status" + published := time.Now() + updated := time.Now() + selfLink := "SelfLink" + content := "Content" + commentModel := &model.Comment{ + Id: 1, + Uuid: commentUuid, + BlogUuid: sql.NullString{String: blogUuid, Valid: true}, + PostUuid: sql.NullString{String: postUuid, Valid: true}, + Status: sql.NullString{String: status, Valid: true}, + Published: sql.NullTime{Time: published, Valid: true}, + Updated: sql.NullTime{Time: updated, Valid: true}, + SelfLink: sql.NullString{String: selfLink, Valid: true}, + Content: sql.NullString{String: content, Valid: true}, + } + + authorUuid := uuid.NewString() + displayName := "DisplayName" + authorUrl := "Url" + authorModel := &postmodel.Author{ + Id: 1, + Uuid: authorUuid, + PostUuid: "", + PageUuid: "", + CommentUuid: commentUuid, + DisplayName: sql.NullString{String: displayName, Valid: true}, + Url: sql.NullString{String: authorUrl, Valid: true}, + } + + imageUuid := uuid.NewString() + imageUrl := "imageUrl" + imageModel := &postmodel.Image{ + Id: 1, + Uuid: imageUuid, + PostUuid: sql.NullString{String: "", Valid: true}, + AuthorUuid: authorUuid, + Url: sql.NullString{String: imageUrl, Valid: true}, + } + + expected := &comment.Comment{ + Kind: "blogger#comment", + Status: status, + Id: commentUuid, + InReplyTo: nil, + Post: &comment.Post{Id: postUuid}, + Blog: &comment.Blog{Id: blogUuid}, + Published: timestamppb.New(published), + Updated: timestamppb.New(updated), + SelfLink: selfLink, + Content: content, + Author: &comment.Author{ + Id: authorUuid, + DisplayName: displayName, + Url: authorUrl, + Image: &comment.Image{Url: imageUrl}, + }, + } + + // CommentNotExist + expectedErr := errcode.Wrap(errcode.CommentNotExist) + commentRepo.EXPECT().FindOneByUuid(ctx, commentUuid).Return(nil, model.ErrNotFound) + actual, actualErr := logicService.Get(getReq) + assert.Nil(t, actual) + assert.Equal(t, expectedErr, actualErr) + + // Database + expectedErr = errcode.Wrap(errcode.Database) + commentRepo.EXPECT().FindOneByUuid(ctx, commentUuid).Return(nil, expectedErr) + actual, actualErr = logicService.Get(getReq) + assert.Nil(t, actual) + assert.Equal(t, expectedErr, actualErr) + + // AuthorNotExist + expectedErr = errcode.Wrap(errcode.AuthorNotExist) + commentRepo.EXPECT().FindOneByUuid(ctx, commentUuid).Return(commentModel, nil) + authorRepo.EXPECT().FindOneByCommentUuid(ctx, commentUuid).Return(nil, model.ErrNotFound) + actual, actualErr = logicService.Get(getReq) + assert.Nil(t, actual) + assert.Equal(t, expectedErr, actualErr) + + // Database + expectedErr = errcode.Wrap(errcode.Database) + commentRepo.EXPECT().FindOneByUuid(ctx, commentUuid).Return(commentModel, nil) + authorRepo.EXPECT().FindOneByCommentUuid(ctx, commentUuid).Return(nil, expectedErr) + actual, actualErr = logicService.Get(getReq) + assert.Nil(t, actual) + assert.Equal(t, expectedErr, actualErr) + + // ImageNotExist + expectedErr = errcode.Wrap(errcode.ImageNotExist) + commentRepo.EXPECT().FindOneByUuid(ctx, commentUuid).Return(commentModel, nil) + authorRepo.EXPECT().FindOneByCommentUuid(ctx, commentUuid).Return(authorModel, nil) + imageRepo.EXPECT().FindOneByAuthorUuid(ctx, authorUuid).Return(nil, model.ErrNotFound) + actual, actualErr = logicService.Get(getReq) + assert.Nil(t, actual) + assert.Equal(t, expectedErr, actualErr) + + // Database + expectedErr = errcode.Wrap(errcode.Database) + commentRepo.EXPECT().FindOneByUuid(ctx, commentUuid).Return(commentModel, nil) + authorRepo.EXPECT().FindOneByCommentUuid(ctx, commentUuid).Return(authorModel, nil) + imageRepo.EXPECT().FindOneByAuthorUuid(ctx, authorUuid).Return(nil, expectedErr) + actual, actualErr = logicService.Get(getReq) + assert.Nil(t, actual) + assert.Equal(t, expectedErr, actualErr) + + // Success + commentRepo.EXPECT().FindOneByUuid(ctx, commentUuid).Return(commentModel, nil) + authorRepo.EXPECT().FindOneByCommentUuid(ctx, commentUuid).Return(authorModel, nil) + imageRepo.EXPECT().FindOneByAuthorUuid(ctx, authorUuid).Return(imageModel, nil) + actual, actualErr = logicService.Get(getReq) + assert.Equal(t, expected, actual) + assert.Nil(t, actualErr) +}