Skip to content

Commit

Permalink
feat(blog): add ListByUser
Browse files Browse the repository at this point in the history
  • Loading branch information
linehk committed Mar 3, 2024
1 parent 717a34e commit 6103f51
Show file tree
Hide file tree
Showing 4 changed files with 285 additions and 3 deletions.
63 changes: 61 additions & 2 deletions service/blog/rpc/internal/logic/list_by_user_logic.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@ package logic

import (
"context"
"errors"
"strconv"

"github.com/linehk/go-microservices-blogger/convert"
"github.com/linehk/go-microservices-blogger/errcode"
"github.com/linehk/go-microservices-blogger/service/blog/rpc/blog"
"github.com/linehk/go-microservices-blogger/service/blog/rpc/internal/svc"
"github.com/linehk/go-microservices-blogger/service/blog/rpc/model"
"github.com/linehk/go-microservices-blogger/service/page/rpc/page"
"github.com/linehk/go-microservices-blogger/service/post/rpc/post"
"google.golang.org/protobuf/types/known/timestamppb"

"github.com/zeromicro/go-zero/core/logx"
)
Expand All @@ -24,7 +32,58 @@ func NewListByUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListBy
}

func (l *ListByUserLogic) ListByUser(in *blog.ListByUserReq) (*blog.ListByUserResp, error) {
// todo: add your logic here and delete this line
blogModelList, err := l.svcCtx.BlogModel.ListByAppUserUuid(l.ctx, in.GetUserId())
if errors.Is(err, model.ErrNotFound) {
l.Error(errcode.Msg(errcode.BlogNotExist))
return nil, errcode.Wrap(errcode.BlogNotExist)
}
if err != nil {
l.Error(errcode.Msg(errcode.Database))
return nil, errcode.Wrap(errcode.Database)
}

var listByUserResp blog.ListByUserResp
listByUserResp.Kind = "blogger#blogList"

for _, blogModel := range blogModelList {
var blogResp blog.Blog
convert.Copy(&blogResp, blogModel)
blogResp.Kind = "blogger#blog"
blogResp.Id = blogModel.Uuid
if blogModel.Published.Valid {
blogResp.Published = timestamppb.New(blogModel.Published.Time)
}
if blogModel.Updated.Valid {
blogResp.Updated = timestamppb.New(blogModel.Updated.Time)
}

listPostReq := &post.ListReq{
BlogId: blogModel.Uuid,
}
listPostResp, err := l.svcCtx.PostService.List(l.ctx, listPostReq)
if err != nil {
l.Error(errcode.Msg(errcode.Service))
return nil, errcode.Wrap(errcode.Service)
}
postTotalItems := strconv.Itoa(len(listPostResp.GetItems()))
for _, postItem := range listPostResp.GetItems() {
blogResp.Posts = append(blogResp.Posts, &blog.Posts{TotalItems: postTotalItems, SelfLink: postItem.GetSelfLink()})
}

listPageReq := &page.ListReq{
BlogId: blogModel.Uuid,
}
listPageResp, err := l.svcCtx.PageService.List(l.ctx, listPageReq)
if err != nil {
l.Error(errcode.Msg(errcode.Service))
return nil, errcode.Wrap(errcode.Service)
}
pageTotalItems := strconv.Itoa(len(listPageResp.GetItems()))
for _, pageItem := range listPageResp.GetItems() {
blogResp.Pages = append(blogResp.Pages, &blog.Pages{TotalItems: pageTotalItems, SelfLink: pageItem.GetSelfLink()})
}
listByUserResp.Items = append(listByUserResp.Items, &blogResp)
}

return &blog.ListByUserResp{}, nil
return &listByUserResp, nil
}
186 changes: 186 additions & 0 deletions service/blog/rpc/internal/test/list_by_user_logic_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
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/blog/rpc/blog"
"github.com/linehk/go-microservices-blogger/service/blog/rpc/internal/logic"
"github.com/linehk/go-microservices-blogger/service/blog/rpc/internal/svc"
"github.com/linehk/go-microservices-blogger/service/blog/rpc/model"
"github.com/linehk/go-microservices-blogger/service/page/rpc/page"
"github.com/linehk/go-microservices-blogger/service/page/rpc/pageservice"
"github.com/linehk/go-microservices-blogger/service/post/rpc/post"
"github.com/linehk/go-microservices-blogger/service/post/rpc/postservice"
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
"google.golang.org/protobuf/types/known/timestamppb"
)

func TestListByUser(t *testing.T) {
ctrl := gomock.NewController(t)
ctx := context.Background()
blogRepo := model.NewMockBlogModel(ctrl)
postService := postservice.NewMockPostService(ctrl)
pageService := pageservice.NewMockPageService(ctrl)
logicService := logic.NewListByUserLogic(ctx, &svc.ServiceContext{
BlogModel: blogRepo,
PostService: postService,
PageService: pageService,
})
defer ctrl.Finish()

userId := uuid.NewString()
blogId1 := uuid.NewString()
blogId2 := uuid.NewString()
listByUserReq := &blog.ListByUserReq{UserId: userId}

name := "Name"
description := "Description"
published := time.Now()
updated := time.Now()
url := "Url"
selfLink := "SelfLink"
customMetaData := "CustomMetaData"
blogModelList := []*model.Blog{
{
Id: 1,
Uuid: blogId1,
AppUserUuid: userId,
Name: sql.NullString{String: name, Valid: true},
Description: sql.NullString{String: description, Valid: true},
Published: sql.NullTime{Time: published, Valid: true},
Updated: sql.NullTime{Time: updated, Valid: true},
Url: sql.NullString{String: url, Valid: true},
SelfLink: sql.NullString{String: selfLink, Valid: true},
CustomMetaData: sql.NullString{String: customMetaData, Valid: true},
},
{
Id: 2,
Uuid: blogId2,
AppUserUuid: userId,
Name: sql.NullString{String: name, Valid: true},
Description: sql.NullString{String: description, Valid: true},
Published: sql.NullTime{Time: published, Valid: true},
Updated: sql.NullTime{Time: updated, Valid: true},
Url: sql.NullString{String: url, Valid: true},
SelfLink: sql.NullString{String: selfLink, Valid: true},
CustomMetaData: sql.NullString{String: customMetaData, Valid: true},
},
}

listPostReq1 := &post.ListReq{
BlogId: blogId1,
}
listPostReq2 := &post.ListReq{
BlogId: blogId2,
}

postSelfLink1 := "postSelfLink1"
postSelfLink2 := "postSelfLink2"
listPostResp := &post.ListResp{
Kind: "blogger#post",
Items: []*post.Post{{
SelfLink: postSelfLink1,
}, {
SelfLink: postSelfLink2,
}},
}

pageSelfLink1 := "pageSelfLink1"
pageSelfLink2 := "pageSelfLink2"
listPageReq1 := &page.ListReq{
BlogId: blogId1,
}
listPageReq2 := &page.ListReq{
BlogId: blogId2,
}
listPageResp := &page.ListResp{
Kind: "blogger#page",
Items: []*page.Page{{
SelfLink: pageSelfLink1,
}, {
SelfLink: pageSelfLink2,
}},
}

postTotalItems := "2"
pageTotalItems := "2"
expected := &blog.ListByUserResp{
Kind: "blogger#blogList",
Items: []*blog.Blog{
{
Kind: "blogger#blog",
Id: blogId1,
Name: name,
Description: description,
Published: timestamppb.New(published),
Updated: timestamppb.New(updated),
Url: url,
SelfLink: selfLink,
Posts: []*blog.Posts{{TotalItems: postTotalItems, SelfLink: postSelfLink1}, {TotalItems: postTotalItems, SelfLink: postSelfLink2}},
Pages: []*blog.Pages{{TotalItems: pageTotalItems, SelfLink: pageSelfLink1}, {TotalItems: pageTotalItems, SelfLink: pageSelfLink2}},
CustomMetaData: customMetaData,
}, {
Kind: "blogger#blog",
Id: blogId2,
Name: name,
Description: description,
Published: timestamppb.New(published),
Updated: timestamppb.New(updated),
Url: url,
SelfLink: selfLink,
Posts: []*blog.Posts{{TotalItems: postTotalItems, SelfLink: postSelfLink1}, {TotalItems: postTotalItems, SelfLink: postSelfLink2}},
Pages: []*blog.Pages{{TotalItems: pageTotalItems, SelfLink: pageSelfLink1}, {TotalItems: pageTotalItems, SelfLink: pageSelfLink2}},
CustomMetaData: customMetaData,
},
},
}

// BlogNotExist
expectedErr := errcode.Wrap(errcode.BlogNotExist)
blogRepo.EXPECT().ListByAppUserUuid(ctx, userId).Return(nil, model.ErrNotFound)
actual, actualErr := logicService.ListByUser(listByUserReq)
assert.Nil(t, actual)
assert.Equal(t, expectedErr, actualErr)

// Database
expectedErr = errcode.Wrap(errcode.Database)
blogRepo.EXPECT().ListByAppUserUuid(ctx, userId).Return(nil, expectedErr)
actual, actualErr = logicService.ListByUser(listByUserReq)
assert.Nil(t, actual)
assert.Equal(t, expectedErr, actualErr)

// Post Service
expectedErr = errcode.Wrap(errcode.Service)
blogRepo.EXPECT().ListByAppUserUuid(ctx, userId).Return(blogModelList, nil)
postService.EXPECT().List(ctx, listPostReq1).Return(nil, expectedErr)

actual, actualErr = logicService.ListByUser(listByUserReq)
assert.Nil(t, actual)
assert.Equal(t, expectedErr, actualErr)

// Page Service
expectedErr = errcode.Wrap(errcode.Service)
blogRepo.EXPECT().ListByAppUserUuid(ctx, userId).Return(blogModelList, nil)
postService.EXPECT().List(ctx, listPostReq1).Return(listPostResp, nil)

pageService.EXPECT().List(ctx, listPageReq1).Return(nil, expectedErr)
actual, actualErr = logicService.ListByUser(listByUserReq)
assert.Nil(t, actual)
assert.Equal(t, expectedErr, actualErr)

// Success
blogRepo.EXPECT().ListByAppUserUuid(ctx, userId).Return(blogModelList, nil)
postService.EXPECT().List(ctx, listPostReq1).Return(listPostResp, nil)
postService.EXPECT().List(ctx, listPostReq2).Return(listPostResp, nil)
pageService.EXPECT().List(ctx, listPageReq1).Return(listPageResp, nil)
pageService.EXPECT().List(ctx, listPageReq2).Return(listPageResp, nil)
actual, actualErr = logicService.ListByUser(listByUserReq)
assert.Equal(t, actual, expected)
assert.Nil(t, actualErr)
}
24 changes: 23 additions & 1 deletion service/blog/rpc/model/blog_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type (
BlogModel interface {
blogModel
FindOneByUrl(ctx context.Context, url string) (*Blog, error)
ListByAppUserUuid(ctx context.Context, appUserUuid string) ([]*Blog, error)
}

customBlogModel struct {
Expand All @@ -33,7 +34,8 @@ func NewBlogModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) Bl
}

var (
cachePublicBlogUrlPrefix = "cache:public:blog:url:"
cachePublicBlogUrlPrefix = "cache:public:blog:url:"
cachePublicBlogListAppUserUuidPrefix = "cache:public:blog:list:appUserUuid:"
)

func (c *customBlogModel) FindOneByUrl(ctx context.Context, url string) (*Blog, error) {
Expand All @@ -55,3 +57,23 @@ func (c *customBlogModel) FindOneByUrl(ctx context.Context, url string) (*Blog,
return nil, err
}
}

func (m *defaultBlogModel) ListByAppUserUuid(ctx context.Context, appUserUuid string) ([]*Blog, error) {
publicBlogListAppUserUuidKey := fmt.Sprintf("%s%v", cachePublicBlogListAppUserUuidPrefix, appUserUuid)
var resp []*Blog
err := m.QueryRowIndexCtx(ctx, &resp, publicBlogListAppUserUuidKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v any) (i any, e error) {
query := fmt.Sprintf("select %s from %s where app_user_uuid = $1", blogRows, m.table)
if err := conn.QueryRowCtx(ctx, &resp, query, appUserUuid); err != nil {
return nil, err
}
return resp[0].Id, nil
}, m.queryPrimary)
switch err {
case nil:
return resp, nil
case sqlc.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
15 changes: 15 additions & 0 deletions service/blog/rpc/model/mock_blog_model.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6103f51

Please sign in to comment.