chat_back_go/internal/service/messages_test.go

1338 lines
42 KiB
Go

package service
import (
"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
"testing"
"time"
"git.urec56.ru/urec/chat_back_go/config"
"git.urec56.ru/urec/chat_back_go/internal/domain"
"git.urec56.ru/urec/chat_back_go/internal/logger"
"git.urec56.ru/urec/chat_back_go/internal/repository"
mock_repository "git.urec56.ru/urec/chat_back_go/internal/repository/mocks"
mock_service "git.urec56.ru/urec/chat_back_go/internal/service/mocks"
)
func Test_newMessageService(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockMessage(c)
l := logger.NewLogger(config.Config{Mode: "TEST"})
u := &userService{}
serv := newMessageService(repo, u, l)
assert.Equal(t, &messageService{repo: repo, u: u, l: l}, serv)
}
func TestMessageService_AddAvatarImageAndUsernameToMessage(t *testing.T) {
type userServiceBehavior func(u *mock_service.MockUser, userID int, user domain.User, err error)
testTable := []struct {
name string
userServiceBehavior userServiceBehavior
inputMsg domain.RawMessage
serviceInput int
serviceUser domain.User
serviceErr error
expectedMsg domain.Message
expectedErr error
}{
{
name: "ok",
userServiceBehavior: func(u *mock_service.MockUser, userID int, user domain.User, err error) {
u.EXPECT().Get(userID, true).Return(user, err)
},
inputMsg: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "some text",
ImageUrl: "image",
ChatID: 1,
UserID: 2,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "some sendMsg",
AnswerImageUrl: "image2",
},
serviceInput: 2,
serviceUser: domain.User{
ID: 1,
Role: 1,
Username: "urec",
Email: "mail@mail.ru",
HashedPassword: "hp",
AvatarImage: "avatar_image",
BlackPhoenix: false,
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
},
expectedMsg: domain.Message{
ID: domain.GenerateTestUUID(),
Message: "some text",
ImageUrl: "image",
ChatID: 1,
UserID: 2,
Username: "urec",
AvatarImage: "avatar_image",
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "some sendMsg",
AnswerImageUrl: "image2",
},
},
{
name: "any_error",
userServiceBehavior: func(u *mock_service.MockUser, userID int, user domain.User, err error) {
u.EXPECT().Get(userID, true).Return(user, err)
},
inputMsg: domain.RawMessage{UserID: 2},
serviceInput: 2,
serviceErr: domain.AnyError,
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
u := mock_service.NewMockUser(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
tc.userServiceBehavior(u, tc.serviceInput, tc.serviceUser, tc.serviceErr)
serv := &messageService{u: u, l: log}
res, err := serv.AddAvatarImageAndUsernameToMessage(tc.inputMsg)
assert.Equal(t, tc.expectedMsg, res)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestMessageService_AddAvatarImageAndUsernameToMessages(t *testing.T) {
type userServiceBehavior func(u *mock_service.MockUser, userID int, user domain.User, err error)
testTable := []struct {
name string
userServiceBehavior userServiceBehavior
inputMsgs []domain.RawMessage
serviceInput int
serviceUser domain.User
serviceErr error
expectedMsgs []domain.Message
}{
{
name: "ok",
userServiceBehavior: func(u *mock_service.MockUser, userID int, user domain.User, err error) {
u.EXPECT().Get(userID, true).Return(user, err)
},
inputMsgs: []domain.RawMessage{
{
ID: domain.GenerateTestUUID(),
Message: "some text",
ImageUrl: "image",
ChatID: 1,
UserID: 2,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "some sendMsg",
AnswerImageUrl: "image2",
},
},
serviceInput: 2,
serviceUser: domain.User{
ID: 1,
Role: 1,
Username: "urec",
Email: "mail@mail.ru",
HashedPassword: "hp",
AvatarImage: "avatar_image",
BlackPhoenix: false,
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
},
expectedMsgs: []domain.Message{
{
ID: domain.GenerateTestUUID(),
Message: "some text",
ImageUrl: "image",
ChatID: 1,
UserID: 2,
Username: "urec",
AvatarImage: "avatar_image",
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "some sendMsg",
AnswerImageUrl: "image2",
},
},
},
{
name: "any_error",
userServiceBehavior: func(u *mock_service.MockUser, userID int, user domain.User, err error) {
u.EXPECT().Get(userID, true).Return(user, err)
},
inputMsgs: []domain.RawMessage{{UserID: 2}},
serviceInput: 2,
serviceErr: domain.AnyError,
expectedMsgs: []domain.Message{},
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
u := mock_service.NewMockUser(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
tc.userServiceBehavior(u, tc.serviceInput, tc.serviceUser, tc.serviceErr)
serv := &messageService{u: u, l: log}
msgs := serv.AddAvatarImageAndUsernameToMessages(tc.inputMsgs)
assert.Equal(t, tc.expectedMsgs, msgs)
})
}
}
func TestMessageService_GetRaw(t *testing.T) {
type repoBehavior func(r *mock_repository.MockMessage, input domain.UUID, msg domain.RawMessage, err error)
testTable := []struct {
name string
repoBehavior repoBehavior
inputID domain.UUID
repoInput domain.UUID
repoMsg domain.RawMessage
repoErr error
expectedMessage domain.RawMessage
expectedErr error
}{
{
name: "ok",
repoBehavior: func(r *mock_repository.MockMessage, input domain.UUID, msg domain.RawMessage, err error) {
r.EXPECT().Get(input).Return(msg, err)
},
inputID: domain.GenerateTestUUID(),
repoInput: domain.GenerateTestUUID(),
repoMsg: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "sendMsg",
ImageUrl: "image",
ChatID: 1,
UserID: 2,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "msg1",
AnswerImageUrl: "image2",
},
expectedMessage: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "sendMsg",
ImageUrl: "image",
ChatID: 1,
UserID: 2,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "msg1",
AnswerImageUrl: "image2",
},
},
{
name: "any_error",
repoBehavior: func(r *mock_repository.MockMessage, input domain.UUID, msg domain.RawMessage, err error) {
r.EXPECT().Get(input).Return(msg, err)
},
inputID: domain.GenerateTestUUID(),
repoInput: domain.GenerateTestUUID(),
repoErr: domain.AnyError,
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockMessage(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
tc.repoBehavior(repo, tc.repoInput, tc.repoMsg, tc.repoErr)
serv := &messageService{repo: repo, l: log}
msg, err := serv.GetRaw(tc.inputID)
assert.Equal(t, msg, tc.expectedMessage)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestMessageService_GetMessage(t *testing.T) {
type repoBehavior func(r *mock_repository.MockMessage, input domain.UUID, msg domain.RawMessage, err error)
type serviceBehavior func(s *mock_service.MockUser, userID int, user domain.User, err error)
testTable := []struct {
name string
repoBehavior repoBehavior
serviceBehavior serviceBehavior
inputID domain.UUID
repoInput domain.UUID
repoMsg domain.RawMessage
serviceInput int
serviceUser domain.User
serviceErr error
repoErr error
expectedMessage domain.Message
expectedErr error
}{
{
name: "ok",
repoBehavior: func(r *mock_repository.MockMessage, input domain.UUID, msg domain.RawMessage, err error) {
r.EXPECT().Get(input).Return(msg, err)
},
serviceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {
s.EXPECT().Get(userID, true).Return(user, err)
},
inputID: domain.GenerateTestUUID(),
repoInput: domain.GenerateTestUUID(),
repoMsg: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "sendMsg",
ImageUrl: "image",
ChatID: 1,
UserID: 2,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "msg1",
AnswerImageUrl: "image2",
},
serviceInput: 2,
serviceUser: domain.User{
ID: 2,
Role: 1,
Username: "username",
Email: "mail@mail.ru",
HashedPassword: "hp",
AvatarImage: "image",
BlackPhoenix: true,
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
},
expectedMessage: domain.Message{
ID: domain.GenerateTestUUID(),
Message: "sendMsg",
ImageUrl: "image",
ChatID: 1,
UserID: 2,
Username: "username",
AvatarImage: "image",
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "msg1",
AnswerImageUrl: "image2",
},
},
{
name: "repoErr",
repoBehavior: func(r *mock_repository.MockMessage, input domain.UUID, msg domain.RawMessage, err error) {
r.EXPECT().Get(input).Return(msg, err)
},
serviceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {},
inputID: domain.GenerateTestUUID(),
repoInput: domain.GenerateTestUUID(),
repoErr: domain.AnyError,
expectedErr: domain.InternalServerError,
},
{
name: "ok",
repoBehavior: func(r *mock_repository.MockMessage, input domain.UUID, msg domain.RawMessage, err error) {
r.EXPECT().Get(input).Return(msg, err)
},
serviceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {
s.EXPECT().Get(userID, true).Return(user, err)
},
inputID: domain.GenerateTestUUID(),
repoInput: domain.GenerateTestUUID(),
repoMsg: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "sendMsg",
ImageUrl: "image",
ChatID: 1,
UserID: 2,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "msg1",
AnswerImageUrl: "image2",
},
serviceInput: 2,
serviceErr: domain.AnyError,
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockMessage(c)
u := mock_service.NewMockUser(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
tc.repoBehavior(repo, tc.repoInput, tc.repoMsg, tc.repoErr)
tc.serviceBehavior(u, tc.serviceInput, tc.serviceUser, tc.serviceErr)
serv := &messageService{repo: repo, u: u, l: log}
msg, err := serv.GetMessage(tc.inputID)
assert.Equal(t, msg, tc.expectedMessage)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestMessageService_GetPinned(t *testing.T) {
type repoGetPinnedIDsBehavior func(r *mock_repository.MockMessage, chatID int, IDs []domain.UUID, err error)
type repoGetByIDsBehavior func(r *mock_repository.MockMessage, IDs []domain.UUID, msgs []domain.RawMessage, err error)
type userServiceBehavior func(s *mock_service.MockUser, userID int, user domain.User, err error)
type repo1Data struct {
chatID int
IDs []domain.UUID
err error
}
type repo2Data struct {
IDs []domain.UUID
msgs []domain.RawMessage
err error
}
type serviceData struct {
userID int
user domain.User
err error
}
testTable := []struct {
name string
repoGetPinnedIDsBehavior repoGetPinnedIDsBehavior
repoGetByIDsBehavior repoGetByIDsBehavior
userServiceBehavior userServiceBehavior
repo1Data repo1Data
repo2Data repo2Data
serviceData serviceData
chatID int
expectedMsgs []domain.Message
expectedErr error
}{
{
name: "ok",
repoGetPinnedIDsBehavior: func(r *mock_repository.MockMessage, chatID int, IDs []domain.UUID, err error) {
r.EXPECT().GetPinnedIDs(chatID).Return(IDs, err)
},
repoGetByIDsBehavior: func(r *mock_repository.MockMessage, IDs []domain.UUID, msgs []domain.RawMessage, err error) {
r.EXPECT().GetByIDs(IDs).Return(msgs, err)
},
userServiceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {
s.EXPECT().Get(userID, true).Return(user, err)
},
repo1Data: repo1Data{
chatID: 32,
IDs: []domain.UUID{domain.GenerateTestUUID()},
},
repo2Data: repo2Data{
IDs: []domain.UUID{domain.GenerateTestUUID()},
msgs: []domain.RawMessage{
{
ID: domain.GenerateTestUUID(),
Message: "message",
ImageUrl: "image",
ChatID: 32,
UserID: 2,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "msg2",
AnswerImageUrl: "image2",
},
},
},
serviceData: serviceData{
userID: 2,
user: domain.User{
ID: 2,
Role: 1,
Username: "username",
Email: "mail@mail.ru",
HashedPassword: "hp",
AvatarImage: "avatar_image",
BlackPhoenix: true,
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
},
},
chatID: 32,
expectedMsgs: []domain.Message{
{
ID: domain.GenerateTestUUID(),
Message: "message",
ImageUrl: "image",
ChatID: 32,
UserID: 2,
Username: "username",
AvatarImage: "avatar_image",
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "msg2",
AnswerImageUrl: "image2",
},
},
},
{
name: "GetPinnedIDs_error",
repoGetPinnedIDsBehavior: func(r *mock_repository.MockMessage, chatID int, IDs []domain.UUID, err error) {
r.EXPECT().GetPinnedIDs(chatID).Return(IDs, err)
},
repoGetByIDsBehavior: func(r *mock_repository.MockMessage, IDs []domain.UUID, msgs []domain.RawMessage, err error) {},
userServiceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {},
repo1Data: repo1Data{
chatID: 32,
err: domain.AnyError,
},
chatID: 32,
expectedErr: domain.InternalServerError,
},
{
name: "GetByIDs_error",
repoGetPinnedIDsBehavior: func(r *mock_repository.MockMessage, chatID int, IDs []domain.UUID, err error) {
r.EXPECT().GetPinnedIDs(chatID).Return(IDs, err)
},
repoGetByIDsBehavior: func(r *mock_repository.MockMessage, IDs []domain.UUID, msgs []domain.RawMessage, err error) {
r.EXPECT().GetByIDs(IDs).Return(msgs, err)
},
userServiceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {},
repo1Data: repo1Data{
chatID: 32,
IDs: []domain.UUID{domain.GenerateTestUUID()},
},
repo2Data: repo2Data{
IDs: []domain.UUID{domain.GenerateTestUUID()},
err: domain.AnyError,
},
chatID: 32,
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockMessage(c)
userServ := mock_service.NewMockUser(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
tc.repoGetPinnedIDsBehavior(repo, tc.repo1Data.chatID, tc.repo1Data.IDs, tc.repo1Data.err)
tc.repoGetByIDsBehavior(repo, tc.repo2Data.IDs, tc.repo2Data.msgs, tc.repo2Data.err)
tc.userServiceBehavior(userServ, tc.serviceData.userID, tc.serviceData.user, tc.serviceData.err)
serv := &messageService{repo: repo, u: userServ, l: log}
msgs, err := serv.GetPinned(tc.chatID)
assert.Equal(t, tc.expectedMsgs, msgs)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestMessageService_GetSome(t *testing.T) {
type repoBehavior func(r *mock_repository.MockMessage, messagesInfo repository.GetSome, msgs []domain.RawMessage, err error)
type serviceBehavior func(s *mock_service.MockUser, userID int, user domain.User, err error)
type repoData struct {
messagesInfo repository.GetSome
msgs []domain.RawMessage
err error
}
type serviceData struct {
userID int
user domain.User
err error
}
testTable := []struct {
name string
repoBehavior repoBehavior
serviceBehavior serviceBehavior
repoData repoData
serviceData serviceData
chatID, offset, limit int
expectedMsgs []domain.Message
expectedErr error
}{
{
name: "ok",
repoBehavior: func(r *mock_repository.MockMessage, messagesInfo repository.GetSome, msgs []domain.RawMessage, err error) {
r.EXPECT().GetSome(messagesInfo).Return(msgs, err)
},
serviceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {
s.EXPECT().Get(userID, true).Return(user, err)
},
repoData: repoData{
messagesInfo: repository.GetSome{ChatID: 15, Offset: 10, Limit: 15},
msgs: []domain.RawMessage{
{
ID: domain.GenerateTestUUID(),
Message: "message",
ImageUrl: "image",
ChatID: 15,
UserID: 2,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "msg2",
AnswerImageUrl: "image2",
},
},
},
serviceData: serviceData{
userID: 2,
user: domain.User{
ID: 2,
Role: 1,
Username: "username",
Email: "mail@mail.ru",
HashedPassword: "hp",
AvatarImage: "avatar_image",
BlackPhoenix: true,
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
},
},
chatID: 15,
offset: 10,
limit: 15,
expectedMsgs: []domain.Message{
{
ID: domain.GenerateTestUUID(),
Message: "message",
ImageUrl: "image",
ChatID: 15,
UserID: 2,
Username: "username",
AvatarImage: "avatar_image",
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "msg2",
AnswerImageUrl: "image2",
},
},
},
{
name: "repo_error",
repoBehavior: func(r *mock_repository.MockMessage, messagesInfo repository.GetSome, msgs []domain.RawMessage, err error) {
r.EXPECT().GetSome(messagesInfo).Return(msgs, err)
},
serviceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {},
repoData: repoData{
messagesInfo: repository.GetSome{ChatID: 15, Offset: 10, Limit: 15},
err: domain.AnyError,
},
chatID: 15,
offset: 10,
limit: 15,
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockMessage(c)
userServ := mock_service.NewMockUser(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
tc.repoBehavior(repo, tc.repoData.messagesInfo, tc.repoData.msgs, tc.repoData.err)
tc.serviceBehavior(userServ, tc.serviceData.userID, tc.serviceData.user, tc.serviceData.err)
serv := &messageService{repo: repo, u: userServ, l: log}
msgs, err := serv.GetSome(tc.chatID, tc.offset, tc.limit)
assert.Equal(t, tc.expectedMsgs, msgs)
assert.ErrorIs(t, tc.expectedErr, err)
})
}
}
func TestMessageService_SendMessage(t *testing.T) {
type getRawBehavior func(r *mock_repository.MockMessage, answerID domain.UUID, msg domain.RawMessage, err error)
type sendBehavior func(r *mock_repository.MockMessage, msg repository.SendMessage, rawMsg domain.RawMessage, err error)
type userGetBehavior func(s *mock_service.MockUser, userID int, user domain.User, err error)
type getRawData struct {
answerID domain.UUID
msg domain.RawMessage
err error
}
type sendData struct {
sendMsg repository.SendMessage
rawMsg domain.RawMessage
err error
}
type userGetData struct {
userID int
user domain.User
err error
}
type input struct {
userID, chatID int
message domain.SendMessage
}
testTable := []struct {
name string
getRawBehavior getRawBehavior
sendBehavior sendBehavior
userGetBehavior userGetBehavior
getRawData getRawData
sendData sendData
userGetData userGetData
input input
expectedMsg domain.Message
expectedErr error
}{
{
name: "message_without_answer",
getRawBehavior: func(r *mock_repository.MockMessage, answerID domain.UUID, msg domain.RawMessage, err error) {},
sendBehavior: func(r *mock_repository.MockMessage, msg repository.SendMessage, rawMsg domain.RawMessage, err error) {
r.EXPECT().Send(msg).Return(rawMsg, err)
},
userGetBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {
s.EXPECT().Get(userID, true).Return(user, err)
},
input: input{
userID: 1,
chatID: 2,
message: domain.SendMessage{
Flag: "send",
Message: "msg",
ImageUrl: "image",
},
},
sendData: sendData{
sendMsg: repository.SendMessage{
Message: "msg",
ImageUrl: "image",
ChatID: 2,
UserID: 1,
},
rawMsg: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "msg",
ImageUrl: "image",
ChatID: 2,
UserID: 1,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
},
},
userGetData: userGetData{
userID: 1,
user: domain.User{
ID: 1,
Role: 1,
Username: "name",
Email: "mail@mail.ru",
HashedPassword: "hp",
AvatarImage: "avatar_image",
BlackPhoenix: true,
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
},
},
expectedMsg: domain.Message{
ID: domain.GenerateTestUUID(),
Message: "msg",
ImageUrl: "image",
ChatID: 2,
UserID: 1,
Username: "name",
AvatarImage: "avatar_image",
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
},
},
{
name: "message_with_answer",
getRawBehavior: func(r *mock_repository.MockMessage, answerID domain.UUID, msg domain.RawMessage, err error) {
r.EXPECT().Get(answerID).Return(msg, err)
},
sendBehavior: func(r *mock_repository.MockMessage, msg repository.SendMessage, rawMsg domain.RawMessage, err error) {
r.EXPECT().Send(msg).Return(rawMsg, err)
},
userGetBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {
s.EXPECT().Get(userID, true).Return(user, err)
},
input: input{
userID: 1,
chatID: 2,
message: domain.SendMessage{
Flag: "send",
Message: "msg",
ImageUrl: "image",
Answer: domain.GenerateTestUUID(),
},
},
getRawData: getRawData{
answerID: domain.GenerateTestUUID(),
msg: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "answer_msg",
ImageUrl: "answer_image",
ChatID: 2,
UserID: 3,
CreatedAt: time.Date(2025, time.February, 1, 0, 0, 0, 0, time.UTC),
},
},
sendData: sendData{
sendMsg: repository.SendMessage{
Message: "msg",
ImageUrl: "image",
ChatID: 2,
UserID: 1,
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "answer_msg",
AnswerImageUrl: "answer_image",
},
rawMsg: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "msg",
ImageUrl: "image",
ChatID: 2,
UserID: 1,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "answer_msg",
AnswerImageUrl: "answer_image",
},
},
userGetData: userGetData{
userID: 1,
user: domain.User{
ID: 1,
Role: 1,
Username: "name",
Email: "mail@mail.ru",
HashedPassword: "hp",
AvatarImage: "avatar_image",
BlackPhoenix: true,
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
},
},
expectedMsg: domain.Message{
ID: domain.GenerateTestUUID(),
Message: "msg",
ImageUrl: "image",
ChatID: 2,
UserID: 1,
Username: "name",
AvatarImage: "avatar_image",
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "answer_msg",
AnswerImageUrl: "answer_image",
},
},
{
name: "message_without_answer_send_error",
getRawBehavior: func(r *mock_repository.MockMessage, answerID domain.UUID, msg domain.RawMessage, err error) {},
sendBehavior: func(r *mock_repository.MockMessage, msg repository.SendMessage, rawMsg domain.RawMessage, err error) {
r.EXPECT().Send(msg).Return(rawMsg, err)
},
userGetBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {},
input: input{
userID: 1,
chatID: 2,
message: domain.SendMessage{
Flag: "send",
Message: "msg",
ImageUrl: "image",
},
},
sendData: sendData{
sendMsg: repository.SendMessage{
Message: "msg",
ImageUrl: "image",
ChatID: 2,
UserID: 1,
},
err: domain.AnyError,
},
expectedErr: domain.InternalServerError,
},
{
name: "message_with_answer_getRaw_error",
getRawBehavior: func(r *mock_repository.MockMessage, answerID domain.UUID, msg domain.RawMessage, err error) {
r.EXPECT().Get(answerID).Return(msg, err)
},
sendBehavior: func(r *mock_repository.MockMessage, msg repository.SendMessage, rawMsg domain.RawMessage, err error) {
},
userGetBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {},
input: input{
userID: 1,
chatID: 2,
message: domain.SendMessage{
Flag: "send",
Message: "msg",
ImageUrl: "image",
Answer: domain.GenerateTestUUID(),
},
},
getRawData: getRawData{
answerID: domain.GenerateTestUUID(),
err: domain.AnyError,
},
expectedErr: domain.InternalServerError,
},
{
name: "message_with_answer_send_error",
getRawBehavior: func(r *mock_repository.MockMessage, answerID domain.UUID, msg domain.RawMessage, err error) {
r.EXPECT().Get(answerID).Return(msg, err)
},
sendBehavior: func(r *mock_repository.MockMessage, msg repository.SendMessage, rawMsg domain.RawMessage, err error) {
r.EXPECT().Send(msg).Return(rawMsg, err)
},
userGetBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {},
input: input{
userID: 1,
chatID: 2,
message: domain.SendMessage{
Flag: "send",
Message: "msg",
ImageUrl: "image",
Answer: domain.GenerateTestUUID(),
},
},
getRawData: getRawData{
answerID: domain.GenerateTestUUID(),
msg: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "answer_msg",
ImageUrl: "answer_image",
ChatID: 2,
UserID: 3,
CreatedAt: time.Date(2025, time.February, 1, 0, 0, 0, 0, time.UTC),
},
},
sendData: sendData{
sendMsg: repository.SendMessage{
Message: "msg",
ImageUrl: "image",
ChatID: 2,
UserID: 1,
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "answer_msg",
AnswerImageUrl: "answer_image",
},
err: domain.AnyError,
},
expectedErr: domain.InternalServerError,
},
{
name: "get_user_error",
getRawBehavior: func(r *mock_repository.MockMessage, answerID domain.UUID, msg domain.RawMessage, err error) {},
sendBehavior: func(r *mock_repository.MockMessage, msg repository.SendMessage, rawMsg domain.RawMessage, err error) {
r.EXPECT().Send(msg).Return(rawMsg, err)
},
userGetBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {
s.EXPECT().Get(userID, true).Return(user, err)
},
input: input{
userID: 1,
chatID: 2,
message: domain.SendMessage{
Flag: "send",
Message: "msg",
ImageUrl: "image",
},
},
sendData: sendData{
sendMsg: repository.SendMessage{
Message: "msg",
ImageUrl: "image",
ChatID: 2,
UserID: 1,
},
rawMsg: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "msg",
ImageUrl: "image",
ChatID: 2,
UserID: 1,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
},
},
userGetData: userGetData{
userID: 1,
err: domain.AnyError,
},
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockMessage(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
userServ := mock_service.NewMockUser(c)
tc.getRawBehavior(repo, tc.getRawData.answerID, tc.getRawData.msg, tc.getRawData.err)
tc.sendBehavior(repo, tc.sendData.sendMsg, tc.sendData.rawMsg, tc.sendData.err)
tc.userGetBehavior(userServ, tc.userGetData.userID, tc.userGetData.user, tc.userGetData.err)
serv := &messageService{repo: repo, u: userServ, l: log}
msg, err := serv.SendMessage(tc.input.userID, tc.input.chatID, tc.input.message)
assert.Equal(t, tc.expectedMsg, msg)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestMessageService_Delete(t *testing.T) {
type repoBehavior func(r *mock_repository.MockMessage, ID domain.UUID, err error)
testTable := []struct {
name string
repoBehavior repoBehavior
ID domain.UUID
repoID domain.UUID
repoErr error
expectedErr error
}{
{
name: "ok",
repoBehavior: func(r *mock_repository.MockMessage, ID domain.UUID, err error) {
r.EXPECT().Delete(ID).Return(err)
},
ID: domain.GenerateTestUUID(),
repoID: domain.GenerateTestUUID(),
},
{
name: "any_error",
repoBehavior: func(r *mock_repository.MockMessage, ID domain.UUID, err error) {
r.EXPECT().Delete(ID).Return(err)
},
ID: domain.GenerateTestUUID(),
repoID: domain.GenerateTestUUID(),
repoErr: domain.AnyError,
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockMessage(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
tc.repoBehavior(repo, tc.repoID, tc.repoErr)
serv := &messageService{repo: repo, l: log}
err := serv.Delete(tc.ID)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestMessageService_Edit(t *testing.T) {
type repoBehavior func(r *mock_repository.MockMessage, msg repository.EditMessage, err error)
testTable := []struct {
name string
repoBehavior repoBehavior
ID domain.UUID
newMessage, newImageUrl string
newMsg repository.EditMessage
repoErr error
expectedErr error
}{
{
name: "ok",
repoBehavior: func(r *mock_repository.MockMessage, msg repository.EditMessage, err error) {
r.EXPECT().Edit(msg).Return(err)
},
ID: domain.GenerateTestUUID(),
newMessage: "new_message",
newImageUrl: "new_image_url",
newMsg: repository.EditMessage{
ID: domain.GenerateTestUUID(),
Message: "new_message",
ImageUrl: "new_image_url",
},
},
{
name: "any_error",
repoBehavior: func(r *mock_repository.MockMessage, msg repository.EditMessage, err error) {
r.EXPECT().Edit(msg).Return(err)
},
ID: domain.GenerateTestUUID(),
newMessage: "new_message",
newImageUrl: "new_image_url",
newMsg: repository.EditMessage{
ID: domain.GenerateTestUUID(),
Message: "new_message",
ImageUrl: "new_image_url",
},
repoErr: domain.AnyError,
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockMessage(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
tc.repoBehavior(repo, tc.newMsg, tc.repoErr)
serv := &messageService{repo: repo, l: log}
err := serv.Edit(tc.ID, tc.newMessage, tc.newImageUrl)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestMessageService_Pin(t *testing.T) {
type repo1Behavior func(r *mock_repository.MockMessage, msg repository.PinMessage, err error)
type repo2Behavior func(r *mock_repository.MockMessage, ID domain.UUID, msg domain.RawMessage, err error)
type serviceBehavior func(s *mock_service.MockUser, userID int, user domain.User, err error)
type repo2Data struct {
ID domain.UUID
msg domain.RawMessage
err error
}
type serviceData struct {
userID int
user domain.User
err error
}
testTable := []struct {
name string
repo1Behavior repo1Behavior
repo2Behavior repo2Behavior
serviceBehavior serviceBehavior
repo2Data repo2Data
serviceData serviceData
pinMsg repository.PinMessage
chatID, userID int
messageID domain.UUID
repoErr error
expectedMsg domain.Message
expectedErr error
}{
{
name: "ok",
repo1Behavior: func(r *mock_repository.MockMessage, msg repository.PinMessage, err error) {
r.EXPECT().Pin(msg).Return(err)
},
repo2Behavior: func(r *mock_repository.MockMessage, ID domain.UUID, msg domain.RawMessage, err error) {
r.EXPECT().Get(ID).Return(msg, err)
},
serviceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {
s.EXPECT().Get(userID, true).Return(user, err)
},
repo2Data: repo2Data{
ID: domain.GenerateTestUUID(),
msg: domain.RawMessage{
ID: domain.GenerateTestUUID(),
Message: "sendMsg",
ImageUrl: "image",
ChatID: 17,
UserID: 3,
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "answer_msg",
AnswerImageUrl: "answer_image",
},
},
serviceData: serviceData{
userID: 3,
user: domain.User{
ID: 3,
Role: 1,
Username: "name",
Email: "mail@mail.ru",
HashedPassword: "hp",
AvatarImage: "avatar_image",
BlackPhoenix: true,
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
DateOfRegistration: domain.CustomDate{Time: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC)},
},
},
pinMsg: repository.PinMessage{MessageID: domain.GenerateTestUUID(), ChatID: 17, UserID: 2},
chatID: 17,
userID: 2,
messageID: domain.GenerateTestUUID(),
expectedMsg: domain.Message{
ID: domain.GenerateTestUUID(),
Message: "sendMsg",
ImageUrl: "image",
ChatID: 17,
UserID: 3,
Username: "name",
AvatarImage: "avatar_image",
CreatedAt: time.Date(2025, time.February, 2, 0, 0, 0, 0, time.UTC),
AnswerID: domain.GenerateTestUUID(),
AnswerMessage: "answer_msg",
AnswerImageUrl: "answer_image",
},
},
{
name: "message_already_pinned",
repo1Behavior: func(r *mock_repository.MockMessage, msg repository.PinMessage, err error) {
r.EXPECT().Pin(msg).Return(err)
},
repo2Behavior: func(r *mock_repository.MockMessage, ID domain.UUID, msg domain.RawMessage, err error) {},
serviceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {},
pinMsg: repository.PinMessage{MessageID: domain.GenerateTestUUID(), ChatID: 17, UserID: 2},
chatID: 17,
userID: 2,
messageID: domain.GenerateTestUUID(),
repoErr: domain.MessageAlreadyPinnedError,
expectedErr: domain.MessageAlreadyPinnedError,
},
{
name: "repo_error",
repo1Behavior: func(r *mock_repository.MockMessage, msg repository.PinMessage, err error) {
r.EXPECT().Pin(msg).Return(err)
},
repo2Behavior: func(r *mock_repository.MockMessage, ID domain.UUID, msg domain.RawMessage, err error) {},
serviceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {},
pinMsg: repository.PinMessage{MessageID: domain.GenerateTestUUID(), ChatID: 17, UserID: 2},
chatID: 17,
userID: 2,
messageID: domain.GenerateTestUUID(),
repoErr: domain.AnyError,
expectedErr: domain.InternalServerError,
},
{
name: "GetMessage_error",
repo1Behavior: func(r *mock_repository.MockMessage, msg repository.PinMessage, err error) {
r.EXPECT().Pin(msg).Return(err)
},
repo2Behavior: func(r *mock_repository.MockMessage, ID domain.UUID, msg domain.RawMessage, err error) {
r.EXPECT().Get(ID).Return(msg, err)
},
serviceBehavior: func(s *mock_service.MockUser, userID int, user domain.User, err error) {},
repo2Data: repo2Data{
ID: domain.GenerateTestUUID(),
err: domain.AnyError,
},
pinMsg: repository.PinMessage{MessageID: domain.GenerateTestUUID(), ChatID: 17, UserID: 2},
chatID: 17,
userID: 2,
messageID: domain.GenerateTestUUID(),
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockMessage(c)
userServ := mock_service.NewMockUser(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
tc.repo1Behavior(repo, tc.pinMsg, tc.repoErr)
tc.repo2Behavior(repo, tc.repo2Data.ID, tc.repo2Data.msg, tc.repo2Data.err)
tc.serviceBehavior(userServ, tc.serviceData.userID, tc.serviceData.user, tc.serviceData.err)
serv := &messageService{repo: repo, u: userServ, l: log}
msg, err := serv.Pin(tc.chatID, tc.userID, tc.messageID)
assert.Equal(t, tc.expectedMsg, msg)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}
func TestMessageService_Unpin(t *testing.T) {
type repoBehavior func(r *mock_repository.MockMessage, msg repository.UnpinMessage, err error)
testTable := []struct {
name string
repoBehavior repoBehavior
repoMsg repository.UnpinMessage
chatID int
messageID domain.UUID
repoErr error
expectedErr error
}{
{
name: "ok",
repoBehavior: func(r *mock_repository.MockMessage, msg repository.UnpinMessage, err error) {
r.EXPECT().Unpin(msg).Return(err)
},
repoMsg: repository.UnpinMessage{MessageID: domain.GenerateTestUUID(), ChatID: 2},
chatID: 2,
messageID: domain.GenerateTestUUID(),
},
{
name: "repo_error",
repoBehavior: func(r *mock_repository.MockMessage, msg repository.UnpinMessage, err error) {
r.EXPECT().Unpin(msg).Return(err)
},
repoMsg: repository.UnpinMessage{MessageID: domain.GenerateTestUUID(), ChatID: 2},
chatID: 2,
messageID: domain.GenerateTestUUID(),
repoErr: domain.AnyError,
expectedErr: domain.InternalServerError,
},
}
for _, tc := range testTable {
t.Run(tc.name, func(t *testing.T) {
c := gomock.NewController(t)
defer c.Finish()
repo := mock_repository.NewMockMessage(c)
log := logger.NewLogger(config.Config{Mode: "TEST"})
tc.repoBehavior(repo, tc.repoMsg, tc.repoErr)
serv := &messageService{repo: repo, l: log}
err := serv.Unpin(tc.chatID, tc.messageID)
assert.ErrorIs(t, err, tc.expectedErr)
})
}
}