592 lines
17 KiB
Go
592 lines
17 KiB
Go
package handler
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"github.com/stretchr/testify/assert"
|
|
"go.uber.org/mock/gomock"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"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"
|
|
mock_service "git.urec56.ru/urec/chat_back_go/internal/service/mocks"
|
|
mock_http "git.urec56.ru/urec/chat_back_go/internal/transport/rest/handler/mocks"
|
|
)
|
|
|
|
func TestHandler_GetUsers(t *testing.T) {
|
|
type servBehavior func(s *mock_service.MockServ, username string, users []domain.User, err error)
|
|
testTable := []struct {
|
|
name string
|
|
username string
|
|
servBehavior servBehavior
|
|
servUsers []domain.User
|
|
servErr error
|
|
logErr error
|
|
writeErr error
|
|
expectedUsers map[string][]domain.User
|
|
expectedStatusCode int
|
|
}{
|
|
{
|
|
name: "ok_1",
|
|
username: "urec",
|
|
servBehavior: func(s *mock_service.MockServ, username string, users []domain.User, err error) {
|
|
s.EXPECT().GetAll(username).Return(users, err)
|
|
},
|
|
servUsers: []domain.User{
|
|
{
|
|
ID: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
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)},
|
|
},
|
|
},
|
|
expectedUsers: map[string][]domain.User{
|
|
"users": {
|
|
{
|
|
ID: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
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)},
|
|
},
|
|
},
|
|
},
|
|
expectedStatusCode: http.StatusOK,
|
|
},
|
|
{
|
|
name: "ok_2",
|
|
servBehavior: func(s *mock_service.MockServ, username string, users []domain.User, err error) {
|
|
s.EXPECT().GetAll(username).Return(users, err)
|
|
},
|
|
servUsers: []domain.User{
|
|
{
|
|
ID: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
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)},
|
|
},
|
|
},
|
|
expectedUsers: map[string][]domain.User{
|
|
"users": {
|
|
{
|
|
ID: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
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)},
|
|
},
|
|
},
|
|
},
|
|
expectedStatusCode: http.StatusOK,
|
|
},
|
|
{
|
|
name: "serv_error",
|
|
servBehavior: func(s *mock_service.MockServ, username string, users []domain.User, err error) {
|
|
s.EXPECT().GetAll(username).Return(users, err)
|
|
},
|
|
servErr: domain.AnyError,
|
|
logErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusInternalServerError,
|
|
},
|
|
{
|
|
name: "response_writing_error",
|
|
servBehavior: func(s *mock_service.MockServ, username string, users []domain.User, err error) {
|
|
s.EXPECT().GetAll(username).Return(users, err)
|
|
},
|
|
logErr: domain.AnyError,
|
|
writeErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusInternalServerError,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testTable {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
reqPath := "/users"
|
|
log := logger.NewLogger(config.Config{Mode: "TEST"})
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
tc.servBehavior(serv, tc.username, tc.servUsers, tc.servErr)
|
|
|
|
req := httptest.NewRequest(http.MethodGet, reqPath, nil)
|
|
w := mock_http.NewRecorder(tc.writeErr)
|
|
|
|
q := req.URL.Query()
|
|
q.Add("username", tc.username)
|
|
req.URL.RawQuery = q.Encode()
|
|
|
|
h := &Handler{serv: serv, l: log}
|
|
|
|
h.GetUsers(w, req)
|
|
|
|
resp := w.Result()
|
|
b, err := io.ReadAll(resp.Body)
|
|
assert.NoError(t, err)
|
|
|
|
var u map[string][]domain.User
|
|
|
|
if tc.expectedStatusCode == http.StatusOK {
|
|
err = json.Unmarshal(b, &u)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
assert.Equal(t, tc.expectedUsers, u)
|
|
assert.Equal(t, tc.expectedStatusCode, resp.StatusCode)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHandler_CheckExisting(t *testing.T) {
|
|
type servBehavior func(s *mock_service.MockServ, username, email string, user domain.User, err error)
|
|
testTable := []struct {
|
|
name string
|
|
reqBody domain.UserFilter
|
|
servBehavior servBehavior
|
|
servUser domain.User
|
|
servErr error
|
|
logErr error
|
|
isDecodeError bool
|
|
expectedStatusCode int
|
|
}{
|
|
{
|
|
name: "ok",
|
|
reqBody: domain.UserFilter{Username: "urecs", Email: "mail@atod.com"},
|
|
servBehavior: func(s *mock_service.MockServ, username, email string, user domain.User, err error) {
|
|
s.EXPECT().FindOne(username, email).Return(user, err)
|
|
},
|
|
expectedStatusCode: http.StatusOK,
|
|
},
|
|
{
|
|
name: "decoding_body_error",
|
|
servBehavior: func(s *mock_service.MockServ, username, email string, user domain.User, err error) {},
|
|
isDecodeError: true,
|
|
expectedStatusCode: http.StatusUnprocessableEntity,
|
|
},
|
|
{
|
|
name: "validation_error",
|
|
reqBody: domain.UserFilter{Username: "u"},
|
|
servBehavior: func(s *mock_service.MockServ, username, email string, user domain.User, err error) {},
|
|
logErr: errors.New("Key: 'UserFilter.Username' Error:Field validation for 'Username' failed on the 'min' tag"),
|
|
expectedStatusCode: http.StatusUnprocessableEntity,
|
|
},
|
|
{
|
|
name: "serv_error",
|
|
reqBody: domain.UserFilter{Username: "urec"},
|
|
servBehavior: func(s *mock_service.MockServ, username, email string, user domain.User, err error) {
|
|
s.EXPECT().FindOne(username, email).Return(user, err)
|
|
},
|
|
servErr: domain.AnyError,
|
|
logErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusInternalServerError,
|
|
},
|
|
{
|
|
name: "user_already_exists",
|
|
reqBody: domain.UserFilter{Username: "urec"},
|
|
servUser: domain.User{ID: 1},
|
|
servBehavior: func(s *mock_service.MockServ, username, email string, user domain.User, err error) {
|
|
s.EXPECT().FindOne(username, email).Return(user, err)
|
|
},
|
|
expectedStatusCode: http.StatusConflict,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testTable {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
reqPath := "/check_existing_user"
|
|
log := logger.NewLogger(config.Config{Mode: "TEST"})
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
tc.servBehavior(serv, tc.reqBody.Username, tc.reqBody.Email, tc.servUser, tc.servErr)
|
|
|
|
var body []byte
|
|
if !tc.isDecodeError {
|
|
b, err := json.Marshal(tc.reqBody)
|
|
assert.NoError(t, err)
|
|
body = b
|
|
} else {
|
|
b := make([]byte, 0)
|
|
body = b
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodPost, reqPath, bytes.NewBuffer(body))
|
|
w := mock_http.NewRecorder(nil)
|
|
|
|
h := &Handler{serv: serv, l: log}
|
|
|
|
h.CheckExisting(w, req)
|
|
|
|
resp := w.Result()
|
|
assert.Equal(t, tc.expectedStatusCode, resp.StatusCode)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHandler_CheckExistingPassword(t *testing.T) {
|
|
reqPath := "/check_existing_password"
|
|
req := httptest.NewRequest(http.MethodPost, reqPath, nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
h := &Handler{}
|
|
|
|
for i := 0; i < 10; i++ {
|
|
h.CheckExistingPassword(w, req)
|
|
}
|
|
}
|
|
|
|
func TestHandler_Register(t *testing.T) {
|
|
type servBehavior func(s *mock_service.MockServ, userData domain.UserRegister, token string, err error)
|
|
testTable := []struct {
|
|
name string
|
|
reqBody domain.UserRegister
|
|
servBehavior servBehavior
|
|
servToken string
|
|
servErr error
|
|
logErr error
|
|
isDecodeError bool
|
|
writeErr error
|
|
expectedStatusCode int
|
|
expectedBody map[string]string
|
|
}{
|
|
{
|
|
name: "ok",
|
|
reqBody: domain.UserRegister{
|
|
Username: "urecs",
|
|
Email: "mail@atod.com",
|
|
Password: "password",
|
|
Password2: "password",
|
|
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
},
|
|
servBehavior: func(s *mock_service.MockServ, userData domain.UserRegister, token string, err error) {
|
|
s.EXPECT().Register(userData).Return(token, err)
|
|
},
|
|
servToken: "token",
|
|
expectedStatusCode: http.StatusCreated,
|
|
expectedBody: map[string]string{"authorization": "Bearer token"},
|
|
},
|
|
{
|
|
name: "user_already_exists",
|
|
reqBody: domain.UserRegister{
|
|
Username: "urec",
|
|
Email: "mail@atod.com",
|
|
Password: "password",
|
|
Password2: "password",
|
|
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
},
|
|
servBehavior: func(s *mock_service.MockServ, userData domain.UserRegister, token string, err error) {
|
|
s.EXPECT().Register(userData).Return(token, err)
|
|
},
|
|
servErr: domain.UserAlreadyExistsError,
|
|
expectedStatusCode: http.StatusConflict,
|
|
},
|
|
{
|
|
name: "decoding_body_error",
|
|
servBehavior: func(s *mock_service.MockServ, userData domain.UserRegister, token string, err error) {},
|
|
isDecodeError: true,
|
|
expectedStatusCode: http.StatusUnprocessableEntity,
|
|
},
|
|
{
|
|
name: "validation_error",
|
|
reqBody: domain.UserRegister{
|
|
Email: "mail@atod.com",
|
|
Password: "password",
|
|
Password2: "password",
|
|
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
},
|
|
servBehavior: func(s *mock_service.MockServ, userData domain.UserRegister, token string, err error) {},
|
|
logErr: errors.New("Key: 'UserRegister.Username' Error:Field validation for 'Username' failed on the 'min' tag"),
|
|
expectedStatusCode: http.StatusUnprocessableEntity,
|
|
},
|
|
{
|
|
name: "serv_error",
|
|
reqBody: domain.UserRegister{
|
|
Username: "urec",
|
|
Email: "mail@atod.com",
|
|
Password: "password",
|
|
Password2: "password",
|
|
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
},
|
|
servBehavior: func(s *mock_service.MockServ, userData domain.UserRegister, token string, err error) {
|
|
s.EXPECT().Register(userData).Return(token, err)
|
|
},
|
|
servErr: domain.AnyError,
|
|
logErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusInternalServerError,
|
|
},
|
|
{
|
|
name: "response_writing_error",
|
|
reqBody: domain.UserRegister{
|
|
Username: "urec",
|
|
Email: "mail@atod.com",
|
|
Password: "password",
|
|
Password2: "password",
|
|
DateOfBirth: domain.CustomDate{Time: time.Date(2002, time.February, 2, 0, 0, 0, 0, time.UTC)},
|
|
},
|
|
servBehavior: func(s *mock_service.MockServ, userData domain.UserRegister, token string, err error) {
|
|
s.EXPECT().Register(userData).Return(token, err)
|
|
},
|
|
writeErr: domain.AnyError,
|
|
logErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusCreated,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testTable {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
reqPath := "/register"
|
|
log := logger.NewLogger(config.Config{Mode: "TEST"})
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
tc.servBehavior(serv, tc.reqBody, tc.servToken, tc.servErr)
|
|
|
|
var body []byte
|
|
if !tc.isDecodeError {
|
|
b, err := json.Marshal(tc.reqBody)
|
|
assert.NoError(t, err)
|
|
body = b
|
|
} else {
|
|
b := make([]byte, 0)
|
|
body = b
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodPost, reqPath, bytes.NewBuffer(body))
|
|
w := mock_http.NewRecorder(tc.writeErr)
|
|
|
|
h := &Handler{serv: serv, l: log}
|
|
|
|
h.Register(w, req)
|
|
|
|
resp := w.Result()
|
|
b, err := io.ReadAll(resp.Body)
|
|
assert.NoError(t, err)
|
|
|
|
var authToken map[string]string
|
|
|
|
if tc.expectedStatusCode == http.StatusCreated && tc.writeErr == nil {
|
|
err = json.Unmarshal(b, &authToken)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
assert.Equal(t, tc.expectedBody, authToken)
|
|
assert.Equal(t, tc.expectedStatusCode, resp.StatusCode)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHandler_ResendEmailVerification(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
log := logger.NewLogger(config.Config{Mode: "TEST"})
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
req := httptest.NewRequest("", "/chats", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
h := &Handler{serv: serv, l: log}
|
|
|
|
h.ResendEmailVerification(w, req)
|
|
|
|
_ = w.Result()
|
|
}
|
|
|
|
func TestHandler_EmailVerification(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
log := logger.NewLogger(config.Config{Mode: "TEST"})
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
req := httptest.NewRequest("", "/chats", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
h := &Handler{serv: serv, l: log}
|
|
|
|
h.EmailVerification(w, req)
|
|
|
|
_ = w.Result()
|
|
}
|
|
|
|
func TestHandler_Login(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
log := logger.NewLogger(config.Config{Mode: "TEST"})
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
req := httptest.NewRequest("", "/chats", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
h := &Handler{serv: serv, l: log}
|
|
|
|
h.Login(w, req)
|
|
|
|
_ = w.Result()
|
|
}
|
|
|
|
func TestHandler_Get(t *testing.T) {
|
|
testTable := []struct {
|
|
name string
|
|
ctxUser domain.User
|
|
addingCtxUser bool
|
|
logErr error
|
|
writeErr error
|
|
expectedUser domain.User
|
|
expectedStatusCode int
|
|
}{
|
|
{
|
|
name: "ok",
|
|
ctxUser: domain.User{
|
|
ID: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
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)},
|
|
},
|
|
addingCtxUser: true,
|
|
expectedUser: domain.User{
|
|
ID: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
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)},
|
|
},
|
|
expectedStatusCode: http.StatusOK,
|
|
},
|
|
{
|
|
name: "incorrect_user_in_ctx",
|
|
expectedStatusCode: http.StatusInternalServerError,
|
|
},
|
|
{
|
|
name: "response_writing_error",
|
|
ctxUser: domain.User{
|
|
ID: 1,
|
|
Username: "urec",
|
|
Email: "mail@mail.ru",
|
|
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)},
|
|
},
|
|
addingCtxUser: true,
|
|
logErr: domain.AnyError,
|
|
writeErr: domain.AnyError,
|
|
expectedStatusCode: http.StatusInternalServerError,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testTable {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
reqPath := "/users/me"
|
|
log := logger.NewLogger(config.Config{Mode: "TEST"})
|
|
|
|
req := httptest.NewRequest(http.MethodGet, reqPath, nil)
|
|
w := mock_http.NewRecorder(tc.writeErr)
|
|
ctx := req.Context()
|
|
if tc.addingCtxUser {
|
|
ctx = context.WithValue(ctx, "user", tc.ctxUser)
|
|
}
|
|
req = req.WithContext(ctx)
|
|
|
|
h := &Handler{l: log}
|
|
|
|
h.Get(w, req)
|
|
|
|
resp := w.Result()
|
|
b, err := io.ReadAll(resp.Body)
|
|
assert.NoError(t, err)
|
|
|
|
var u domain.User
|
|
|
|
if tc.expectedStatusCode == http.StatusOK {
|
|
err = json.Unmarshal(b, &u)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
assert.Equal(t, tc.expectedUser, u)
|
|
assert.Equal(t, tc.expectedStatusCode, resp.StatusCode)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHandler_GetAvatarsHistory(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
log := logger.NewLogger(config.Config{Mode: "TEST"})
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
req := httptest.NewRequest("", "/chats", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
h := &Handler{serv: serv, l: log}
|
|
|
|
h.GetAvatarsHistory(w, req)
|
|
|
|
_ = w.Result()
|
|
}
|
|
|
|
func TestHandler_SendConfirmationCode(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
log := logger.NewLogger(config.Config{Mode: "TEST"})
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
req := httptest.NewRequest("", "/chats", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
h := &Handler{serv: serv, l: log}
|
|
|
|
h.SendConfirmationCode(w, req)
|
|
|
|
_ = w.Result()
|
|
}
|
|
|
|
func TestHandler_ChangeUserData(t *testing.T) {
|
|
c := gomock.NewController(t)
|
|
defer c.Finish()
|
|
|
|
log := logger.NewLogger(config.Config{Mode: "TEST"})
|
|
serv := mock_service.NewMockServ(c)
|
|
|
|
req := httptest.NewRequest("", "/chats", nil)
|
|
w := httptest.NewRecorder()
|
|
|
|
h := &Handler{serv: serv, l: log}
|
|
|
|
h.ChangeUserData(w, req)
|
|
|
|
_ = w.Result()
|
|
}
|