feature/fanout #3
			
				
			
		
		
		
	
							
								
								
									
										2
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								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/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_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/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" | 	@echo "Generate mock files successfully" | ||||||
| 
 | 
 | ||||||
| .PHONY: migrate-database | .PHONY: migrate-database | ||||||
|  |  | ||||||
							
								
								
									
										33
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										33
									
								
								go.mod
								
								
								
								
							|  | @ -8,6 +8,7 @@ require ( | ||||||
| 	github.com/alicebob/miniredis/v2 v2.33.0 | 	github.com/alicebob/miniredis/v2 v2.33.0 | ||||||
| 	github.com/neo4j/neo4j-go-driver/v5 v5.24.0 | 	github.com/neo4j/neo4j-go-driver/v5 v5.24.0 | ||||||
| 	github.com/stretchr/testify v1.9.0 | 	github.com/stretchr/testify v1.9.0 | ||||||
|  | 	github.com/testcontainers/testcontainers-go v0.33.0 | ||||||
| 	github.com/zeromicro/go-zero v1.7.0 | 	github.com/zeromicro/go-zero v1.7.0 | ||||||
| 	go.mongodb.org/mongo-driver v1.16.0 | 	go.mongodb.org/mongo-driver v1.16.0 | ||||||
| 	go.uber.org/mock v0.4.0 | 	go.uber.org/mock v0.4.0 | ||||||
|  | @ -16,19 +17,32 @@ require ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| 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/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect | ||||||
| 	github.com/beorn7/perks v1.0.1 // indirect | 	github.com/beorn7/perks v1.0.1 // indirect | ||||||
| 	github.com/cenkalti/backoff/v4 v4.3.0 // indirect | 	github.com/cenkalti/backoff/v4 v4.3.0 // indirect | ||||||
| 	github.com/cespare/xxhash/v2 v2.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-semver v0.3.1 // indirect | ||||||
| 	github.com/coreos/go-systemd/v22 v22.5.0 // 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/davecgh/go-spew v1.1.1 // indirect | ||||||
| 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // 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/emicklei/go-restful/v3 v3.11.0 // indirect | ||||||
| 	github.com/fatih/color v1.17.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/gabriel-vasile/mimetype v1.4.3 // indirect | ||||||
| 	github.com/go-logr/logr v1.4.2 // indirect | 	github.com/go-logr/logr v1.4.2 // indirect | ||||||
| 	github.com/go-logr/stdr v1.2.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/jsonpointer v0.19.6 // indirect | ||||||
| 	github.com/go-openapi/jsonreference v0.20.2 // indirect | 	github.com/go-openapi/jsonreference v0.20.2 // indirect | ||||||
| 	github.com/go-openapi/swag v0.22.4 // 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/json-iterator/go v1.1.12 // indirect | ||||||
| 	github.com/klauspost/compress v1.17.8 // indirect | 	github.com/klauspost/compress v1.17.8 // indirect | ||||||
| 	github.com/leodido/go-urn v1.4.0 // 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/mailru/easyjson v0.7.7 // indirect | ||||||
| 	github.com/mattn/go-colorable v0.1.13 // indirect | 	github.com/mattn/go-colorable v0.1.13 // indirect | ||||||
| 	github.com/mattn/go-isatty v0.0.20 // 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/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||||||
| 	github.com/modern-go/reflect2 v1.0.2 // indirect | 	github.com/modern-go/reflect2 v1.0.2 // indirect | ||||||
| 	github.com/montanaflynn/stats v0.7.1 // 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/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/openzipkin/zipkin-go v0.4.3 // indirect | ||||||
| 	github.com/pelletier/go-toml/v2 v2.2.2 // 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/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_golang v1.19.1 // indirect | ||||||
| 	github.com/prometheus/client_model v0.5.0 // indirect | 	github.com/prometheus/client_model v0.5.0 // indirect | ||||||
| 	github.com/prometheus/common v0.48.0 // indirect | 	github.com/prometheus/common v0.48.0 // indirect | ||||||
| 	github.com/prometheus/procfs v0.12.0 // indirect | 	github.com/prometheus/procfs v0.12.0 // indirect | ||||||
| 	github.com/redis/go-redis/v9 v9.6.1 // 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/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/pbkdf2 v1.0.0 // indirect | ||||||
| 	github.com/xdg-go/scram v1.1.2 // indirect | 	github.com/xdg-go/scram v1.1.2 // indirect | ||||||
| 	github.com/xdg-go/stringprep v1.0.4 // indirect | 	github.com/xdg-go/stringprep v1.0.4 // indirect | ||||||
| 	github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect | 	github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect | ||||||
| 	github.com/yuin/gopher-lua v1.1.1 // 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/api/v3 v3.5.15 // indirect | ||||||
| 	go.etcd.io/etcd/client/pkg/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.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 v1.24.0 // indirect | ||||||
| 	go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect | 	go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect | ||||||
| 	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect | 	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ type Config struct { | ||||||
| 	// Redis Cluster
 | 	// Redis Cluster
 | ||||||
| 	RedisCluster redis.RedisConf | 	RedisCluster redis.RedisConf | ||||||
| 
 | 
 | ||||||
| 	// 圖形話資料庫
 | 	// 圖形資料庫
 | ||||||
| 	Neo4J struct { | 	Neo4J struct { | ||||||
| 		URI                   string | 		URI                   string | ||||||
| 		Username              string | 		Username              string | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
|  | 				}() | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -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) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -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) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -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) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -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) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -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) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -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) | ||||||
|  | 			} | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -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) | ||||||
|  | } | ||||||
|  | @ -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) | ||||||
|  | } | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | package repository | ||||||
		Loading…
	
		Reference in New Issue