feat: init project
This commit is contained in:
commit
22db9d53ec
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="Go" enabled="true" />
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MaterialThemeProjectNewConfig">
|
||||
<option name="metadata">
|
||||
<MTProjectMetadataState>
|
||||
<option name="userId" value="44a3c0f2:19449e817e3:-7fe1" />
|
||||
</MTProjectMetadataState>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/app-cloudep-comment-server.iml" filepath="$PROJECT_DIR$/.idea/app-cloudep-comment-server.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,31 @@
|
|||
# go-zero 生成風格
|
||||
GO_ZERO_STYLE=go_zero
|
||||
GO ?= go
|
||||
GOFMT ?= gofmt "-s"
|
||||
GOFILES := $(shell find . -name "*.go")
|
||||
LDFLAGS := -s -w
|
||||
VERSION="v1.0.4"
|
||||
DOCKER_REPO="igs170911/comment"
|
||||
GIT_COMMIT ?= $(shell git rev-parse --short HEAD)
|
||||
|
||||
.PHONY: test
|
||||
test: # 進行測試
|
||||
go test -v --cover ./...
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: # 格式優化
|
||||
$(GOFMT) -w $(GOFILES)
|
||||
goimports -w ./
|
||||
golangci-lint run
|
||||
|
||||
.PHONY: gen-rpc
|
||||
gen-rpc: # 建立 rpc code
|
||||
goctl rpc protoc ./generate/protobuf/comment.proto -m --style=$(GO_ZERO_STYLE) --go_out=./gen_result/pb --go-grpc_out=./gen_result/pb --zrpc_out=.
|
||||
go mod tidy
|
||||
@echo "Generate core-api files successfully"
|
||||
|
||||
.PHONY: mock-gen
|
||||
mock-gen: # 建立 mock 資料
|
||||
mockgen -source=./pkg/domain/repository/comment.go -destination=./pkg/mock/repository/comment.go -package=mock
|
||||
|
||||
@echo "Generate mock files successfully"
|
|
@ -0,0 +1,39 @@
|
|||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.7.3
|
||||
// Source: comment.proto
|
||||
|
||||
package comment
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"app-cloudep-comment-server/gen_result/pb/comment"
|
||||
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type (
|
||||
NoneReq = comment.NoneReq
|
||||
OKResp = comment.OKResp
|
||||
Pager = comment.Pager
|
||||
|
||||
Comment interface {
|
||||
Empty(ctx context.Context, in *NoneReq, opts ...grpc.CallOption) (*OKResp, error)
|
||||
}
|
||||
|
||||
defaultComment struct {
|
||||
cli zrpc.Client
|
||||
}
|
||||
)
|
||||
|
||||
func NewComment(cli zrpc.Client) Comment {
|
||||
return &defaultComment{
|
||||
cli: cli,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultComment) Empty(ctx context.Context, in *NoneReq, opts ...grpc.CallOption) (*OKResp, error) {
|
||||
client := comment.NewCommentClient(m.cli.Conn())
|
||||
return client.Empty(ctx, in, opts...)
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"app-cloudep-comment-server/gen_result/pb/comment"
|
||||
"app-cloudep-comment-server/internal/config"
|
||||
commentServer "app-cloudep-comment-server/internal/server/comment"
|
||||
"app-cloudep-comment-server/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
"github.com/zeromicro/go-zero/core/service"
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection"
|
||||
)
|
||||
|
||||
var configFile = flag.String("f", "etc/comment.yaml", "the config file")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
ctx := svc.NewServiceContext(c)
|
||||
|
||||
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
||||
comment.RegisterCommentServer(grpcServer, commentServer.NewCommentServer(ctx))
|
||||
|
||||
if c.Mode == service.DevMode || c.Mode == service.TestMode {
|
||||
reflection.Register(grpcServer)
|
||||
}
|
||||
})
|
||||
defer s.Stop()
|
||||
|
||||
fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
|
||||
s.Start()
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
Name: comment.rpc
|
||||
ListenOn: 0.0.0.0:8080
|
||||
Etcd:
|
||||
Hosts:
|
||||
- 127.0.0.1:2379
|
||||
Key: comment.rpc
|
|
@ -0,0 +1,227 @@
|
|||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.1
|
||||
// protoc v3.19.4
|
||||
// source: generate/protobuf/comment.proto
|
||||
|
||||
package comment
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// OKResp
|
||||
type OKResp struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *OKResp) Reset() {
|
||||
*x = OKResp{}
|
||||
mi := &file_generate_protobuf_comment_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *OKResp) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*OKResp) ProtoMessage() {}
|
||||
|
||||
func (x *OKResp) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_generate_protobuf_comment_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use OKResp.ProtoReflect.Descriptor instead.
|
||||
func (*OKResp) Descriptor() ([]byte, []int) {
|
||||
return file_generate_protobuf_comment_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
// NoneReq
|
||||
type NoneReq struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *NoneReq) Reset() {
|
||||
*x = NoneReq{}
|
||||
mi := &file_generate_protobuf_comment_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *NoneReq) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*NoneReq) ProtoMessage() {}
|
||||
|
||||
func (x *NoneReq) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_generate_protobuf_comment_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use NoneReq.ProtoReflect.Descriptor instead.
|
||||
func (*NoneReq) Descriptor() ([]byte, []int) {
|
||||
return file_generate_protobuf_comment_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type Pager struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
|
||||
Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"`
|
||||
Index int64 `protobuf:"varint,3,opt,name=index,proto3" json:"index,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Pager) Reset() {
|
||||
*x = Pager{}
|
||||
mi := &file_generate_protobuf_comment_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Pager) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Pager) ProtoMessage() {}
|
||||
|
||||
func (x *Pager) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_generate_protobuf_comment_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Pager.ProtoReflect.Descriptor instead.
|
||||
func (*Pager) Descriptor() ([]byte, []int) {
|
||||
return file_generate_protobuf_comment_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *Pager) GetTotal() int64 {
|
||||
if x != nil {
|
||||
return x.Total
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Pager) GetSize() int64 {
|
||||
if x != nil {
|
||||
return x.Size
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Pager) GetIndex() int64 {
|
||||
if x != nil {
|
||||
return x.Index
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_generate_protobuf_comment_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_generate_protobuf_comment_proto_rawDesc = []byte{
|
||||
0x0a, 0x1f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x08, 0x0a, 0x06, 0x4f, 0x4b,
|
||||
0x52, 0x65, 0x73, 0x70, 0x22, 0x09, 0x0a, 0x07, 0x4e, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x22,
|
||||
0x47, 0x0a, 0x05, 0x50, 0x61, 0x67, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69,
|
||||
0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x32, 0x35, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d,
|
||||
0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x10, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x4e, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x0f,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x4f, 0x4b, 0x52, 0x65, 0x73, 0x70, 0x42,
|
||||
0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_generate_protobuf_comment_proto_rawDescOnce sync.Once
|
||||
file_generate_protobuf_comment_proto_rawDescData = file_generate_protobuf_comment_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_generate_protobuf_comment_proto_rawDescGZIP() []byte {
|
||||
file_generate_protobuf_comment_proto_rawDescOnce.Do(func() {
|
||||
file_generate_protobuf_comment_proto_rawDescData = protoimpl.X.CompressGZIP(file_generate_protobuf_comment_proto_rawDescData)
|
||||
})
|
||||
return file_generate_protobuf_comment_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_generate_protobuf_comment_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_generate_protobuf_comment_proto_goTypes = []any{
|
||||
(*OKResp)(nil), // 0: comment.OKResp
|
||||
(*NoneReq)(nil), // 1: comment.NoneReq
|
||||
(*Pager)(nil), // 2: comment.Pager
|
||||
}
|
||||
var file_generate_protobuf_comment_proto_depIdxs = []int32{
|
||||
1, // 0: comment.Comment.Empty:input_type -> comment.NoneReq
|
||||
0, // 1: comment.Comment.Empty:output_type -> comment.OKResp
|
||||
1, // [1:2] is the sub-list for method output_type
|
||||
0, // [0:1] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_generate_protobuf_comment_proto_init() }
|
||||
func file_generate_protobuf_comment_proto_init() {
|
||||
if File_generate_protobuf_comment_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_generate_protobuf_comment_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_generate_protobuf_comment_proto_goTypes,
|
||||
DependencyIndexes: file_generate_protobuf_comment_proto_depIdxs,
|
||||
MessageInfos: file_generate_protobuf_comment_proto_msgTypes,
|
||||
}.Build()
|
||||
File_generate_protobuf_comment_proto = out.File
|
||||
file_generate_protobuf_comment_proto_rawDesc = nil
|
||||
file_generate_protobuf_comment_proto_goTypes = nil
|
||||
file_generate_protobuf_comment_proto_depIdxs = nil
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.5.1
|
||||
// - protoc v3.19.4
|
||||
// source: generate/protobuf/comment.proto
|
||||
|
||||
package comment
|
||||
|
||||
import (
|
||||
context "context"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
// Requires gRPC-Go v1.64.0 or later.
|
||||
const _ = grpc.SupportPackageIsVersion9
|
||||
|
||||
const (
|
||||
Comment_Empty_FullMethodName = "/comment.Comment/Empty"
|
||||
)
|
||||
|
||||
// CommentClient is the client API for Comment service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type CommentClient interface {
|
||||
Empty(ctx context.Context, in *NoneReq, opts ...grpc.CallOption) (*OKResp, error)
|
||||
}
|
||||
|
||||
type commentClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewCommentClient(cc grpc.ClientConnInterface) CommentClient {
|
||||
return &commentClient{cc}
|
||||
}
|
||||
|
||||
func (c *commentClient) Empty(ctx context.Context, in *NoneReq, opts ...grpc.CallOption) (*OKResp, error) {
|
||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||
out := new(OKResp)
|
||||
err := c.cc.Invoke(ctx, Comment_Empty_FullMethodName, in, out, cOpts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// CommentServer is the server API for Comment service.
|
||||
// All implementations must embed UnimplementedCommentServer
|
||||
// for forward compatibility.
|
||||
type CommentServer interface {
|
||||
Empty(context.Context, *NoneReq) (*OKResp, error)
|
||||
mustEmbedUnimplementedCommentServer()
|
||||
}
|
||||
|
||||
// UnimplementedCommentServer must be embedded to have
|
||||
// forward compatible implementations.
|
||||
//
|
||||
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||
// pointer dereference when methods are called.
|
||||
type UnimplementedCommentServer struct{}
|
||||
|
||||
func (UnimplementedCommentServer) Empty(context.Context, *NoneReq) (*OKResp, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Empty not implemented")
|
||||
}
|
||||
func (UnimplementedCommentServer) mustEmbedUnimplementedCommentServer() {}
|
||||
func (UnimplementedCommentServer) testEmbeddedByValue() {}
|
||||
|
||||
// UnsafeCommentServer may be embedded to opt out of forward compatibility for this service.
|
||||
// Use of this interface is not recommended, as added methods to CommentServer will
|
||||
// result in compilation errors.
|
||||
type UnsafeCommentServer interface {
|
||||
mustEmbedUnimplementedCommentServer()
|
||||
}
|
||||
|
||||
func RegisterCommentServer(s grpc.ServiceRegistrar, srv CommentServer) {
|
||||
// If the following call pancis, it indicates UnimplementedCommentServer was
|
||||
// embedded by pointer and is nil. This will cause panics if an
|
||||
// unimplemented method is ever invoked, so we test this at initialization
|
||||
// time to prevent it from happening at runtime later due to I/O.
|
||||
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||
t.testEmbeddedByValue()
|
||||
}
|
||||
s.RegisterService(&Comment_ServiceDesc, srv)
|
||||
}
|
||||
|
||||
func _Comment_Empty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(NoneReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(CommentServer).Empty(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: Comment_Empty_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(CommentServer).Empty(ctx, req.(*NoneReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
// Comment_ServiceDesc is the grpc.ServiceDesc for Comment service.
|
||||
// It's only intended for direct use with grpc.RegisterService,
|
||||
// and not to be introspected or modified (even as a copy)
|
||||
var Comment_ServiceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "comment.Comment",
|
||||
HandlerType: (*CommentServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Empty",
|
||||
Handler: _Comment_Empty_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "generate/protobuf/comment.proto",
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package comment;
|
||||
option go_package="./comment";
|
||||
// OKResp
|
||||
message OKResp {}
|
||||
// NoneReq
|
||||
message NoneReq {}
|
||||
|
||||
message Pager {
|
||||
int64 total =1;
|
||||
int64 size=2;
|
||||
int64 index=3;
|
||||
}
|
||||
|
||||
|
||||
service Comment {
|
||||
rpc Empty(NoneReq) returns(OKResp);
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
module app-cloudep-comment-server
|
||||
|
||||
go 1.23.4
|
||||
|
||||
require (
|
||||
code.30cm.net/digimon/library-go/errs v1.2.13
|
||||
code.30cm.net/digimon/library-go/mongo v0.0.9
|
||||
github.com/alicebob/miniredis/v2 v2.34.0
|
||||
github.com/golang/snappy v0.0.4
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/testcontainers/testcontainers-go v0.34.0
|
||||
github.com/zeromicro/go-zero v1.7.6
|
||||
go.mongodb.org/mongo-driver v1.17.1
|
||||
go.uber.org/mock v0.5.0
|
||||
google.golang.org/grpc v1.69.2
|
||||
google.golang.org/protobuf v1.36.2
|
||||
)
|
||||
|
||||
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.2 // 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.18.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // 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
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // 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.20.5 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.7.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // 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-20240726163527-a2c0da244d78 // 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.31.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/otlptracegrpc v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.31.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/term v0.27.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.8.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.29.3 // indirect
|
||||
k8s.io/apimachinery v0.29.4 // indirect
|
||||
k8s.io/client-go v0.29.3 // indirect
|
||||
k8s.io/klog/v2 v2.110.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
|
@ -0,0 +1,397 @@
|
|||
code.30cm.net/digimon/library-go/errs v1.2.13 h1:0HC13nwYvmGTXbF8+cjdCmFww1yHcDChJfbsWN9ZKCk=
|
||||
code.30cm.net/digimon/library-go/errs v1.2.13/go.mod h1:Hs4v7SbXNggDVBGXSYsFMjkii1qLF+rugrIpWePN4/o=
|
||||
code.30cm.net/digimon/library-go/mongo v0.0.9 h1:fPciIE5B85tXpLg8aeVQqKVbLnfpVAk9xbMu7pE2tVw=
|
||||
code.30cm.net/digimon/library-go/mongo v0.0.9/go.mod h1:KBVKz/Ci5IheI77BgZxPUeKkaGvDy8fV8EDHSCOLIO4=
|
||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE=
|
||||
github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis/v2 v2.34.0 h1:mBFWMaJSNL9RwdGRyEDoAAv8OQc5UlEhLDQggTglU/0=
|
||||
github.com/alicebob/miniredis/v2 v2.34.0/go.mod h1:kWShP4b58T1CW0Y5dViCd5ztzrDqRWqM3nksiyXk5s8=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao=
|
||||
github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
|
||||
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
|
||||
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA=
|
||||
github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
|
||||
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||
github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
|
||||
github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
|
||||
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4=
|
||||
github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o=
|
||||
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
|
||||
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
|
||||
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
|
||||
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4=
|
||||
github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
|
||||
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
|
||||
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
|
||||
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo=
|
||||
github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
|
||||
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/zeromicro/go-zero v1.7.6 h1:SArK4xecdrpVY3ZFJcbc0IZCx+NuWyHNjCv9f1+Gwrc=
|
||||
github.com/zeromicro/go-zero v1.7.6/go.mod h1:SmGykRm5e0Z4CGNj+GaSKDffaHzQV56fel0FkymTLlE=
|
||||
go.etcd.io/etcd/api/v3 v3.5.15 h1:3KpLJir1ZEBrYuV2v+Twaa/e2MdDCEZ/70H+lzEiwsk=
|
||||
go.etcd.io/etcd/api/v3 v3.5.15/go.mod h1:N9EhGzXq58WuMllgH9ZvnEr7SI9pS0k0+DHZezGp7jM=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.15 h1:fo0HpWz/KlHGMCC+YejpiCmyWDEuIpnTDzpJLB5fWlA=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.15/go.mod h1:mXDI4NAOwEiszrHCb0aqfAYNCrZP4e9hRca3d1YK8EU=
|
||||
go.etcd.io/etcd/client/v3 v3.5.15 h1:23M0eY4Fd/inNv1ZfU3AxrbbOdW79r9V9Rl62Nm6ip4=
|
||||
go.etcd.io/etcd/client/v3 v3.5.15/go.mod h1:CLSJxrYjvLtHsrPKsy7LmZEE+DK2ktfd2bN4RhBMwlU=
|
||||
go.mongodb.org/mongo-driver v1.17.1 h1:Wic5cJIwJgSpBhe3lx3+/RybR5PiYRMpVFgO7cOHyIM=
|
||||
go.mongodb.org/mongo-driver v1.17.1/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
|
||||
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 h1:Mw5xcxMwlqoJd97vwPxA8isEaIoxsta9/Q51+TTJLGE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0/go.mod h1:CQNu9bj7o7mC6U7+CA/schKEYakYXWr79ucDHTMGhCM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 h1:s0PHtIkN+3xrbDOpt2M8OTG92cWqUESvzh2MxiR5xY8=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0/go.mod h1:hZlFbDbRt++MMPCCfSJfmhkGIWnX1h3XjkfxZUjLrIA=
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.24.0 h1:3evrL5poBuh1KF51D9gO/S+N/1msnm4DaBqs/rpXUqY=
|
||||
go.opentelemetry.io/otel/exporters/zipkin v1.24.0/go.mod h1:0EHgD8R0+8yRhUYJOGR8Hfg2dpiJQxDOszd5smVO9wM=
|
||||
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
|
||||
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
|
||||
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
|
||||
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
|
||||
google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU=
|
||||
google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
|
||||
google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU=
|
||||
google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
|
||||
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
|
||||
k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw=
|
||||
k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80=
|
||||
k8s.io/apimachinery v0.29.4 h1:RaFdJiDmuKs/8cm1M6Dh1Kvyh59YQFDcFuFTSmXes6Q=
|
||||
k8s.io/apimachinery v0.29.4/go.mod h1:i3FJVwhvSp/6n8Fl4K97PJEP8C+MM+aoDq4+ZJBf70Y=
|
||||
k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg=
|
||||
k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0=
|
||||
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
|
||||
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780=
|
||||
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
|
@ -0,0 +1,7 @@
|
|||
package config
|
||||
|
||||
import "github.com/zeromicro/go-zero/zrpc"
|
||||
|
||||
type Config struct {
|
||||
zrpc.RpcServerConf
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package commentlogic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"app-cloudep-comment-server/gen_result/pb/comment"
|
||||
"app-cloudep-comment-server/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type EmptyLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewEmptyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *EmptyLogic {
|
||||
return &EmptyLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *EmptyLogic) Empty(in *comment.NoneReq) (*comment.OKResp, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return &comment.OKResp{}, nil
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.7.3
|
||||
// Source: comment.proto
|
||||
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"app-cloudep-comment-server/gen_result/pb/comment"
|
||||
"app-cloudep-comment-server/internal/logic/comment"
|
||||
"app-cloudep-comment-server/internal/svc"
|
||||
)
|
||||
|
||||
type CommentServer struct {
|
||||
svcCtx *svc.ServiceContext
|
||||
comment.UnimplementedCommentServer
|
||||
}
|
||||
|
||||
func NewCommentServer(svcCtx *svc.ServiceContext) *CommentServer {
|
||||
return &CommentServer{
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *CommentServer) Empty(ctx context.Context, in *comment.NoneReq) (*comment.OKResp, error) {
|
||||
l := commentlogic.NewEmptyLogic(ctx, s.svcCtx)
|
||||
return l.Empty(in)
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package svc
|
||||
|
||||
import "app-cloudep-comment-server/internal/config"
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package comment
|
||||
|
||||
type Level int8
|
||||
|
||||
// ToInt8 將訂單狀態轉為 int64
|
||||
func (s Level) ToInt8() int8 {
|
||||
return int8(s)
|
||||
}
|
||||
|
||||
const (
|
||||
TopLevelComment Level = iota
|
||||
SubLevelComment
|
||||
)
|
|
@ -0,0 +1,22 @@
|
|||
package entity
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain/comment"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
// Comments 只有一層的回應,沒有巢狀回覆
|
||||
type Comments struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty"` // MongoDB 的 ObjectID
|
||||
UID string `bson:"uid"` // 留言的使用者的 ID
|
||||
ReferenceID string `bson:"reference_id"` // 參考的 id,例如 product_id
|
||||
ParentCommentID string `bson:"parent_comment_id"` // 父留言 id,沒有就空白
|
||||
Message string `bson:"message"` // 留言內容
|
||||
Level comment.Level `bson:"level"` // 等級,數字較小的為上層
|
||||
UpdatedAt int64 `bson:"updated_at"` // 更新時間
|
||||
CreatedAt int64 `bson:"created_at"` // 建立時間
|
||||
}
|
||||
|
||||
func (c *Comments) CollectionName() string {
|
||||
return "comments"
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package domain
|
||||
|
||||
import "code.30cm.net/digimon/library-go/errs"
|
||||
|
||||
const (
|
||||
_ = iota
|
||||
CreateCommentErrorCode errs.ErrorCode = iota
|
||||
GetCommentErrorCode
|
||||
DelCommentErrorCode
|
||||
ListCommentErrorCode
|
||||
UpdateCommentErrorCode
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
package domain
|
||||
|
||||
import "strings"
|
||||
|
||||
type RedisKey string
|
||||
|
||||
const (
|
||||
CommentRedisKey RedisKey = "comment"
|
||||
)
|
||||
|
||||
func (key RedisKey) ToString() string {
|
||||
return "comment:" + string(key)
|
||||
}
|
||||
|
||||
func (key RedisKey) With(s ...string) RedisKey {
|
||||
parts := append([]string{string(key)}, s...)
|
||||
|
||||
return RedisKey(strings.Join(parts, ":"))
|
||||
}
|
||||
|
||||
func GetCommentRedisKey(id string) string {
|
||||
return CommentRedisKey.With(id).ToString()
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain/comment"
|
||||
"app-cloudep-comment-server/pkg/domain/entity"
|
||||
"context"
|
||||
)
|
||||
|
||||
type CommentRepository interface {
|
||||
CreateComment(ctx context.Context, comment *entity.Comments) error // 新增留言 // 根據 ID 獲取單條留言
|
||||
DeleteCommentByID(ctx context.Context, id string) error // 根據 ID 刪除留言 // 刪除某留言的所有子留言
|
||||
UpdateCommentMessage(ctx context.Context, id string, message string) error // 更新留言內容
|
||||
ListComments(ctx context.Context, req ListCommentRequest) ([]*entity.Comments, int64, error) // 分頁列出留言
|
||||
}
|
||||
|
||||
type ListCommentRequest struct {
|
||||
PageSize int64
|
||||
PageIndex int64
|
||||
ReferenceID *string
|
||||
ParentID *string
|
||||
Level comment.Level
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type CommentUseCase interface {
|
||||
// CreateCommentItem 建立 Comment
|
||||
CreateCommentItem(ctx context.Context, info CreateCommentDocs) error
|
||||
// GetCommentItem 取得CommentItem
|
||||
GetCommentItem(ctx context.Context, id string) (*CommentDocs, error)
|
||||
// ListComment 取得 CommentItem 列表
|
||||
ListComment(ctx context.Context, req ListCommentRequest) ([]*CommentDocs, int64, error)
|
||||
// RemoveCommentItem 移除 CommentItem 列表
|
||||
RemoveCommentItem(ctx context.Context, id string) error
|
||||
// UpdateCommentMessage 更新
|
||||
UpdateCommentMessage(ctx context.Context, id string, message string) error
|
||||
}
|
||||
|
||||
type CreateCommentDocs struct {
|
||||
UID string `bson:"uid"` // 留言的使用者的 ID
|
||||
ReferenceID string `bson:"reference_id"` // 參考的 id ex product_id or product_item_id 之類的
|
||||
ParentCommentID string `bson:"parent_comment_id"` // 父留言 id 沒有就空白
|
||||
Message string `bson:"message"` // 留言內容
|
||||
}
|
||||
|
||||
type CommentDocs struct {
|
||||
ID string `json:"id"`
|
||||
UID string `json:"uid"` // 留言的使用者的 ID
|
||||
ReferenceID string `json:"reference_id"` // 參考的 id ex product_id or product_item_id 之類的
|
||||
ParentCommentID string `json:"parent_comment_id"` // 父留言 id 沒有就空白
|
||||
Message string `json:"message"` // 留言內容
|
||||
Replies []*CommentDocs `json:"replies"` // 子留言
|
||||
UpdatedAt int64 `json:"updated_at"` // 更新時間
|
||||
CreatedAt int64 `json:"created_at"` // 建立時間
|
||||
}
|
||||
|
||||
type ListCommentRequest struct {
|
||||
PageSize int64
|
||||
PageIndex int64
|
||||
ReferenceID *string
|
||||
ParentID *string
|
||||
IsSub bool
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: ./pkg/domain/repository/comment.go
|
||||
//
|
||||
// Generated by this command:
|
||||
//
|
||||
// mockgen -source=./pkg/domain/repository/comment.go -destination=./pkg/mock/repository/comment.go -package=mock
|
||||
//
|
||||
|
||||
// Package mock is a generated GoMock package.
|
||||
package mock
|
||||
|
||||
import (
|
||||
entity "app-cloudep-comment-server/pkg/domain/entity"
|
||||
repository "app-cloudep-comment-server/pkg/domain/repository"
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockCommentRepository is a mock of CommentRepository interface.
|
||||
type MockCommentRepository struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockCommentRepositoryMockRecorder
|
||||
isgomock struct{}
|
||||
}
|
||||
|
||||
// MockCommentRepositoryMockRecorder is the mock recorder for MockCommentRepository.
|
||||
type MockCommentRepositoryMockRecorder struct {
|
||||
mock *MockCommentRepository
|
||||
}
|
||||
|
||||
// NewMockCommentRepository creates a new mock instance.
|
||||
func NewMockCommentRepository(ctrl *gomock.Controller) *MockCommentRepository {
|
||||
mock := &MockCommentRepository{ctrl: ctrl}
|
||||
mock.recorder = &MockCommentRepositoryMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockCommentRepository) EXPECT() *MockCommentRepositoryMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// CreateComment mocks base method.
|
||||
func (m *MockCommentRepository) CreateComment(ctx context.Context, comment *entity.Comments) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateComment", ctx, comment)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// CreateComment indicates an expected call of CreateComment.
|
||||
func (mr *MockCommentRepositoryMockRecorder) CreateComment(ctx, comment any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateComment", reflect.TypeOf((*MockCommentRepository)(nil).CreateComment), ctx, comment)
|
||||
}
|
||||
|
||||
// DeleteCommentByID mocks base method.
|
||||
func (m *MockCommentRepository) DeleteCommentByID(ctx context.Context, id string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteCommentByID", ctx, id)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeleteCommentByID indicates an expected call of DeleteCommentByID.
|
||||
func (mr *MockCommentRepositoryMockRecorder) DeleteCommentByID(ctx, id any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCommentByID", reflect.TypeOf((*MockCommentRepository)(nil).DeleteCommentByID), ctx, id)
|
||||
}
|
||||
|
||||
// ListComments mocks base method.
|
||||
func (m *MockCommentRepository) ListComments(ctx context.Context, req repository.ListCommentRequest) ([]*entity.Comments, int64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ListComments", ctx, req)
|
||||
ret0, _ := ret[0].([]*entity.Comments)
|
||||
ret1, _ := ret[1].(int64)
|
||||
ret2, _ := ret[2].(error)
|
||||
return ret0, ret1, ret2
|
||||
}
|
||||
|
||||
// ListComments indicates an expected call of ListComments.
|
||||
func (mr *MockCommentRepositoryMockRecorder) ListComments(ctx, req any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListComments", reflect.TypeOf((*MockCommentRepository)(nil).ListComments), ctx, req)
|
||||
}
|
||||
|
||||
// UpdateCommentMessage mocks base method.
|
||||
func (m *MockCommentRepository) UpdateCommentMessage(ctx context.Context, id, message string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpdateCommentMessage", ctx, id, message)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// UpdateCommentMessage indicates an expected call of UpdateCommentMessage.
|
||||
func (mr *MockCommentRepositoryMockRecorder) UpdateCommentMessage(ctx, id, message any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateCommentMessage", reflect.TypeOf((*MockCommentRepository)(nil).UpdateCommentMessage), ctx, id, message)
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain"
|
||||
"app-cloudep-comment-server/pkg/domain/entity"
|
||||
"app-cloudep-comment-server/pkg/domain/repository"
|
||||
mgo "code.30cm.net/digimon/library-go/mongo"
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"time"
|
||||
)
|
||||
|
||||
type CommentRepositoryParam struct {
|
||||
Conf *mgo.Conf
|
||||
CacheConf cache.CacheConf
|
||||
DBOpts []mon.Option
|
||||
CacheOpts []cache.Option
|
||||
}
|
||||
|
||||
type CommentRepository struct {
|
||||
DB mgo.DocumentDBWithCacheUseCase
|
||||
}
|
||||
|
||||
func MustCommentRepository(param CommentRepositoryParam) repository.CommentRepository {
|
||||
e := entity.Comments{}
|
||||
documentDB, err := mgo.MustDocumentDBWithCache(
|
||||
param.Conf,
|
||||
e.CollectionName(),
|
||||
param.CacheConf,
|
||||
param.DBOpts,
|
||||
param.CacheOpts,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &CommentRepository{
|
||||
DB: documentDB,
|
||||
}
|
||||
}
|
||||
|
||||
func (repo *CommentRepository) CreateComment(ctx context.Context, comment *entity.Comments) error {
|
||||
now := time.Now().UTC().UnixNano()
|
||||
if comment.ID.IsZero() {
|
||||
comment.ID = primitive.NewObjectID()
|
||||
comment.CreatedAt = now
|
||||
comment.UpdatedAt = now
|
||||
}
|
||||
|
||||
rk := domain.GetCommentRedisKey(comment.ID.Hex())
|
||||
_, err := repo.DB.InsertOne(ctx, rk, comment)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (repo *CommentRepository) DeleteCommentByID(ctx context.Context, id string) error {
|
||||
oid, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return ErrInvalidObjectID
|
||||
}
|
||||
|
||||
rk := domain.GetCommentRedisKey(id)
|
||||
_, err = repo.DB.DeleteOne(ctx, rk, bson.M{"_id": oid})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (repo *CommentRepository) UpdateCommentMessage(ctx context.Context, id string, message string) error {
|
||||
// 驗證 ObjectID 是否有效
|
||||
oid, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return ErrInvalidObjectID
|
||||
}
|
||||
|
||||
// 初始化更新字段
|
||||
updates := bson.M{
|
||||
"message": message, // 更新留言內容
|
||||
"updated_at": time.Now().UTC().UnixNano(), // 更新時間
|
||||
}
|
||||
|
||||
// 查詢條件:根據 _id 查詢
|
||||
filter := bson.M{
|
||||
"_id": oid,
|
||||
}
|
||||
|
||||
rk := domain.GetCommentRedisKey(id)
|
||||
// 執行更新操作
|
||||
res, err := repo.DB.UpdateOne(ctx, rk, filter, bson.M{"$set": updates})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 驗證是否有匹配的記錄被更新
|
||||
if res.MatchedCount == 0 {
|
||||
return ErrNotFound
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *CommentRepository) ListComments(ctx context.Context, req repository.ListCommentRequest) ([]*entity.Comments, int64, error) {
|
||||
// 構建查詢過濾器
|
||||
filter := bson.M{}
|
||||
if req.ParentID != nil {
|
||||
filter["parent_comment_id"] = req.ParentID
|
||||
}
|
||||
if req.ReferenceID != nil {
|
||||
filter["reference_id"] = req.ReferenceID
|
||||
}
|
||||
|
||||
// 設置排序選項
|
||||
opts := options.Find().SetSkip((req.PageIndex - 1) * req.PageSize).SetLimit(req.PageSize)
|
||||
opts.SetSort(bson.D{{Key: "created_at", Value: -1}})
|
||||
|
||||
// 查詢符合條件的總數
|
||||
count, err := repo.DB.GetClient().CountDocuments(ctx, filter)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 執行查詢並獲取結果
|
||||
var data []*entity.Comments
|
||||
err = repo.DB.GetClient().Find(ctx, &data, filter, opts)
|
||||
|
||||
switch {
|
||||
case err == nil:
|
||||
return data, count, nil
|
||||
case errors.Is(err, mon.ErrNotFound):
|
||||
return nil, 0, ErrNotFound
|
||||
default:
|
||||
return nil, 0, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,385 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain/entity"
|
||||
"app-cloudep-comment-server/pkg/domain/repository"
|
||||
mgo "code.30cm.net/digimon/library-go/mongo"
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/alicebob/miniredis/v2"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func SetupTestCommentRepository(db string) (repository.CommentRepository, func(), error) {
|
||||
h, p, tearDown, err := startMongoContainer()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
s, _ := miniredis.Run()
|
||||
|
||||
conf := &mgo.Conf{
|
||||
Schema: Schema,
|
||||
Host: fmt.Sprintf("%s:%s", h, p),
|
||||
Database: db,
|
||||
MaxStaleness: 300,
|
||||
MaxPoolSize: 100,
|
||||
MinPoolSize: 100,
|
||||
MaxConnIdleTime: 300,
|
||||
Compressors: []string{},
|
||||
EnableStandardReadWriteSplitMode: false,
|
||||
ConnectTimeoutMs: 3000,
|
||||
}
|
||||
|
||||
cacheConf := cache.CacheConf{
|
||||
cache.NodeConf{
|
||||
RedisConf: redis.RedisConf{
|
||||
Host: s.Addr(),
|
||||
Type: redis.NodeType,
|
||||
},
|
||||
Weight: 100,
|
||||
},
|
||||
}
|
||||
|
||||
cacheOpts := []cache.Option{
|
||||
cache.WithExpiry(1000 * time.Microsecond),
|
||||
cache.WithNotFoundExpiry(1000 * time.Microsecond),
|
||||
}
|
||||
|
||||
dbOpts := []mon.Option{
|
||||
mgo.SetCustomDecimalType(),
|
||||
mgo.InitMongoOptions(*conf),
|
||||
}
|
||||
|
||||
param := CommentRepositoryParam{
|
||||
Conf: conf,
|
||||
CacheConf: cacheConf,
|
||||
CacheOpts: cacheOpts,
|
||||
DBOpts: dbOpts,
|
||||
}
|
||||
repo := MustCommentRepository(param)
|
||||
//_, _ = repo.Index20241230001UP(context.Background())
|
||||
|
||||
return repo, tearDown, nil
|
||||
}
|
||||
|
||||
func TestCommentRepository_CreateCommentItem(t *testing.T) {
|
||||
repo, tearDown, err := SetupTestCommentRepository("testDB")
|
||||
assert.NoError(t, err)
|
||||
defer tearDown()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input *entity.Comments
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "Valid comment creation",
|
||||
input: &entity.Comments{
|
||||
UID: "test-uid",
|
||||
ReferenceID: "ref-001",
|
||||
ParentCommentID: "",
|
||||
Message: "This is a test comment",
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Comment with existing ID",
|
||||
input: &entity.Comments{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: "test-uid",
|
||||
ReferenceID: "ref-002",
|
||||
ParentCommentID: "",
|
||||
Message: "This is another test comment",
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := repo.CreateComment(context.Background(), tt.input)
|
||||
|
||||
if tt.expectError {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 驗證插入的數據是否存在於資料庫中
|
||||
result, _, err := repo.ListComments(context.Background(), repository.ListCommentRequest{
|
||||
PageSize: 10,
|
||||
PageIndex: 1,
|
||||
ReferenceID: &tt.input.ReferenceID,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, result, "應該能找到插入的留言")
|
||||
assert.Equal(t, tt.input.UID, result[0].UID, "UID 應該匹配")
|
||||
assert.Equal(t, tt.input.ReferenceID, result[0].ReferenceID, "ReferenceID 應該匹配")
|
||||
assert.Equal(t, tt.input.Message, result[0].Message, "Message 應該匹配")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommentRepository_ListComment(t *testing.T) {
|
||||
repo, tearDown, err := SetupTestCommentRepository("testDB")
|
||||
assert.NoError(t, err)
|
||||
defer tearDown()
|
||||
|
||||
// 插入測試留言資料
|
||||
testComments := []entity.Comments{
|
||||
{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: "user1",
|
||||
ReferenceID: "ref-001",
|
||||
ParentCommentID: "",
|
||||
Message: "This is a parent comment",
|
||||
CreatedAt: time.Now().Add(-10 * time.Minute).UnixNano(),
|
||||
},
|
||||
{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: "user2",
|
||||
ReferenceID: "ref-001",
|
||||
ParentCommentID: "",
|
||||
Message: "This is another parent comment",
|
||||
CreatedAt: time.Now().Add(-5 * time.Minute).UnixNano(),
|
||||
},
|
||||
{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: "user3",
|
||||
ReferenceID: "ref-002",
|
||||
ParentCommentID: "parent-id",
|
||||
Message: "This is a child comment",
|
||||
CreatedAt: time.Now().Add(-3 * time.Minute).UnixNano(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, comment := range testComments {
|
||||
err := repo.CreateComment(context.Background(), &comment)
|
||||
assert.NoError(t, err, "插入應成功")
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
req repository.ListCommentRequest
|
||||
expectedTotal int64
|
||||
expectedIDs []primitive.ObjectID
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "List all comments for ReferenceID",
|
||||
req: repository.ListCommentRequest{
|
||||
ReferenceID: proto.String("ref-001"),
|
||||
PageIndex: 1,
|
||||
PageSize: 10,
|
||||
},
|
||||
expectedTotal: 2,
|
||||
expectedIDs: []primitive.ObjectID{testComments[1].ID, testComments[0].ID}, // 根據 CreatedAt 排序
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "List child comments by ParentID",
|
||||
req: repository.ListCommentRequest{
|
||||
ParentID: proto.String("parent-id"),
|
||||
PageIndex: 1,
|
||||
PageSize: 10,
|
||||
},
|
||||
expectedTotal: 1,
|
||||
expectedIDs: []primitive.ObjectID{testComments[2].ID},
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Pagination test",
|
||||
req: repository.ListCommentRequest{
|
||||
ReferenceID: proto.String("ref-001"),
|
||||
PageIndex: 1,
|
||||
PageSize: 1,
|
||||
},
|
||||
expectedTotal: 2,
|
||||
expectedIDs: []primitive.ObjectID{testComments[1].ID}, // 第一頁應只有一條
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "No matching comments",
|
||||
req: repository.ListCommentRequest{
|
||||
ReferenceID: proto.String("non-existent"),
|
||||
PageIndex: 1,
|
||||
PageSize: 10,
|
||||
},
|
||||
expectedTotal: 0,
|
||||
expectedIDs: nil,
|
||||
expectError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
comments, total, err := repo.ListComments(context.Background(), tt.req)
|
||||
|
||||
if tt.expectError {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.expectedTotal, total, "返回的總數應該正確")
|
||||
assert.Len(t, comments, len(tt.expectedIDs), "返回的留言數量應該正確")
|
||||
|
||||
for i, comment := range comments {
|
||||
assert.Equal(t, tt.expectedIDs[i], comment.ID, "留言 ID 應匹配")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommentRepository_DeleteCommentByID(t *testing.T) {
|
||||
repo, tearDown, err := SetupTestCommentRepository("testDB")
|
||||
assert.NoError(t, err)
|
||||
defer tearDown()
|
||||
|
||||
// 插入測試留言
|
||||
comment := &entity.Comments{
|
||||
UID: "test-uid",
|
||||
ReferenceID: "ref-001",
|
||||
ParentCommentID: "",
|
||||
Message: "This is a test comment",
|
||||
}
|
||||
err = repo.CreateComment(context.Background(), comment)
|
||||
assert.NoError(t, err, "插入應成功")
|
||||
|
||||
invalidID := "invalid-id" // 無效的 ObjectID 格式
|
||||
nonExistentID := primitive.NewObjectID().Hex() // 不存在的 ID
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
id string
|
||||
expectError bool
|
||||
expectedErr error
|
||||
expectedRes int64
|
||||
}{
|
||||
{
|
||||
name: "Valid delete",
|
||||
id: comment.ID.Hex(),
|
||||
expectError: false,
|
||||
expectedErr: ErrNotFound,
|
||||
expectedRes: 1,
|
||||
},
|
||||
{
|
||||
name: "Invalid ID format",
|
||||
id: invalidID,
|
||||
expectError: true,
|
||||
expectedErr: ErrInvalidObjectID,
|
||||
expectedRes: 0,
|
||||
},
|
||||
{
|
||||
name: "Non-existent ID",
|
||||
id: nonExistentID,
|
||||
expectError: false,
|
||||
expectedRes: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// 調用刪除方法
|
||||
err := repo.DeleteCommentByID(context.Background(), tt.id)
|
||||
|
||||
if tt.expectError {
|
||||
// 驗證錯誤是否正確
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, tt.expectedErr, err)
|
||||
} else {
|
||||
// 驗證刪除是否成功
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 驗證刪除後是否還存在
|
||||
// 驗證插入的數據是否存在於資料庫中
|
||||
result, _, err := repo.ListComments(context.Background(), repository.ListCommentRequest{
|
||||
PageSize: 10,
|
||||
PageIndex: 1,
|
||||
ReferenceID: &comment.ReferenceID,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, result, "留言應該被刪除或不存在")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommentRepository_UpdateCommentMessage(t *testing.T) {
|
||||
repo, tearDown, err := SetupTestCommentRepository("testDB")
|
||||
assert.NoError(t, err)
|
||||
defer tearDown()
|
||||
|
||||
// 插入測試留言
|
||||
comment := &entity.Comments{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: "user123",
|
||||
Message: "Original message",
|
||||
ReferenceID: "ref-001",
|
||||
CreatedAt: time.Now().UTC().UnixNano(),
|
||||
UpdatedAt: time.Now().UTC().UnixNano(),
|
||||
}
|
||||
err = repo.CreateComment(context.Background(), comment)
|
||||
assert.NoError(t, err, "插入應成功")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
id string
|
||||
newMessage string
|
||||
expectError bool
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
name: "Valid update",
|
||||
id: comment.ID.Hex(),
|
||||
newMessage: "Updated message",
|
||||
expectError: false,
|
||||
},
|
||||
{
|
||||
name: "Invalid ObjectID",
|
||||
id: "invalid-id",
|
||||
newMessage: "Should not update",
|
||||
expectError: true,
|
||||
expectedError: ErrInvalidObjectID,
|
||||
},
|
||||
{
|
||||
name: "Comment not found",
|
||||
id: primitive.NewObjectID().Hex(),
|
||||
newMessage: "Should not update",
|
||||
expectError: true,
|
||||
expectedError: ErrNotFound,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := repo.UpdateCommentMessage(context.Background(), tt.id, tt.newMessage)
|
||||
|
||||
if tt.expectError {
|
||||
// 驗證錯誤是否正確
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, tt.expectedError, err)
|
||||
} else {
|
||||
// 驗證無錯誤返回
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 驗證刪除後是否還存在
|
||||
// 驗證插入的數據是否存在於資料庫中
|
||||
result, _, err := repo.ListComments(context.Background(), repository.ListCommentRequest{
|
||||
PageSize: 10,
|
||||
PageIndex: 1,
|
||||
ReferenceID: &comment.ReferenceID,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, result, "更新後的留言應存在")
|
||||
assert.Equal(t, tt.newMessage, result[0].Message, "留言內容應更新")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotFound = mon.ErrNotFound
|
||||
ErrInvalidObjectID = errors.New("invalid objectId")
|
||||
)
|
|
@ -0,0 +1,52 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/testcontainers/testcontainers-go"
|
||||
"github.com/testcontainers/testcontainers-go/wait"
|
||||
)
|
||||
|
||||
const (
|
||||
Host = "127.0.0.1"
|
||||
Port = "27017"
|
||||
Schema = "mongodb"
|
||||
)
|
||||
|
||||
func startMongoContainer() (string, string, func(), error) {
|
||||
ctx := context.Background()
|
||||
|
||||
req := testcontainers.ContainerRequest{
|
||||
Image: "mongo:latest",
|
||||
ExposedPorts: []string{"27017/tcp"},
|
||||
WaitingFor: wait.ForListeningPort("27017/tcp"),
|
||||
}
|
||||
|
||||
mongoC, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
|
||||
ContainerRequest: req,
|
||||
Started: true,
|
||||
})
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
|
||||
port, err := mongoC.MappedPort(ctx, Port)
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
|
||||
host, err := mongoC.Host(ctx)
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("mongodb://%s:%s", host, port.Port())
|
||||
tearDown := func() {
|
||||
mongoC.Terminate(ctx)
|
||||
}
|
||||
|
||||
fmt.Printf("Connecting to %s\n", uri)
|
||||
|
||||
return host, port.Port(), tearDown, nil
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain"
|
||||
"app-cloudep-comment-server/pkg/domain/comment"
|
||||
"app-cloudep-comment-server/pkg/domain/entity"
|
||||
"app-cloudep-comment-server/pkg/domain/repository"
|
||||
"app-cloudep-comment-server/pkg/domain/usecase"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"github.com/golang/snappy"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"code.30cm.net/digimon/library-go/errs"
|
||||
"code.30cm.net/digimon/library-go/errs/code"
|
||||
)
|
||||
|
||||
type CommentUseCaseParam struct {
|
||||
Comment repository.CommentRepository
|
||||
}
|
||||
|
||||
type CommentUseCase struct {
|
||||
CommentUseCaseParam
|
||||
}
|
||||
|
||||
func MustCommentUseCase(param CommentUseCaseParam) usecase.CommentUseCase {
|
||||
return &CommentUseCase{
|
||||
param,
|
||||
}
|
||||
}
|
||||
|
||||
func (use *CommentUseCase) CreateCommentItem(ctx context.Context, info usecase.CreateCommentDocs) error {
|
||||
insert := &entity.Comments{
|
||||
UID: info.UID,
|
||||
ReferenceID: info.ReferenceID,
|
||||
Level: comment.TopLevelComment,
|
||||
}
|
||||
snappyContent := snappy.Encode(nil, []byte(info.Message))
|
||||
insert.Message = base64.StdEncoding.EncodeToString(snappyContent)
|
||||
|
||||
if info.ParentCommentID != "" {
|
||||
insert.ParentCommentID = info.ParentCommentID
|
||||
insert.Level = comment.SubLevelComment
|
||||
}
|
||||
|
||||
err := use.Comment.CreateComment(ctx, insert)
|
||||
if err != nil {
|
||||
return errs.DatabaseErrorWithScopeL(
|
||||
code.CloudEPComment,
|
||||
domain.CreateCommentErrorCode,
|
||||
logx.WithContext(ctx),
|
||||
[]logx.LogField{
|
||||
{Key: "info", Value: info},
|
||||
{Key: "func", Value: "Comment.CreateComment"},
|
||||
{Key: "err", Value: err.Error()},
|
||||
},
|
||||
"failed to create comment").Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (use *CommentUseCase) GetCommentItem(ctx context.Context, id string) (*usecase.CommentDocs, error) {
|
||||
item, _, err := use.Comment.ListComments(ctx, repository.ListCommentRequest{
|
||||
ReferenceID: &id,
|
||||
PageIndex: 1,
|
||||
PageSize: 20,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errs.DatabaseErrorWithScopeL(
|
||||
code.CloudEPComment,
|
||||
domain.GetCommentErrorCode,
|
||||
logx.WithContext(ctx),
|
||||
[]logx.LogField{
|
||||
{Key: "id", Value: id},
|
||||
{Key: "func", Value: "Comment.ListComments"},
|
||||
{Key: "err", Value: err.Error()},
|
||||
},
|
||||
"failed to get comment").Wrap(err)
|
||||
}
|
||||
|
||||
decodeB64Content, _ := base64.StdEncoding.DecodeString(item[0].Message)
|
||||
snappyContent, _ := snappy.Decode(nil, decodeB64Content)
|
||||
item[0].Message = string(snappyContent)
|
||||
|
||||
return &usecase.CommentDocs{
|
||||
ID: item[0].ID.Hex(),
|
||||
UID: item[0].UID,
|
||||
ReferenceID: item[0].ReferenceID,
|
||||
ParentCommentID: item[0].ParentCommentID,
|
||||
Message: item[0].Message,
|
||||
UpdatedAt: item[0].UpdatedAt,
|
||||
CreatedAt: item[0].CreatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (use *CommentUseCase) UpdateCommentMessage(ctx context.Context, id string, message string) error {
|
||||
err := use.Comment.UpdateCommentMessage(ctx, id, message)
|
||||
if err != nil {
|
||||
return errs.DatabaseErrorWithScopeL(
|
||||
code.CloudEPComment,
|
||||
domain.UpdateCommentErrorCode,
|
||||
logx.WithContext(ctx),
|
||||
[]logx.LogField{
|
||||
{Key: "id", Value: id},
|
||||
{Key: "func", Value: "Comment.UpdateCommentMessage"},
|
||||
{Key: "err", Value: err.Error()},
|
||||
},
|
||||
"failed to update comment").Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (use *CommentUseCase) RemoveCommentItem(ctx context.Context, id string) error {
|
||||
// 也需要把子留言給刪除
|
||||
err := use.Comment.DeleteCommentByID(ctx, id)
|
||||
if err != nil {
|
||||
return errs.DatabaseErrorWithScopeL(
|
||||
code.CloudEPComment,
|
||||
domain.DelCommentErrorCode,
|
||||
logx.WithContext(ctx),
|
||||
[]logx.LogField{
|
||||
{Key: "id", Value: id},
|
||||
{Key: "func", Value: "Comment.DeleteCommentByID"},
|
||||
{Key: "err", Value: err.Error()},
|
||||
},
|
||||
"failed to del comment").Wrap(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (use *CommentUseCase) ListComment(ctx context.Context, req usecase.ListCommentRequest) ([]*usecase.CommentDocs, int64, error) {
|
||||
// 查詢主層留言
|
||||
comments, total, err := use.Comment.ListComments(ctx, repository.ListCommentRequest{
|
||||
ParentID: req.ParentID,
|
||||
PageSize: req.PageSize,
|
||||
PageIndex: req.PageIndex,
|
||||
ReferenceID: req.ReferenceID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, 0, errs.DatabaseErrorWithScopeL(
|
||||
code.CloudEPComment,
|
||||
domain.ListCommentErrorCode,
|
||||
logx.WithContext(ctx),
|
||||
[]logx.LogField{
|
||||
{Key: "req", Value: req},
|
||||
{Key: "func", Value: "Comment.ListComments"},
|
||||
{Key: "err", Value: err.Error()},
|
||||
},
|
||||
"failed to list comment").Wrap(err)
|
||||
}
|
||||
|
||||
// 批量構建子留言
|
||||
replyMap, err := use.buildReplies(ctx, comments)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
// 組裝結果
|
||||
results := make([]*usecase.CommentDocs, 0, len(comments))
|
||||
for _, item := range comments {
|
||||
decodedMessage, err := decodeMessage(item.Message)
|
||||
if err != nil {
|
||||
logx.WithContext(ctx).Errorf("Failed to decode message: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
results = append(results, &usecase.CommentDocs{
|
||||
ID: item.ID.Hex(),
|
||||
UID: item.UID,
|
||||
ReferenceID: item.ReferenceID,
|
||||
ParentCommentID: item.ParentCommentID,
|
||||
Message: decodedMessage,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
CreatedAt: item.CreatedAt,
|
||||
Replies: replyMap[item.ID.Hex()],
|
||||
})
|
||||
}
|
||||
|
||||
return results, total, nil
|
||||
}
|
||||
|
||||
func (use *CommentUseCase) buildReplies(ctx context.Context, parentComments []*entity.Comments) (map[string][]*usecase.CommentDocs, error) {
|
||||
// 分組
|
||||
replyMap := make(map[string][]*usecase.CommentDocs)
|
||||
// 查詢子留言
|
||||
for _, item := range parentComments {
|
||||
id := item.ID.Hex()
|
||||
subComments, _, err := use.Comment.ListComments(ctx, repository.ListCommentRequest{
|
||||
ParentID: &id,
|
||||
PageSize: 20,
|
||||
PageIndex: 1, // 可調整分頁大小
|
||||
})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, sub := range subComments {
|
||||
decodedMessage, err := decodeMessage(sub.Message)
|
||||
if err != nil {
|
||||
logx.WithContext(ctx).Errorf("Failed to decode message: %v", err)
|
||||
continue
|
||||
}
|
||||
replyMap[sub.ParentCommentID] = append(replyMap[sub.ParentCommentID], &usecase.CommentDocs{
|
||||
ID: sub.ID.Hex(),
|
||||
UID: sub.UID,
|
||||
ReferenceID: sub.ReferenceID,
|
||||
ParentCommentID: sub.ParentCommentID,
|
||||
Message: decodedMessage,
|
||||
UpdatedAt: sub.UpdatedAt,
|
||||
CreatedAt: sub.CreatedAt,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return replyMap, nil
|
||||
}
|
||||
|
||||
func decodeMessage(encodedMessage string) (string, error) {
|
||||
// Base64 解碼
|
||||
decodedBase64, err := base64.StdEncoding.DecodeString(encodedMessage)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to decode Base64: %w", err)
|
||||
}
|
||||
|
||||
// Snappy 解碼
|
||||
decodedSnappy, err := snappy.Decode(nil, decodedBase64)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to decode Snappy: %w", err)
|
||||
}
|
||||
|
||||
return string(decodedSnappy), nil
|
||||
}
|
|
@ -0,0 +1,479 @@
|
|||
package usecase
|
||||
|
||||
import (
|
||||
"app-cloudep-comment-server/pkg/domain/comment"
|
||||
"app-cloudep-comment-server/pkg/domain/entity"
|
||||
"app-cloudep-comment-server/pkg/domain/repository"
|
||||
"app-cloudep-comment-server/pkg/domain/usecase"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"github.com/golang/snappy"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.uber.org/mock/gomock"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
mockRepo "app-cloudep-comment-server/pkg/mock/repository"
|
||||
err "app-cloudep-comment-server/pkg/repository"
|
||||
)
|
||||
|
||||
func TestCommentUseCase_CreateCommentItem(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
defer mockCtrl.Finish()
|
||||
|
||||
mockCommentRepository := mockRepo.NewMockCommentRepository(mockCtrl)
|
||||
|
||||
uc := MustCommentUseCase(CommentUseCaseParam{
|
||||
Comment: mockCommentRepository,
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
req usecase.CreateCommentDocs
|
||||
mockSetup func()
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "successfully create top-level comment",
|
||||
req: usecase.CreateCommentDocs{
|
||||
UID: "user-123",
|
||||
ReferenceID: "ref-001",
|
||||
Message: "This is a top-level comment",
|
||||
},
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
CreateComment(gomock.Any(), gomock.Any()).
|
||||
DoAndReturn(func(ctx context.Context, e *entity.Comments) error {
|
||||
// 驗證插入內容是否正確
|
||||
assert.Equal(t, "user-123", e.UID)
|
||||
assert.Equal(t, "ref-001", e.ReferenceID)
|
||||
assert.Equal(t, comment.TopLevelComment, e.Level)
|
||||
return nil
|
||||
})
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "successfully create sub-level comment",
|
||||
req: usecase.CreateCommentDocs{
|
||||
UID: "user-456",
|
||||
ReferenceID: "ref-002",
|
||||
ParentCommentID: "parent-001",
|
||||
Message: "This is a sub-level comment",
|
||||
},
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
CreateComment(gomock.Any(), gomock.Any()).
|
||||
DoAndReturn(func(ctx context.Context, e *entity.Comments) error {
|
||||
// 驗證插入內容是否正確
|
||||
assert.Equal(t, "user-456", e.UID)
|
||||
assert.Equal(t, "ref-002", e.ReferenceID)
|
||||
assert.Equal(t, "parent-001", e.ParentCommentID)
|
||||
assert.Equal(t, comment.SubLevelComment, e.Level)
|
||||
return nil
|
||||
})
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "failed to create comment due to repository error",
|
||||
req: usecase.CreateCommentDocs{
|
||||
UID: "user-789",
|
||||
ReferenceID: "ref-003",
|
||||
Message: "This is a failing comment",
|
||||
},
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
CreateComment(gomock.Any(), gomock.Any()).
|
||||
Return(errors.New("database error"))
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.mockSetup()
|
||||
err := uc.CreateCommentItem(context.Background(), tt.req)
|
||||
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
if err != nil {
|
||||
assert.Contains(t, err.Error(), "failed to create comment")
|
||||
}
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommentUseCase_GetCommentItem(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
defer mockCtrl.Finish()
|
||||
|
||||
mockCommentRepository := mockRepo.NewMockCommentRepository(mockCtrl)
|
||||
|
||||
uc := MustCommentUseCase(CommentUseCaseParam{
|
||||
Comment: mockCommentRepository,
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
id string
|
||||
mockSetup func()
|
||||
wantErr bool
|
||||
expected *usecase.CommentDocs
|
||||
}{
|
||||
{
|
||||
name: "successfully get comment item",
|
||||
id: "64a1f2e9347e1a001d345678",
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
ListComments(gomock.Any(), gomock.Any()).
|
||||
DoAndReturn(func(ctx context.Context, req repository.ListCommentRequest) ([]*entity.Comments, int64, error) {
|
||||
assert.Equal(t, "64a1f2e9347e1a001d345678", *req.ReferenceID)
|
||||
return []*entity.Comments{
|
||||
{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: "user-123",
|
||||
ReferenceID: "64a1f2e9347e1a001d345678",
|
||||
ParentCommentID: "",
|
||||
Message: base64.StdEncoding.EncodeToString(snappy.Encode(nil, []byte("This is a test comment"))),
|
||||
UpdatedAt: time.Now().UTC().UnixNano(),
|
||||
CreatedAt: time.Now().UTC().UnixNano(),
|
||||
},
|
||||
}, 1, nil
|
||||
})
|
||||
},
|
||||
wantErr: false,
|
||||
expected: &usecase.CommentDocs{
|
||||
UID: "user-123",
|
||||
ReferenceID: "64a1f2e9347e1a001d345678",
|
||||
ParentCommentID: "",
|
||||
Message: "This is a test comment",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "comment not found",
|
||||
id: "64a1f2e9347e1a001d345679",
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
ListComments(gomock.Any(), gomock.Any()).
|
||||
Return([]*entity.Comments{}, int64(0), err.ErrNotFound)
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "database error",
|
||||
id: "64a1f2e9347e1a001d345680",
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
ListComments(gomock.Any(), gomock.Any()).
|
||||
Return([]*entity.Comments{}, int64(0), errors.New("database error"))
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.mockSetup()
|
||||
comment, err := uc.GetCommentItem(context.Background(), tt.id)
|
||||
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, comment)
|
||||
assert.Equal(t, tt.expected.UID, comment.UID)
|
||||
assert.Equal(t, tt.expected.ReferenceID, comment.ReferenceID)
|
||||
assert.Equal(t, tt.expected.Message, comment.Message)
|
||||
assert.Equal(t, tt.expected.ParentCommentID, comment.ParentCommentID)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommentUseCase_UpdateCommentMessage(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
defer mockCtrl.Finish()
|
||||
|
||||
// Mock Repository
|
||||
mockCommentRepository := mockRepo.NewMockCommentRepository(mockCtrl)
|
||||
|
||||
// UseCase Initialization
|
||||
uc := MustCommentUseCase(CommentUseCaseParam{
|
||||
Comment: mockCommentRepository,
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
id string
|
||||
message string
|
||||
mockSetup func()
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "successfully update comment message",
|
||||
id: "64a1f2e9347e1a001d345678", // Valid ObjectID
|
||||
message: "Updated comment message",
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
UpdateCommentMessage(gomock.Any(), "64a1f2e9347e1a001d345678", "Updated comment message").
|
||||
Return(nil)
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid ObjectID format",
|
||||
id: "invalid-id", // Invalid ObjectID
|
||||
message: "Invalid ID test",
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
UpdateCommentMessage(gomock.Any(), "invalid-id", "Invalid ID test").
|
||||
Return(err.ErrInvalidObjectID)
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "comment not found",
|
||||
id: "64a1f2e9347e1a001d345679", // Non-existent ObjectID
|
||||
message: "Non-existent comment",
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
UpdateCommentMessage(gomock.Any(), "64a1f2e9347e1a001d345679", "Non-existent comment").
|
||||
Return(err.ErrNotFound)
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "database error while updating",
|
||||
id: "64a1f2e9347e1a001d345680",
|
||||
message: "Database error test",
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
UpdateCommentMessage(gomock.Any(), "64a1f2e9347e1a001d345680", "Database error test").
|
||||
Return(errors.New("database error"))
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Mock Setup
|
||||
tt.mockSetup()
|
||||
|
||||
// Execute UseCase
|
||||
err := uc.UpdateCommentMessage(context.Background(), tt.id, tt.message)
|
||||
|
||||
// Assert Results
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
if err != nil {
|
||||
assert.Contains(t, err.Error(), "failed to update comment")
|
||||
}
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommentUseCase_RemoveCommentItem(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
defer mockCtrl.Finish()
|
||||
|
||||
// Mock Repository
|
||||
mockCommentRepository := mockRepo.NewMockCommentRepository(mockCtrl)
|
||||
|
||||
// UseCase Initialization
|
||||
uc := MustCommentUseCase(CommentUseCaseParam{
|
||||
Comment: mockCommentRepository,
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
id string
|
||||
mockSetup func()
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "successfully remove comment item",
|
||||
id: "64a1f2e9347e1a001d345678", // Valid ObjectID
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
DeleteCommentByID(gomock.Any(), "64a1f2e9347e1a001d345678").
|
||||
Return(nil)
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid ObjectID format",
|
||||
id: "invalid-id", // Invalid ObjectID
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
DeleteCommentByID(gomock.Any(), "invalid-id").
|
||||
Return(err.ErrInvalidObjectID)
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "comment not found",
|
||||
id: "64a1f2e9347e1a001d345679", // Non-existent ObjectID
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
DeleteCommentByID(gomock.Any(), "64a1f2e9347e1a001d345679").
|
||||
Return(err.ErrNotFound)
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "database error while deleting",
|
||||
id: "64a1f2e9347e1a001d345680",
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
DeleteCommentByID(gomock.Any(), "64a1f2e9347e1a001d345680").
|
||||
Return(errors.New("database error"))
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Mock Setup
|
||||
tt.mockSetup()
|
||||
|
||||
// Execute UseCase
|
||||
err := uc.RemoveCommentItem(context.Background(), tt.id)
|
||||
|
||||
// Assert Results
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
if err != nil {
|
||||
assert.Contains(t, err.Error(), "failed to del comment")
|
||||
}
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommentUseCase_ListComment(t *testing.T) {
|
||||
mockCtrl := gomock.NewController(t)
|
||||
defer mockCtrl.Finish()
|
||||
|
||||
// Mock Repository
|
||||
mockCommentRepository := mockRepo.NewMockCommentRepository(mockCtrl)
|
||||
|
||||
// UseCase Initialization
|
||||
uc := MustCommentUseCase(CommentUseCaseParam{
|
||||
Comment: mockCommentRepository,
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
req usecase.ListCommentRequest
|
||||
mockSetup func()
|
||||
wantErr bool
|
||||
expected []*usecase.CommentDocs
|
||||
total int64
|
||||
}{
|
||||
{
|
||||
name: "successfully list comments with replies",
|
||||
req: usecase.ListCommentRequest{
|
||||
PageSize: 10,
|
||||
PageIndex: 1,
|
||||
},
|
||||
mockSetup: func() {
|
||||
// Mock main layer comments
|
||||
mockCommentRepository.EXPECT().
|
||||
ListComments(gomock.Any(), gomock.Any()).
|
||||
Return([]*entity.Comments{
|
||||
{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: "user-123",
|
||||
ReferenceID: "ref-001",
|
||||
Message: base64.StdEncoding.EncodeToString(snappy.Encode(nil, []byte("Comment 1"))),
|
||||
UpdatedAt: time.Now().UnixNano(),
|
||||
CreatedAt: time.Now().UnixNano(),
|
||||
},
|
||||
}, int64(1), nil)
|
||||
|
||||
// Mock replies
|
||||
mockCommentRepository.EXPECT().
|
||||
ListComments(gomock.Any(), gomock.Any()).
|
||||
Return([]*entity.Comments{
|
||||
{
|
||||
ID: primitive.NewObjectID(),
|
||||
UID: "user-456",
|
||||
ReferenceID: "ref-001",
|
||||
ParentCommentID: "parent-001",
|
||||
Message: base64.StdEncoding.EncodeToString(snappy.Encode(nil, []byte("Reply 1"))),
|
||||
UpdatedAt: time.Now().UnixNano(),
|
||||
CreatedAt: time.Now().UnixNano(),
|
||||
},
|
||||
}, int64(1), nil)
|
||||
},
|
||||
wantErr: false,
|
||||
expected: []*usecase.CommentDocs{
|
||||
{
|
||||
UID: "user-123",
|
||||
ReferenceID: "ref-001",
|
||||
Message: "Comment 1",
|
||||
Replies: []*usecase.CommentDocs{
|
||||
{
|
||||
UID: "user-456",
|
||||
ReferenceID: "ref-001",
|
||||
ParentCommentID: "parent-001",
|
||||
Message: "Reply 1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
total: 1,
|
||||
},
|
||||
{
|
||||
name: "database error while listing comments",
|
||||
req: usecase.ListCommentRequest{
|
||||
PageSize: 10,
|
||||
PageIndex: 1,
|
||||
},
|
||||
mockSetup: func() {
|
||||
mockCommentRepository.EXPECT().
|
||||
ListComments(gomock.Any(), gomock.Any()).
|
||||
Return([]*entity.Comments{}, int64(0), errors.New("database error"))
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
// Mock Setup
|
||||
tt.mockSetup()
|
||||
|
||||
// Execute UseCase
|
||||
results, total, err := uc.ListComment(context.Background(), tt.req)
|
||||
|
||||
// Assert Results
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, results)
|
||||
assert.Equal(t, int64(0), total)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.total, total)
|
||||
assert.Len(t, results, len(tt.expected))
|
||||
for i, expectedComment := range tt.expected {
|
||||
assert.Equal(t, expectedComment.Message, results[i].Message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue