pull/2696/head
truongpx-Mac 12 months ago
parent a7deadc697
commit 819a6e58ce

@ -279,6 +279,11 @@ msg:
@echo "${NOW} Starting to build rpc_msg..."
CGO_ENABLED=0 GOOS=${OS} GOARCH=${ARCH};go build -ldflags="-w -s" -o ./bin/openim-rpc-msg cmd/openim-rpc/openim-rpc-msg/main.go
.PHONY:test-user
test-user:
@echo "${NOW} Starting to test rpc_user..."
go test ./internal/rpc/user
.PHONY:user
user:
@echo "${NOW} Starting to build rpc_user..."

@ -1,6 +1,6 @@
module github.com/openimsdk/open-im-server/v3
go 1.19
go 1.21
require (
firebase.google.com/go v3.13.0+incompatible
@ -118,6 +118,7 @@ require (
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect
github.com/rs/xid v1.5.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect

@ -318,6 +318,7 @@ 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 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=

@ -1,16 +1,18 @@
go 1.18
go 1.21
toolchain go1.23.2
use (
.
./test/typecheck
./tools/changelog
./tools/component
./tools/data-conversion
//./tools/imctl
./tools/infra
./tools/ncpu
./tools/openim-web
./tools/url2im
./tools/versionchecker
./tools/yamlfmt
./tools/component
./tools/url2im
./tools/data-conversion
)

@ -0,0 +1,52 @@
// Code generated by mockery v2.46.2. DO NOT EDIT.
package mocks
import mock "github.com/stretchr/testify/mock"
// DataProvider is an autogenerated mock type for the DataProvider type
type DataProvider struct {
mock.Mock
}
// GetRandomNumber provides a mock function with given fields: id
func (_m *DataProvider) GetRandomNumber(id int) (int, error) {
ret := _m.Called(id)
if len(ret) == 0 {
panic("no return value specified for GetRandomNumber")
}
var r0 int
var r1 error
if rf, ok := ret.Get(0).(func(int) (int, error)); ok {
return rf(id)
}
if rf, ok := ret.Get(0).(func(int) int); ok {
r0 = rf(id)
} else {
r0 = ret.Get(0).(int)
}
if rf, ok := ret.Get(1).(func(int) error); ok {
r1 = rf(id)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// NewDataProvider creates a new instance of DataProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewDataProvider(t interface {
mock.TestingT
Cleanup(func())
}) *DataProvider {
mock := &DataProvider{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

@ -0,0 +1,463 @@
// Code generated by mockery v2.46.2. DO NOT EDIT.
package mocks
import (
context "context"
mock "github.com/stretchr/testify/mock"
relation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
time "time"
user "github.com/OpenIMSDK/protocol/user"
)
// UserDatabase is an autogenerated mock type for the UserDatabase type
type UserDatabase struct {
mock.Mock
}
// CountRangeEverydayTotal provides a mock function with given fields: ctx, start, end
func (_m *UserDatabase) CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) {
ret := _m.Called(ctx, start, end)
if len(ret) == 0 {
panic("no return value specified for CountRangeEverydayTotal")
}
var r0 map[string]int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, time.Time, time.Time) (map[string]int64, error)); ok {
return rf(ctx, start, end)
}
if rf, ok := ret.Get(0).(func(context.Context, time.Time, time.Time) map[string]int64); ok {
r0 = rf(ctx, start, end)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(map[string]int64)
}
}
if rf, ok := ret.Get(1).(func(context.Context, time.Time, time.Time) error); ok {
r1 = rf(ctx, start, end)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CountTotal provides a mock function with given fields: ctx, before
func (_m *UserDatabase) CountTotal(ctx context.Context, before *time.Time) (int64, error) {
ret := _m.Called(ctx, before)
if len(ret) == 0 {
panic("no return value specified for CountTotal")
}
var r0 int64
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *time.Time) (int64, error)); ok {
return rf(ctx, before)
}
if rf, ok := ret.Get(0).(func(context.Context, *time.Time) int64); ok {
r0 = rf(ctx, before)
} else {
r0 = ret.Get(0).(int64)
}
if rf, ok := ret.Get(1).(func(context.Context, *time.Time) error); ok {
r1 = rf(ctx, before)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Create provides a mock function with given fields: ctx, users
func (_m *UserDatabase) Create(ctx context.Context, users []*relation.UserModel) error {
ret := _m.Called(ctx, users)
if len(ret) == 0 {
panic("no return value specified for Create")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, []*relation.UserModel) error); ok {
r0 = rf(ctx, users)
} else {
r0 = ret.Error(0)
}
return r0
}
// Find provides a mock function with given fields: ctx, userIDs
func (_m *UserDatabase) Find(ctx context.Context, userIDs []string) ([]*relation.UserModel, error) {
ret := _m.Called(ctx, userIDs)
if len(ret) == 0 {
panic("no return value specified for Find")
}
var r0 []*relation.UserModel
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, []string) ([]*relation.UserModel, error)); ok {
return rf(ctx, userIDs)
}
if rf, ok := ret.Get(0).(func(context.Context, []string) []*relation.UserModel); ok {
r0 = rf(ctx, userIDs)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*relation.UserModel)
}
}
if rf, ok := ret.Get(1).(func(context.Context, []string) error); ok {
r1 = rf(ctx, userIDs)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// FindWithError provides a mock function with given fields: ctx, userIDs
func (_m *UserDatabase) FindWithError(ctx context.Context, userIDs []string) ([]*relation.UserModel, error) {
ret := _m.Called(ctx, userIDs)
if len(ret) == 0 {
panic("no return value specified for FindWithError")
}
var r0 []*relation.UserModel
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, []string) ([]*relation.UserModel, error)); ok {
return rf(ctx, userIDs)
}
if rf, ok := ret.Get(0).(func(context.Context, []string) []*relation.UserModel); ok {
r0 = rf(ctx, userIDs)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*relation.UserModel)
}
}
if rf, ok := ret.Get(1).(func(context.Context, []string) error); ok {
r1 = rf(ctx, userIDs)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetAllSubscribeList provides a mock function with given fields: ctx, userID
func (_m *UserDatabase) GetAllSubscribeList(ctx context.Context, userID string) ([]string, error) {
ret := _m.Called(ctx, userID)
if len(ret) == 0 {
panic("no return value specified for GetAllSubscribeList")
}
var r0 []string
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) ([]string, error)); ok {
return rf(ctx, userID)
}
if rf, ok := ret.Get(0).(func(context.Context, string) []string); ok {
r0 = rf(ctx, userID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, userID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetAllUserID provides a mock function with given fields: ctx, pageNumber, showNumber
func (_m *UserDatabase) GetAllUserID(ctx context.Context, pageNumber int32, showNumber int32) ([]string, error) {
ret := _m.Called(ctx, pageNumber, showNumber)
if len(ret) == 0 {
panic("no return value specified for GetAllUserID")
}
var r0 []string
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, int32, int32) ([]string, error)); ok {
return rf(ctx, pageNumber, showNumber)
}
if rf, ok := ret.Get(0).(func(context.Context, int32, int32) []string); ok {
r0 = rf(ctx, pageNumber, showNumber)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int32, int32) error); ok {
r1 = rf(ctx, pageNumber, showNumber)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetSubscribedList provides a mock function with given fields: ctx, userID
func (_m *UserDatabase) GetSubscribedList(ctx context.Context, userID string) ([]string, error) {
ret := _m.Called(ctx, userID)
if len(ret) == 0 {
panic("no return value specified for GetSubscribedList")
}
var r0 []string
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) ([]string, error)); ok {
return rf(ctx, userID)
}
if rf, ok := ret.Get(0).(func(context.Context, string) []string); ok {
r0 = rf(ctx, userID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, userID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetUserStatus provides a mock function with given fields: ctx, userIDs
func (_m *UserDatabase) GetUserStatus(ctx context.Context, userIDs []string) ([]*user.OnlineStatus, error) {
ret := _m.Called(ctx, userIDs)
if len(ret) == 0 {
panic("no return value specified for GetUserStatus")
}
var r0 []*user.OnlineStatus
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, []string) ([]*user.OnlineStatus, error)); ok {
return rf(ctx, userIDs)
}
if rf, ok := ret.Get(0).(func(context.Context, []string) []*user.OnlineStatus); ok {
r0 = rf(ctx, userIDs)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*user.OnlineStatus)
}
}
if rf, ok := ret.Get(1).(func(context.Context, []string) error); ok {
r1 = rf(ctx, userIDs)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// InitOnce provides a mock function with given fields: ctx, users
func (_m *UserDatabase) InitOnce(ctx context.Context, users []*relation.UserModel) error {
ret := _m.Called(ctx, users)
if len(ret) == 0 {
panic("no return value specified for InitOnce")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, []*relation.UserModel) error); ok {
r0 = rf(ctx, users)
} else {
r0 = ret.Error(0)
}
return r0
}
// IsExist provides a mock function with given fields: ctx, userIDs
func (_m *UserDatabase) IsExist(ctx context.Context, userIDs []string) (bool, error) {
ret := _m.Called(ctx, userIDs)
if len(ret) == 0 {
panic("no return value specified for IsExist")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, []string) (bool, error)); ok {
return rf(ctx, userIDs)
}
if rf, ok := ret.Get(0).(func(context.Context, []string) bool); ok {
r0 = rf(ctx, userIDs)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(context.Context, []string) error); ok {
r1 = rf(ctx, userIDs)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Page provides a mock function with given fields: ctx, pageNumber, showNumber
func (_m *UserDatabase) Page(ctx context.Context, pageNumber int32, showNumber int32) ([]*relation.UserModel, int64, error) {
ret := _m.Called(ctx, pageNumber, showNumber)
if len(ret) == 0 {
panic("no return value specified for Page")
}
var r0 []*relation.UserModel
var r1 int64
var r2 error
if rf, ok := ret.Get(0).(func(context.Context, int32, int32) ([]*relation.UserModel, int64, error)); ok {
return rf(ctx, pageNumber, showNumber)
}
if rf, ok := ret.Get(0).(func(context.Context, int32, int32) []*relation.UserModel); ok {
r0 = rf(ctx, pageNumber, showNumber)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*relation.UserModel)
}
}
if rf, ok := ret.Get(1).(func(context.Context, int32, int32) int64); ok {
r1 = rf(ctx, pageNumber, showNumber)
} else {
r1 = ret.Get(1).(int64)
}
if rf, ok := ret.Get(2).(func(context.Context, int32, int32) error); ok {
r2 = rf(ctx, pageNumber, showNumber)
} else {
r2 = ret.Error(2)
}
return r0, r1, r2
}
// SetUserStatus provides a mock function with given fields: ctx, list
func (_m *UserDatabase) SetUserStatus(ctx context.Context, list []*user.OnlineStatus) error {
ret := _m.Called(ctx, list)
if len(ret) == 0 {
panic("no return value specified for SetUserStatus")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, []*user.OnlineStatus) error); ok {
r0 = rf(ctx, list)
} else {
r0 = ret.Error(0)
}
return r0
}
// SubscribeUsersStatus provides a mock function with given fields: ctx, userID, userIDs
func (_m *UserDatabase) SubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error {
ret := _m.Called(ctx, userID, userIDs)
if len(ret) == 0 {
panic("no return value specified for SubscribeUsersStatus")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string, []string) error); ok {
r0 = rf(ctx, userID, userIDs)
} else {
r0 = ret.Error(0)
}
return r0
}
// UnsubscribeUsersStatus provides a mock function with given fields: ctx, userID, userIDs
func (_m *UserDatabase) UnsubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error {
ret := _m.Called(ctx, userID, userIDs)
if len(ret) == 0 {
panic("no return value specified for UnsubscribeUsersStatus")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string, []string) error); ok {
r0 = rf(ctx, userID, userIDs)
} else {
r0 = ret.Error(0)
}
return r0
}
// Update provides a mock function with given fields: ctx, _a1
func (_m *UserDatabase) Update(ctx context.Context, _a1 *relation.UserModel) error {
ret := _m.Called(ctx, _a1)
if len(ret) == 0 {
panic("no return value specified for Update")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *relation.UserModel) error); ok {
r0 = rf(ctx, _a1)
} else {
r0 = ret.Error(0)
}
return r0
}
// UpdateByMap provides a mock function with given fields: ctx, userID, args
func (_m *UserDatabase) UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) error {
ret := _m.Called(ctx, userID, args)
if len(ret) == 0 {
panic("no return value specified for UpdateByMap")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string, map[string]interface{}) error); ok {
r0 = rf(ctx, userID, args)
} else {
r0 = ret.Error(0)
}
return r0
}
// NewUserDatabase creates a new instance of UserDatabase. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewUserDatabase(t interface {
mock.TestingT
Cleanup(func())
}) *UserDatabase {
mock := &UserDatabase{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

@ -0,0 +1,5 @@
package service
type DataProvider interface {
GetRandomNumber(id int) (int, error)
}

@ -0,0 +1,18 @@
package service
import (
"errors"
"math/rand"
)
// DataProviderImpl is the concrete implementation of the DataProvider interface.
type DataProviderImpl struct{}
// GetRandomNumber simulates fetching a random number between 0 and id.
func (d *DataProviderImpl) GetRandomNumber(id int) (int, error) {
if id < 0 {
return 0, errors.New("InvalidId")
}
// Simulate fetching a random number between 0 and id
return rand.Intn(id + 1), nil
}

@ -0,0 +1,100 @@
package user
import (
"context"
"fmt"
"testing"
pbuser "github.com/OpenIMSDK/protocol/user"
"github.com/openimsdk/open-im-server/v3/internal/rpc/user/mocks"
"github.com/openimsdk/open-im-server/v3/internal/rpc/user/service"
"github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
var mockUserDatabase = &mocks.UserDatabase{}
// var uServer userServer
// func inti() {
// }
func TestGetDesignateUsers(t *testing.T) {
uServer := userServer{UserDatabase: mockUserDatabase}
mockUserDatabase.On("FindWithError", mock.Anything, mock.Anything).Return([]*relation.UserModel{{UserID: "99"}}, nil)
ctx := context.Background()
res, err := uServer.GetDesignateUsers(ctx, &pbuser.GetDesignateUsersReq{UserIDs: []string{}})
assert.NoError(t, err)
assert.Equal(t, "99", res.UsersInfo[0].UserID)
t.Logf("success")
}
type MyMockedObject struct {
mock.Mock
}
func (m *MyMockedObject) DoSomeThing(number int) (bool, error) {
args := m.Called(number)
return args.Bool(0), args.Error(1)
}
func TestDataProvider(t *testing.T) {
testOjb := new(MyMockedObject)
testOjb.On("DoSomeThing", mock.Anything).Return(true, nil)
targetFuncThatDoesSomethingWithObj(*testOjb)
testOjb.AssertExpectations(t)
///////
mock := &mocks.DataProvider{}
// Set the expected return value for the GetRandomNumber method
mock.On("GetRandomNumber", 5).Return(3, nil).Once()
// Call ConsumeData that using the mocked DataProvider
result, err := ConsumeData(mock, 5)
// Assert that the result and error are as expected
assert.Equal(t, "Odd", result)
assert.NoError(t, err)
// Assert that the GetRandomNumber method was called with the expected input
mock.AssertExpectations(t)
}
func targetFuncThatDoesSomethingWithObj(testObj MyMockedObject) {
fmt.Println(testObj.DoSomeThing(12))
}
// ConsumeData is a function that uses a DataProvider to fetch and process data.
func ConsumeData(provider service.DataProvider, id int) (string, error) {
// Use GetRandomNumber to get a random number between 0 and id
randomNumber, err := provider.GetRandomNumber(id)
if err != nil {
return "", err
}
// Check whether the value is even or odd
result := checkEvenOrOdd(randomNumber)
// Return the result
return result, nil
}
// checkEvenOrOdd checks whether the given value is even or odd.
func checkEvenOrOdd(value int) string {
if value%2 == 0 {
return "Even"
}
return "Odd"
}
//mockery --dir ../../../pkg/common/db/controller --name UserDatabase
//mockery --all --output path/to/output
//mockery --all --recursive
//mockery --output ./mocks --dir ./service --all

@ -58,6 +58,14 @@ pipeline {
])
}
}
stage("Unit-Test") {
steps {
echo 'UNIT TEST EXECUTION STARTED'
sh 'make test-user'
}
}
stage('CommitHash') {
steps {
script {
@ -113,8 +121,7 @@ pipeline {
extensions: [],
gitTool: 'Default',
submoduleCfg: [],
userRemoteConfigs: [[url: "https://github.com/${ORGANIZATION_NAME}/${SERVICE_NAME_INFRA}", credentialsId: "${CREDENTIALS_ID}"]]
])
userRemoteConfigs: [[url: "https://github.com/${ORGANIZATION_NAME}/${SERVICE_NAME_INFRA}", credentialsId: "${CREDENTIALS_ID}"]]])
}
}

@ -0,0 +1,34 @@
package main
import (
"fmt"
"testing"
"github.com/stretchr/testify/mock"
)
type MyMockedObject struct {
mock.Mock
}
func (m *MyMockedObject) DoSomeThing(number int) (bool, error) {
args := m.Called(number)
return args.Bool(0), args.Error(1)
}
// var uServer = userServer{}
func TestGetDesignateUsers(t *testing.T) {
testOjb := new(MyMockedObject)
testOjb.On("DoSomeThing", mock.Anything).Return(true, nil)
targetFuncThatDoesSomethingWithObj(*testOjb)
testOjb.AssertExpectations(t)
t.Logf("success")
}
func targetFuncThatDoesSomethingWithObj(testObj MyMockedObject) {
fmt.Println(testObj.DoSomeThing(12))
}
Loading…
Cancel
Save