From 184586cdffe146335d19208373250d2a5c4a2a96 Mon Sep 17 00:00:00 2001 From: "daniel.w" Date: Tue, 3 Sep 2024 19:20:10 +0800 Subject: [PATCH] add social network test --- Makefile | 2 + go.mod | 33 +++ internal/config/config.go | 2 +- internal/lib/neo4j/neo4j_test.go | 209 ++++++++++++++++++ .../get_followee_count_logic_test.go | 88 ++++++++ .../get_followee_logic_test.go | 130 +++++++++++ .../get_follower_count_logic_test.go | 108 +++++++++ .../get_follower_logic_test.go | 130 +++++++++++ .../mark_follow_relation_logic_test.go | 108 +++++++++ .../remove_follow_relation_logic_test.go | 108 +++++++++ internal/mock/repository/social_network.go | 174 +++++++++++++++ internal/mock/repository/timeline.go | 113 ++++++++++ internal/repository/social_network_test.go | 1 + 13 files changed, 1205 insertions(+), 1 deletion(-) create mode 100644 internal/lib/neo4j/neo4j_test.go create mode 100644 internal/logic/socialnetworkservice/get_followee_count_logic_test.go create mode 100644 internal/logic/socialnetworkservice/get_followee_logic_test.go create mode 100644 internal/logic/socialnetworkservice/get_follower_count_logic_test.go create mode 100644 internal/logic/socialnetworkservice/get_follower_logic_test.go create mode 100644 internal/logic/socialnetworkservice/mark_follow_relation_logic_test.go create mode 100644 internal/logic/socialnetworkservice/remove_follow_relation_logic_test.go create mode 100644 internal/mock/repository/social_network.go create mode 100644 internal/mock/repository/timeline.go create mode 100644 internal/repository/social_network_test.go diff --git a/Makefile b/Makefile index 186d9a1..d8e2c07 100644 --- a/Makefile +++ b/Makefile @@ -63,6 +63,8 @@ mock-gen: # 建立 mock 資料 mockgen -source=./internal/model/mongo/post_model.go -destination=./internal/mock/model/post_model.go -package=mock mockgen -source=./internal/model/mongo/comment_model_gen.go -destination=./internal/mock/model/comment_model_gen.go -package=mock mockgen -source=./internal/model/mongo/comment_model.go -destination=./internal/mock/model/comment_model.go -package=mock + mockgen -source=./internal/domain/repository/social_network.go -destination=./internal/mock/repository/social_network.go -package=mock + mockgen -source=./internal/domain/repository/timeline.go -destination=./internal/mock/repository/timeline.go -package=mock @echo "Generate mock files successfully" .PHONY: migrate-database diff --git a/go.mod b/go.mod index f1c33fb..f1f1499 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/alicebob/miniredis/v2 v2.33.0 github.com/neo4j/neo4j-go-driver/v5 v5.24.0 github.com/stretchr/testify v1.9.0 + github.com/testcontainers/testcontainers-go v0.33.0 github.com/zeromicro/go-zero v1.7.0 go.mongodb.org/mongo-driver v1.16.0 go.uber.org/mock v0.4.0 @@ -16,19 +17,32 @@ require ( ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/containerd/containerd v1.7.18 // indirect + github.com/containerd/log v0.1.0 // indirect + github.com/containerd/platforms v0.2.1 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/docker v27.1.1+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/fatih/color v1.17.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.4 // indirect @@ -48,30 +62,49 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.8 // indirect github.com/leodido/go-urn v1.4.0 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/sys/user v0.1.0 // indirect + github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/montanaflynn/stats v0.7.1 // indirect + github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/redis/go-redis/v9 v9.6.1 // indirect + github.com/shirou/gopsutil/v3 v3.23.12 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect github.com/yuin/gopher-lua v1.1.1 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect go.etcd.io/etcd/api/v3 v3.5.15 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect go.etcd.io/etcd/client/v3 v3.5.15 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect go.opentelemetry.io/otel v1.24.0 // indirect go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect diff --git a/internal/config/config.go b/internal/config/config.go index 30a88a1..a028a59 100755 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -27,7 +27,7 @@ type Config struct { // Redis Cluster RedisCluster redis.RedisConf - // 圖形話資料庫 + // 圖形資料庫 Neo4J struct { URI string Username string diff --git a/internal/lib/neo4j/neo4j_test.go b/internal/lib/neo4j/neo4j_test.go new file mode 100644 index 0000000..5618f69 --- /dev/null +++ b/internal/lib/neo4j/neo4j_test.go @@ -0,0 +1,209 @@ +package neo4j + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/wait" +) + +func TestNewNeo4J(t *testing.T) { + tests := []struct { + name string + conf *Config + expected *Config + }{ + { + name: "valid configuration", + conf: &Config{ + URI: "neo4j://localhost:7687", + Username: "neo4j", + Password: "password", + LogLevel: "info", + MaxConnectionLifetime: time.Minute * 5, + MaxConnectionPoolSize: 10, + ConnectionTimeout: time.Second * 5, + }, + expected: &Config{ + URI: "neo4j://localhost:7687", + Username: "neo4j", + Password: "password", + LogLevel: "info", + }, + }, + { + name: "empty URI", + conf: &Config{ + URI: "", + Username: "neo4j", + Password: "password", + LogLevel: "info", + MaxConnectionLifetime: time.Minute * 5, + MaxConnectionPoolSize: 10, + ConnectionTimeout: time.Second * 5, + }, + expected: &Config{ + URI: "", + Username: "neo4j", + Password: "password", + LogLevel: "info", + }, + }, + { + name: "empty username and password", + conf: &Config{ + URI: "neo4j://localhost:7687", + Username: "", + Password: "", + LogLevel: "info", + MaxConnectionLifetime: time.Minute * 5, + MaxConnectionPoolSize: 10, + ConnectionTimeout: time.Second * 5, + }, + expected: &Config{ + URI: "neo4j://localhost:7687", + Username: "", + Password: "", + LogLevel: "info", + }, + }, + { + name: "custom log level", + conf: &Config{ + URI: "neo4j://localhost:7687", + Username: "neo4j", + Password: "password", + LogLevel: "debug", + MaxConnectionLifetime: time.Minute * 5, + MaxConnectionPoolSize: 10, + ConnectionTimeout: time.Second * 5, + }, + expected: &Config{ + URI: "neo4j://localhost:7687", + Username: "neo4j", + Password: "password", + LogLevel: "debug", + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := NewNeo4J(tt.conf) + assert.NotNil(t, client) + assert.Equal(t, tt.expected.URI, client.serviceConf.URI) + assert.Equal(t, tt.expected.Username, client.serviceConf.Username) + assert.Equal(t, tt.expected.Password, client.serviceConf.Password) + assert.Equal(t, tt.expected.LogLevel, client.serviceConf.LogLevel) + }) + } +} + +func TestConn(t *testing.T) { + ctx := context.Background() + + neo4jContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ContainerRequest: testcontainers.ContainerRequest{ + Image: "neo4j:latest", + ExposedPorts: []string{"7687/tcp"}, + Env: map[string]string{ + "NEO4J_AUTH": "neo4j/yyyytttt", + }, + WaitingFor: wait.ForLog("Started"), + }, + Started: true, + }) + if err != nil { + t.Fatal(err) + } + defer neo4jContainer.Terminate(ctx) + + host, _ := neo4jContainer.Host(ctx) + port, _ := neo4jContainer.MappedPort(ctx, "7687") + + uri := fmt.Sprintf("bolt://%s:%s", host, port.Port()) + t.Log("Neo4j running at:", uri) + + tests := []struct { + name string + conf *Config + shouldFail bool + }{ + { + name: "successful connection", + conf: &Config{ + URI: uri, + Username: "neo4j", + Password: "yyyytttt", + LogLevel: "info", + MaxConnectionLifetime: time.Minute * 5, + MaxConnectionPoolSize: 10, + ConnectionTimeout: time.Second * 5, + }, + shouldFail: false, + }, + { + name: "failed connection due to invalid URI", + conf: &Config{ + URI: uri, + Username: "neo4j", + Password: "wrongpassword", + LogLevel: "info", + MaxConnectionLifetime: time.Minute * 5, + MaxConnectionPoolSize: 10, + ConnectionTimeout: time.Second * 5, + }, + shouldFail: true, + }, + { + name: "failed connection due to missing URI", + conf: &Config{ + URI: "", + Username: "neo4j", + Password: "password", + LogLevel: "info", + MaxConnectionLifetime: time.Minute * 5, + MaxConnectionPoolSize: 10, + ConnectionTimeout: time.Second * 5, + }, + shouldFail: true, + }, + { + name: "failed connection due to missing username and password", + conf: &Config{ + URI: uri, + Username: "", + Password: "", + LogLevel: "info", + MaxConnectionLifetime: time.Minute * 5, + MaxConnectionPoolSize: 10, + ConnectionTimeout: time.Second * 5, + }, + shouldFail: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := NewNeo4J(tt.conf) + driver, err := client.Conn() + if tt.shouldFail { + assert.Error(t, err) + assert.Nil(t, driver) + } else { + assert.NoError(t, err) + assert.NotNil(t, driver) + + // Close the driver after test + defer func() { + err := driver.Close(context.Background()) + assert.NoError(t, err) + }() + } + }) + } +} diff --git a/internal/logic/socialnetworkservice/get_followee_count_logic_test.go b/internal/logic/socialnetworkservice/get_followee_count_logic_test.go new file mode 100644 index 0000000..93d9991 --- /dev/null +++ b/internal/logic/socialnetworkservice/get_followee_count_logic_test.go @@ -0,0 +1,88 @@ +package socialnetworkservicelogic + +import ( + "app-cloudep-tweeting-service/gen_result/pb/tweeting" + mocklib "app-cloudep-tweeting-service/internal/mock/lib" + mockRepo "app-cloudep-tweeting-service/internal/mock/repository" + "app-cloudep-tweeting-service/internal/svc" + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +func TestGetFolloweeCountLogic_GetFolloweeCount(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + mockSocialNetworkRepository := mockRepo.NewMockSocialNetworkRepository(ctrl) + mockValidate := mocklib.NewMockValidate(ctrl) + + svcCtx := &svc.ServiceContext{ + SocialNetworkRepository: mockSocialNetworkRepository, + Validate: mockValidate, + } + + // 测试数据集 + tests := []struct { + name string + input *tweeting.FollowCountReq + prepare func() + expectErr bool + }{ + { + name: "ok", + input: &tweeting.FollowCountReq{ + Uid: "12345", + }, + prepare: func() { + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + mockSocialNetworkRepository.EXPECT().GetFolloweeCount(gomock.Any(), "12345").Return(int64(10), nil).Times(1) + }, + expectErr: false, + }, + { + name: "驗證失敗", + input: &tweeting.FollowCountReq{ + Uid: "", + }, + prepare: func() { + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(errors.New("validation failed")).Times(1) + }, + expectErr: true, + }, + { + name: "取得跟隨數量失敗", + input: &tweeting.FollowCountReq{ + Uid: "12345", + }, + prepare: func() { + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + mockSocialNetworkRepository.EXPECT().GetFolloweeCount(gomock.Any(), "12345").Return(int64(0), errors.New("repository error")).Times(1) + }, + expectErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tt.prepare() + + logic := GetFolloweeCountLogic{ + svcCtx: svcCtx, + ctx: context.TODO(), + } + + got, err := logic.GetFolloweeCount(tt.input) + + if tt.expectErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.input.Uid, got.Uid) + } + }) + } +} diff --git a/internal/logic/socialnetworkservice/get_followee_logic_test.go b/internal/logic/socialnetworkservice/get_followee_logic_test.go new file mode 100644 index 0000000..d356767 --- /dev/null +++ b/internal/logic/socialnetworkservice/get_followee_logic_test.go @@ -0,0 +1,130 @@ +package socialnetworkservicelogic + +import ( + "app-cloudep-tweeting-service/gen_result/pb/tweeting" + "app-cloudep-tweeting-service/internal/domain/repository" + mocklib "app-cloudep-tweeting-service/internal/mock/lib" + mockRepo "app-cloudep-tweeting-service/internal/mock/repository" + "app-cloudep-tweeting-service/internal/svc" + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +func TestGetFolloweeLogic_GetFollowee(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // 初始化 mock 依賴 + mockSocialNetworkRepository := mockRepo.NewMockSocialNetworkRepository(ctrl) + mockValidate := mocklib.NewMockValidate(ctrl) + + // 初始化服務上下文 + svcCtx := &svc.ServiceContext{ + SocialNetworkRepository: mockSocialNetworkRepository, + Validate: mockValidate, + } + + // 測試數據集 + tests := []struct { + name string + input *tweeting.FollowReq + prepare func() + expectErr bool + wantResp *tweeting.FollowResp + }{ + { + name: "成功獲取我跟隨的名單", + input: &tweeting.FollowReq{ + Uid: "12345", + PageSize: 10, + PageIndex: 1, + }, + prepare: func() { + // 模擬驗證通過 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + // 模擬 GetFollowee 返回正確的結果 + mockSocialNetworkRepository.EXPECT().GetFollowee(gomock.Any(), repository.FollowReq{ + UID: "12345", + PageSize: 10, + PageIndex: 1, + }).Return(repository.FollowResp{ + UIDs: []string{"user1", "user2"}, + Total: 2, + }, nil).Times(1) + }, + expectErr: false, + wantResp: &tweeting.FollowResp{ + Uid: []string{"user1", "user2"}, + Page: &tweeting.Pager{ + Total: 2, + Index: 1, + Size: 10, + }, + }, + }, + { + name: "驗證失敗", + input: &tweeting.FollowReq{ + Uid: "", + PageSize: 10, + PageIndex: 1, + }, + prepare: func() { + // 模擬驗證失敗 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(errors.New("validation failed")).Times(1) + }, + expectErr: true, + wantResp: nil, + }, + { + name: "獲取我跟隨的名單失敗", + input: &tweeting.FollowReq{ + Uid: "12345", + PageSize: 10, + PageIndex: 1, + }, + prepare: func() { + // 模擬驗證通過 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + // 模擬 GetFollowee 返回錯誤 + mockSocialNetworkRepository.EXPECT().GetFollowee(gomock.Any(), repository.FollowReq{ + UID: "12345", + PageSize: 10, + PageIndex: 1, + }).Return(repository.FollowResp{}, errors.New("repository error")).Times(1) + }, + expectErr: true, + wantResp: nil, + }, + } + + // 執行測試 + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // 設置測試環境 + tt.prepare() + + // 初始化 GetFolloweeLogic + logic := GetFolloweeLogic{ + svcCtx: svcCtx, + ctx: context.TODO(), + } + + // 執行 GetFollowee + got, err := logic.GetFollowee(tt.input) + + // 驗證結果 + if tt.expectErr { + assert.Error(t, err) + assert.Nil(t, got) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.wantResp, got) + } + }) + } +} diff --git a/internal/logic/socialnetworkservice/get_follower_count_logic_test.go b/internal/logic/socialnetworkservice/get_follower_count_logic_test.go new file mode 100644 index 0000000..b6f9924 --- /dev/null +++ b/internal/logic/socialnetworkservice/get_follower_count_logic_test.go @@ -0,0 +1,108 @@ +package socialnetworkservicelogic + +import ( + "app-cloudep-tweeting-service/gen_result/pb/tweeting" + mocklib "app-cloudep-tweeting-service/internal/mock/lib" + mockRepo "app-cloudep-tweeting-service/internal/mock/repository" + "app-cloudep-tweeting-service/internal/svc" + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +func TestGetFollowerCountLogic_GetFollowerCount(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // 初始化 mock 依賴 + mockSocialNetworkRepository := mockRepo.NewMockSocialNetworkRepository(ctrl) + mockValidate := mocklib.NewMockValidate(ctrl) + + // 初始化服務上下文 + svcCtx := &svc.ServiceContext{ + SocialNetworkRepository: mockSocialNetworkRepository, + Validate: mockValidate, + } + + // 測試數據集 + tests := []struct { + name string + input *tweeting.FollowCountReq + prepare func() + expectErr bool + wantResp *tweeting.FollowCountResp + }{ + { + name: "成功獲取跟隨者數量", + input: &tweeting.FollowCountReq{ + Uid: "12345", + }, + prepare: func() { + // 模擬驗證通過 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + // 模擬 GetFollowerCount 返回正確的結果 + mockSocialNetworkRepository.EXPECT().GetFollowerCount(gomock.Any(), "12345").Return(int64(10), nil).Times(1) + }, + expectErr: false, + wantResp: &tweeting.FollowCountResp{ + Uid: "12345", + Total: 10, + }, + }, + { + name: "驗證失敗", + input: &tweeting.FollowCountReq{ + Uid: "", + }, + prepare: func() { + // 模擬驗證失敗 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(errors.New("validation failed")).Times(1) + }, + expectErr: true, + wantResp: nil, + }, + { + name: "獲取跟隨者數量失敗", + input: &tweeting.FollowCountReq{ + Uid: "12345", + }, + prepare: func() { + // 模擬驗證通過 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + // 模擬 GetFollowerCount 返回錯誤 + mockSocialNetworkRepository.EXPECT().GetFollowerCount(gomock.Any(), "12345").Return(int64(0), errors.New("repository error")).Times(1) + }, + expectErr: true, + wantResp: nil, + }, + } + + // 執行測試 + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // 設置測試環境 + tt.prepare() + + // 初始化 GetFollowerCountLogic + logic := GetFollowerCountLogic{ + svcCtx: svcCtx, + ctx: context.TODO(), + } + + // 執行 GetFollowerCount + got, err := logic.GetFollowerCount(tt.input) + + // 驗證結果 + if tt.expectErr { + assert.Error(t, err) + assert.Nil(t, got) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.wantResp, got) + } + }) + } +} diff --git a/internal/logic/socialnetworkservice/get_follower_logic_test.go b/internal/logic/socialnetworkservice/get_follower_logic_test.go new file mode 100644 index 0000000..249a7c4 --- /dev/null +++ b/internal/logic/socialnetworkservice/get_follower_logic_test.go @@ -0,0 +1,130 @@ +package socialnetworkservicelogic + +import ( + "app-cloudep-tweeting-service/gen_result/pb/tweeting" + "app-cloudep-tweeting-service/internal/domain/repository" + mocklib "app-cloudep-tweeting-service/internal/mock/lib" + mockRepo "app-cloudep-tweeting-service/internal/mock/repository" + "app-cloudep-tweeting-service/internal/svc" + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +func TestGetFollowerLogic_GetFollower(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // 初始化 mock 依賴 + mockSocialNetworkRepository := mockRepo.NewMockSocialNetworkRepository(ctrl) + mockValidate := mocklib.NewMockValidate(ctrl) + + // 初始化服務上下文 + svcCtx := &svc.ServiceContext{ + SocialNetworkRepository: mockSocialNetworkRepository, + Validate: mockValidate, + } + + // 測試數據集 + tests := []struct { + name string + input *tweeting.FollowReq + prepare func() + expectErr bool + wantResp *tweeting.FollowResp + }{ + { + name: "成功獲取跟隨者名單", + input: &tweeting.FollowReq{ + Uid: "12345", + PageSize: 10, + PageIndex: 1, + }, + prepare: func() { + // 模擬驗證通過 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + // 模擬 GetFollower 返回正確的結果 + mockSocialNetworkRepository.EXPECT().GetFollower(gomock.Any(), repository.FollowReq{ + UID: "12345", + PageSize: 10, + PageIndex: 1, + }).Return(repository.FollowResp{ + UIDs: []string{"user1", "user2"}, + Total: 2, + }, nil).Times(1) + }, + expectErr: false, + wantResp: &tweeting.FollowResp{ + Uid: []string{"user1", "user2"}, + Page: &tweeting.Pager{ + Total: 2, + Index: 1, + Size: 10, + }, + }, + }, + { + name: "驗證失敗", + input: &tweeting.FollowReq{ + Uid: "", + PageSize: 10, + PageIndex: 1, + }, + prepare: func() { + // 模擬驗證失敗 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(errors.New("validation failed")).Times(1) + }, + expectErr: true, + wantResp: nil, + }, + { + name: "獲取跟隨者名單失敗", + input: &tweeting.FollowReq{ + Uid: "12345", + PageSize: 10, + PageIndex: 1, + }, + prepare: func() { + // 模擬驗證通過 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + // 模擬 GetFollower 返回錯誤 + mockSocialNetworkRepository.EXPECT().GetFollower(gomock.Any(), repository.FollowReq{ + UID: "12345", + PageSize: 10, + PageIndex: 1, + }).Return(repository.FollowResp{}, errors.New("repository error")).Times(1) + }, + expectErr: true, + wantResp: nil, + }, + } + + // 執行測試 + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // 設置測試環境 + tt.prepare() + + // 初始化 GetFollowerLogic + logic := GetFollowerLogic{ + svcCtx: svcCtx, + ctx: context.TODO(), + } + + // 執行 GetFollower + got, err := logic.GetFollower(tt.input) + + // 驗證結果 + if tt.expectErr { + assert.Error(t, err) + assert.Nil(t, got) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.wantResp, got) + } + }) + } +} diff --git a/internal/logic/socialnetworkservice/mark_follow_relation_logic_test.go b/internal/logic/socialnetworkservice/mark_follow_relation_logic_test.go new file mode 100644 index 0000000..ec6163c --- /dev/null +++ b/internal/logic/socialnetworkservice/mark_follow_relation_logic_test.go @@ -0,0 +1,108 @@ +package socialnetworkservicelogic + +import ( + "app-cloudep-tweeting-service/gen_result/pb/tweeting" + mocklib "app-cloudep-tweeting-service/internal/mock/lib" + mockRepo "app-cloudep-tweeting-service/internal/mock/repository" + "app-cloudep-tweeting-service/internal/svc" + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +func TestMarkFollowRelationLogic_MarkFollowRelation(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // 初始化 mock 依賴 + mockSocialNetworkRepository := mockRepo.NewMockSocialNetworkRepository(ctrl) + mockValidate := mocklib.NewMockValidate(ctrl) + + // 初始化服務上下文 + svcCtx := &svc.ServiceContext{ + SocialNetworkRepository: mockSocialNetworkRepository, + Validate: mockValidate, + } + + // 測試數據集 + tests := []struct { + name string + input *tweeting.DoFollowerRelationReq + prepare func() + expectErr bool + wantResp *tweeting.OKResp + }{ + { + name: "成功建立關注關係", + input: &tweeting.DoFollowerRelationReq{ + FollowerUid: "follower123", + FolloweeUid: "followee456", + }, + prepare: func() { + // 模擬驗證通過 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + // 模擬成功建立關注關係 + mockSocialNetworkRepository.EXPECT().MarkFollowerRelation(gomock.Any(), "follower123", "followee456").Return(nil).Times(1) + }, + expectErr: false, + wantResp: &tweeting.OKResp{}, + }, + { + name: "驗證失敗", + input: &tweeting.DoFollowerRelationReq{ + FollowerUid: "", + FolloweeUid: "", + }, + prepare: func() { + // 模擬驗證失敗 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(errors.New("validation failed")).Times(1) + }, + expectErr: true, + wantResp: nil, + }, + { + name: "建立關注關係失敗", + input: &tweeting.DoFollowerRelationReq{ + FollowerUid: "follower123", + FolloweeUid: "followee456", + }, + prepare: func() { + // 模擬驗證通過 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + // 模擬建立關注關係失敗 + mockSocialNetworkRepository.EXPECT().MarkFollowerRelation(gomock.Any(), "follower123", "followee456").Return(errors.New("repository error")).Times(1) + }, + expectErr: true, + wantResp: nil, + }, + } + + // 執行測試 + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // 設置測試環境 + tt.prepare() + + // 初始化 MarkFollowRelationLogic + logic := MarkFollowRelationLogic{ + svcCtx: svcCtx, + ctx: context.TODO(), + } + + // 執行 MarkFollowRelation + got, err := logic.MarkFollowRelation(tt.input) + + // 驗證結果 + if tt.expectErr { + assert.Error(t, err) + assert.Nil(t, got) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.wantResp, got) + } + }) + } +} diff --git a/internal/logic/socialnetworkservice/remove_follow_relation_logic_test.go b/internal/logic/socialnetworkservice/remove_follow_relation_logic_test.go new file mode 100644 index 0000000..17b9484 --- /dev/null +++ b/internal/logic/socialnetworkservice/remove_follow_relation_logic_test.go @@ -0,0 +1,108 @@ +package socialnetworkservicelogic + +import ( + "app-cloudep-tweeting-service/gen_result/pb/tweeting" + mocklib "app-cloudep-tweeting-service/internal/mock/lib" + mockRepo "app-cloudep-tweeting-service/internal/mock/repository" + "app-cloudep-tweeting-service/internal/svc" + "context" + "errors" + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +func TestRemoveFollowRelationLogic_RemoveFollowRelation(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + // 初始化 mock 依賴 + mockSocialNetworkRepository := mockRepo.NewMockSocialNetworkRepository(ctrl) + mockValidate := mocklib.NewMockValidate(ctrl) + + // 初始化服務上下文 + svcCtx := &svc.ServiceContext{ + SocialNetworkRepository: mockSocialNetworkRepository, + Validate: mockValidate, + } + + // 測試數據集 + tests := []struct { + name string + input *tweeting.DoFollowerRelationReq + prepare func() + expectErr bool + wantResp *tweeting.OKResp + }{ + { + name: "成功取消關注", + input: &tweeting.DoFollowerRelationReq{ + FollowerUid: "follower123", + FolloweeUid: "followee456", + }, + prepare: func() { + // 模擬驗證通過 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + // 模擬成功刪除關注關係 + mockSocialNetworkRepository.EXPECT().RemoveFollowerRelation(gomock.Any(), "follower123", "followee456").Return(nil).Times(1) + }, + expectErr: false, + wantResp: &tweeting.OKResp{}, + }, + { + name: "驗證失敗", + input: &tweeting.DoFollowerRelationReq{ + FollowerUid: "", + FolloweeUid: "", + }, + prepare: func() { + // 模擬驗證失敗 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(errors.New("validation failed")).Times(1) + }, + expectErr: true, + wantResp: nil, + }, + { + name: "取消關注失敗", + input: &tweeting.DoFollowerRelationReq{ + FollowerUid: "follower123", + FolloweeUid: "followee456", + }, + prepare: func() { + // 模擬驗證通過 + mockValidate.EXPECT().ValidateAll(gomock.Any()).Return(nil).Times(1) + // 模擬刪除關注關係失敗 + mockSocialNetworkRepository.EXPECT().RemoveFollowerRelation(gomock.Any(), "follower123", "followee456").Return(errors.New("repository error")).Times(1) + }, + expectErr: true, + wantResp: nil, + }, + } + + // 執行測試 + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // 設置測試環境 + tt.prepare() + + // 初始化 RemoveFollowRelationLogic + logic := RemoveFollowRelationLogic{ + svcCtx: svcCtx, + ctx: context.TODO(), + } + + // 執行 RemoveFollowRelation + got, err := logic.RemoveFollowRelation(tt.input) + + // 驗證結果 + if tt.expectErr { + assert.Error(t, err) + assert.Nil(t, got) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.wantResp, got) + } + }) + } +} diff --git a/internal/mock/repository/social_network.go b/internal/mock/repository/social_network.go new file mode 100644 index 0000000..163a03d --- /dev/null +++ b/internal/mock/repository/social_network.go @@ -0,0 +1,174 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./internal/domain/repository/social_network.go +// +// Generated by this command: +// +// mockgen -source=./internal/domain/repository/social_network.go -destination=./internal/mock/repository/social_network.go -package=mock +// + +// Package mock is a generated GoMock package. +package mock + +import ( + repository "app-cloudep-tweeting-service/internal/domain/repository" + context "context" + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockSocialNetworkRepository is a mock of SocialNetworkRepository interface. +type MockSocialNetworkRepository struct { + ctrl *gomock.Controller + recorder *MockSocialNetworkRepositoryMockRecorder +} + +// MockSocialNetworkRepositoryMockRecorder is the mock recorder for MockSocialNetworkRepository. +type MockSocialNetworkRepositoryMockRecorder struct { + mock *MockSocialNetworkRepository +} + +// NewMockSocialNetworkRepository creates a new mock instance. +func NewMockSocialNetworkRepository(ctrl *gomock.Controller) *MockSocialNetworkRepository { + mock := &MockSocialNetworkRepository{ctrl: ctrl} + mock.recorder = &MockSocialNetworkRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSocialNetworkRepository) EXPECT() *MockSocialNetworkRepositoryMockRecorder { + return m.recorder +} + +// CreateUserNode mocks base method. +func (m *MockSocialNetworkRepository) CreateUserNode(ctx context.Context, uid string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateUserNode", ctx, uid) + ret0, _ := ret[0].(error) + return ret0 +} + +// CreateUserNode indicates an expected call of CreateUserNode. +func (mr *MockSocialNetworkRepositoryMockRecorder) CreateUserNode(ctx, uid any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateUserNode", reflect.TypeOf((*MockSocialNetworkRepository)(nil).CreateUserNode), ctx, uid) +} + +// GetDegreeBetweenUsers mocks base method. +func (m *MockSocialNetworkRepository) GetDegreeBetweenUsers(ctx context.Context, uid1, uid2 string) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetDegreeBetweenUsers", ctx, uid1, uid2) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetDegreeBetweenUsers indicates an expected call of GetDegreeBetweenUsers. +func (mr *MockSocialNetworkRepositoryMockRecorder) GetDegreeBetweenUsers(ctx, uid1, uid2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDegreeBetweenUsers", reflect.TypeOf((*MockSocialNetworkRepository)(nil).GetDegreeBetweenUsers), ctx, uid1, uid2) +} + +// GetFollowee mocks base method. +func (m *MockSocialNetworkRepository) GetFollowee(ctx context.Context, req repository.FollowReq) (repository.FollowResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFollowee", ctx, req) + ret0, _ := ret[0].(repository.FollowResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFollowee indicates an expected call of GetFollowee. +func (mr *MockSocialNetworkRepositoryMockRecorder) GetFollowee(ctx, req any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFollowee", reflect.TypeOf((*MockSocialNetworkRepository)(nil).GetFollowee), ctx, req) +} + +// GetFolloweeCount mocks base method. +func (m *MockSocialNetworkRepository) GetFolloweeCount(ctx context.Context, uid string) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFolloweeCount", ctx, uid) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFolloweeCount indicates an expected call of GetFolloweeCount. +func (mr *MockSocialNetworkRepositoryMockRecorder) GetFolloweeCount(ctx, uid any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFolloweeCount", reflect.TypeOf((*MockSocialNetworkRepository)(nil).GetFolloweeCount), ctx, uid) +} + +// GetFollower mocks base method. +func (m *MockSocialNetworkRepository) GetFollower(ctx context.Context, req repository.FollowReq) (repository.FollowResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFollower", ctx, req) + ret0, _ := ret[0].(repository.FollowResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFollower indicates an expected call of GetFollower. +func (mr *MockSocialNetworkRepositoryMockRecorder) GetFollower(ctx, req any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFollower", reflect.TypeOf((*MockSocialNetworkRepository)(nil).GetFollower), ctx, req) +} + +// GetFollowerCount mocks base method. +func (m *MockSocialNetworkRepository) GetFollowerCount(ctx context.Context, uid string) (int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFollowerCount", ctx, uid) + ret0, _ := ret[0].(int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFollowerCount indicates an expected call of GetFollowerCount. +func (mr *MockSocialNetworkRepositoryMockRecorder) GetFollowerCount(ctx, uid any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFollowerCount", reflect.TypeOf((*MockSocialNetworkRepository)(nil).GetFollowerCount), ctx, uid) +} + +// GetUIDsWithinNDegrees mocks base method. +func (m *MockSocialNetworkRepository) GetUIDsWithinNDegrees(ctx context.Context, uid string, degrees, pageSize, pageIndex int64) ([]string, int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetUIDsWithinNDegrees", ctx, uid, degrees, pageSize, pageIndex) + ret0, _ := ret[0].([]string) + ret1, _ := ret[1].(int64) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 +} + +// GetUIDsWithinNDegrees indicates an expected call of GetUIDsWithinNDegrees. +func (mr *MockSocialNetworkRepositoryMockRecorder) GetUIDsWithinNDegrees(ctx, uid, degrees, pageSize, pageIndex any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUIDsWithinNDegrees", reflect.TypeOf((*MockSocialNetworkRepository)(nil).GetUIDsWithinNDegrees), ctx, uid, degrees, pageSize, pageIndex) +} + +// MarkFollowerRelation mocks base method. +func (m *MockSocialNetworkRepository) MarkFollowerRelation(ctx context.Context, fromUID, toUID string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MarkFollowerRelation", ctx, fromUID, toUID) + ret0, _ := ret[0].(error) + return ret0 +} + +// MarkFollowerRelation indicates an expected call of MarkFollowerRelation. +func (mr *MockSocialNetworkRepositoryMockRecorder) MarkFollowerRelation(ctx, fromUID, toUID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarkFollowerRelation", reflect.TypeOf((*MockSocialNetworkRepository)(nil).MarkFollowerRelation), ctx, fromUID, toUID) +} + +// RemoveFollowerRelation mocks base method. +func (m *MockSocialNetworkRepository) RemoveFollowerRelation(ctx context.Context, fromUID, toUID string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveFollowerRelation", ctx, fromUID, toUID) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveFollowerRelation indicates an expected call of RemoveFollowerRelation. +func (mr *MockSocialNetworkRepositoryMockRecorder) RemoveFollowerRelation(ctx, fromUID, toUID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveFollowerRelation", reflect.TypeOf((*MockSocialNetworkRepository)(nil).RemoveFollowerRelation), ctx, fromUID, toUID) +} diff --git a/internal/mock/repository/timeline.go b/internal/mock/repository/timeline.go new file mode 100644 index 0000000..91325f5 --- /dev/null +++ b/internal/mock/repository/timeline.go @@ -0,0 +1,113 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: ./internal/domain/repository/timeline.go +// +// Generated by this command: +// +// mockgen -source=./internal/domain/repository/timeline.go -destination=./internal/mock/repository/timeline.go -package=mock +// + +// Package mock is a generated GoMock package. +package mock + +import ( + repository "app-cloudep-tweeting-service/internal/domain/repository" + context "context" + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockTimelineRepository is a mock of TimelineRepository interface. +type MockTimelineRepository struct { + ctrl *gomock.Controller + recorder *MockTimelineRepositoryMockRecorder +} + +// MockTimelineRepositoryMockRecorder is the mock recorder for MockTimelineRepository. +type MockTimelineRepositoryMockRecorder struct { + mock *MockTimelineRepository +} + +// NewMockTimelineRepository creates a new mock instance. +func NewMockTimelineRepository(ctrl *gomock.Controller) *MockTimelineRepository { + mock := &MockTimelineRepository{ctrl: ctrl} + mock.recorder = &MockTimelineRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTimelineRepository) EXPECT() *MockTimelineRepositoryMockRecorder { + return m.recorder +} + +// AddPost mocks base method. +func (m *MockTimelineRepository) AddPost(ctx context.Context, req repository.AddPostRequest) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddPost", ctx, req) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddPost indicates an expected call of AddPost. +func (mr *MockTimelineRepositoryMockRecorder) AddPost(ctx, req any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPost", reflect.TypeOf((*MockTimelineRepository)(nil).AddPost), ctx, req) +} + +// ClearNoMoreDataFlag mocks base method. +func (m *MockTimelineRepository) ClearNoMoreDataFlag(ctx context.Context, uid string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClearNoMoreDataFlag", ctx, uid) + ret0, _ := ret[0].(error) + return ret0 +} + +// ClearNoMoreDataFlag indicates an expected call of ClearNoMoreDataFlag. +func (mr *MockTimelineRepositoryMockRecorder) ClearNoMoreDataFlag(ctx, uid any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClearNoMoreDataFlag", reflect.TypeOf((*MockTimelineRepository)(nil).ClearNoMoreDataFlag), ctx, uid) +} + +// FetchTimeline mocks base method. +func (m *MockTimelineRepository) FetchTimeline(ctx context.Context, req repository.FetchTimelineRequest) (repository.FetchTimelineResponse, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FetchTimeline", ctx, req) + ret0, _ := ret[0].(repository.FetchTimelineResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// FetchTimeline indicates an expected call of FetchTimeline. +func (mr *MockTimelineRepositoryMockRecorder) FetchTimeline(ctx, req any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FetchTimeline", reflect.TypeOf((*MockTimelineRepository)(nil).FetchTimeline), ctx, req) +} + +// HasNoMoreData mocks base method. +func (m *MockTimelineRepository) HasNoMoreData(ctx context.Context, uid string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HasNoMoreData", ctx, uid) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HasNoMoreData indicates an expected call of HasNoMoreData. +func (mr *MockTimelineRepositoryMockRecorder) HasNoMoreData(ctx, uid any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasNoMoreData", reflect.TypeOf((*MockTimelineRepository)(nil).HasNoMoreData), ctx, uid) +} + +// SetNoMoreDataFlag mocks base method. +func (m *MockTimelineRepository) SetNoMoreDataFlag(ctx context.Context, uid string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetNoMoreDataFlag", ctx, uid) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetNoMoreDataFlag indicates an expected call of SetNoMoreDataFlag. +func (mr *MockTimelineRepositoryMockRecorder) SetNoMoreDataFlag(ctx, uid any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNoMoreDataFlag", reflect.TypeOf((*MockTimelineRepository)(nil).SetNoMoreDataFlag), ctx, uid) +} diff --git a/internal/repository/social_network_test.go b/internal/repository/social_network_test.go new file mode 100644 index 0000000..50a4378 --- /dev/null +++ b/internal/repository/social_network_test.go @@ -0,0 +1 @@ +package repository