package postservicelogic import ( "app-cloudep-tweeting-service/gen_result/pb/tweeting" mocklib "app-cloudep-tweeting-service/internal/mock/lib" mockmodel "app-cloudep-tweeting-service/internal/mock/model" model "app-cloudep-tweeting-service/internal/model/mongo" "app-cloudep-tweeting-service/internal/svc" "context" "errors" "testing" "time" "google.golang.org/protobuf/proto" "github.com/stretchr/testify/assert" "go.mongodb.org/mongo-driver/bson/primitive" "go.uber.org/mock/gomock" ) func TestConvertToPostDetailItem(t *testing.T) { // 構建測試數據 postID := primitive.NewObjectID() post := &model.Post{ ID: postID, UID: "12345", Content: "Test Content", Tags: []string{"tag1", "tag2"}, MediaURL: []model.Media{ {Type: "image", Links: "http://example.com/image.png"}, {Type: "video", Links: "http://example.com/video.mp4"}, }, IsAd: true, CreateAt: time.Now().Unix(), UpdateAt: time.Now().Unix(), Like: 10, DisLike: 2, } // 執行轉換 result := convertToPostDetailItem(post) // 驗證結果 assert.Equal(t, postID.Hex(), result.PostId) assert.Equal(t, "12345", result.Uid) assert.Equal(t, "Test Content", result.Content) assert.Equal(t, []string{"tag1", "tag2"}, result.Tags) assert.Equal(t, true, result.IsAd) assert.Equal(t, int64(10), result.LikeCount) assert.Equal(t, int64(2), result.DislikeCount) // 驗證 Media 的轉換 assert.Len(t, result.Media, 2) assert.Equal(t, "image", result.Media[0].Type) assert.Equal(t, "http://example.com/image.png", result.Media[0].Url) assert.Equal(t, "video", result.Media[1].Type) assert.Equal(t, "http://example.com/video.mp4", result.Media[1].Url) } func TestListPosts(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() // 初始化 mock 依賴 mockPostModel := mockmodel.NewMockPostModel(ctrl) mockValidate := mocklib.NewMockValidate(ctrl) // 初始化服務上下文 svcCtx := &svc.ServiceContext{ PostModel: mockPostModel, Validate: mockValidate, } // 構建測試數據 queryReq := &tweeting.QueryPostsReq{ PageSize: 10, PageIndex: 1, OnlyAds: proto.Int32(1), } mockPosts := []*model.Post{ { ID: primitive.NewObjectID(), UID: "12345", Content: "Test Content 1", Tags: []string{"tag1", "tag2"}, MediaURL: []model.Media{ {Type: "image", Links: "http://example.com/image1.png"}, }, IsAd: false, CreateAt: time.Now().Unix(), UpdateAt: time.Now().Unix(), Like: 5, DisLike: 1, }, { ID: primitive.NewObjectID(), UID: "67890", Content: "Test Content 2", Tags: []string{"tag3", "tag4"}, MediaURL: []model.Media{ {Type: "video", Links: "http://example.com/video1.mp4"}, }, IsAd: true, CreateAt: time.Now().Unix(), UpdateAt: time.Now().Unix(), Like: 3, DisLike: 0, }, } // 測試數據集 tests := []struct { name string input *tweeting.QueryPostsReq prepare func() expectErr bool }{ { name: "成功查詢貼文", input: queryReq, prepare: func() { mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) mockPostModel.EXPECT().Find(gomock.Any(), gomock.Any()).Return(mockPosts, int64(len(mockPosts)), nil).Times(1) }, expectErr: false, }, { name: "查詢貼文失敗", input: queryReq, prepare: func() { mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) mockPostModel.EXPECT().Find(gomock.Any(), gomock.Any()).Return(nil, int64(0), errors.New("find failed")).Times(1) }, expectErr: true, }, } // 執行測試 for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // 設置測試環境 tt.prepare() // 初始化 ListPostsLogic logic := ListPostsLogic{ svcCtx: svcCtx, ctx: context.TODO(), } // 執行 ListPosts resp, err := logic.ListPosts(tt.input) // 驗證結果 if tt.expectErr { assert.Error(t, err) } else { assert.NoError(t, err) assert.NotNil(t, resp) assert.Len(t, resp.Posts, len(mockPosts)) } }) } }