From 01cf1c900bb235c6e2b0aca4476a6e9cad6bb029 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 26 May 2024 14:47:58 +0300 Subject: [PATCH 1/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=B0=D0=B2=D1=82=D0=BE=D1=80=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 1 + .../authorization/auth_handler_test.go | 231 ++++++++++++------ .../authorization/authorization_handler.go | 6 +- internal/usecase/user_usecase.go | 2 +- 4 files changed, 162 insertions(+), 78 deletions(-) diff --git a/go.mod b/go.mod index 09b009c..59f35a0 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/lib/pq v1.10.2 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/swaggo/files v0.0.0-20220610200504-28940afbdbfe // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/tools v0.20.0 // indirect diff --git a/internal/delivery/handlers/authorization/auth_handler_test.go b/internal/delivery/handlers/authorization/auth_handler_test.go index d7b13e8..47152b1 100644 --- a/internal/delivery/handlers/authorization/auth_handler_test.go +++ b/internal/delivery/handlers/authorization/auth_handler_test.go @@ -1,76 +1,159 @@ package authorization_test -// import ( -// "context" -// "encoding/json" -// "net/http" -// "net/http/httptest" -// "strings" -// "testing" - -// "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" -// // "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/http-server/handlers/login" -// "github.com/stretchr/testify/assert" -// ) - -// func TestAuthorize(t *testing.T) { -// authHandler := login.Authorization{} - -// entities.CreateUser("san", "123") - -// testCases := []struct { -// name string -// inputJSON string -// expectedStatus int -// expectedError string -// }{ -// { -// name: "Successful authorization", -// inputJSON: `{"username": "san", "password": "123"}`, -// expectedStatus: http.StatusOK, -// expectedError: "", -// }, -// { -// name: "Empty username", -// inputJSON: `{"username": "", "password": "testpassword"}`, -// expectedStatus: http.StatusUnauthorized, -// expectedError: "Authorization failed", -// }, -// { -// name: "Empty password", -// inputJSON: `{"username": "testuser", "password": ""}`, -// expectedStatus: http.StatusUnauthorized, -// expectedError: "Authorization failed", -// }, -// { -// name: "User not found", -// inputJSON: `{"username": "nonexistentuser", "password": "testpassword"}`, -// expectedStatus: http.StatusUnauthorized, -// expectedError: "Authorization failed", -// }, -// } - -// for _, tc := range testCases { -// t.Run(tc.name, func(t *testing.T) { -// req, err := http.NewRequest("POST", "/login", strings.NewReader(tc.inputJSON)) -// if err != nil { -// t.Fatal(err) -// } -// req.Header.Set("Content-Type", "application/json") - -// var user entities.User -// err = json.NewDecoder(req.Body).Decode(&user) -// if err != nil { -// t.Fatal(err) -// } - -// rr := httptest.NewRecorder() -// ctx := context.WithValue(req.Context(), "responseWriter", rr) -// ctx = context.WithValue(ctx, "requestData", user) - -// response, err := authHandler.Authorize(ctx) - -// assert.Equal(t, tc.expectedStatus, response.Status, "handler returned wrong status code") -// }) -// } -// } +import ( + "bytes" + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/delivery/handlers/authorization" + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/httputils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +type MockSessionUseCase struct { + mock.Mock +} + +func (m *MockSessionUseCase) CreateSession(ctx context.Context, w http.ResponseWriter, userID int) error { + args := m.Called(ctx, w, userID) + return args.Error(0) +} + +func (m *MockSessionUseCase) GetSession(ctx context.Context, r *http.Request) (int, error) { + args := m.Called(ctx, r) + return args.Int(0), args.Error(1) +} + +func (m *MockSessionUseCase) ClearSession(ctx context.Context, w http.ResponseWriter, r *http.Request) error { + args := m.Called(ctx, w, r) + return args.Error(0) +} + +type MockUserUseCase struct { + mock.Mock +} + +func (m *MockUserUseCase) CreateUser(ctx context.Context, email string, password string) error { + args := m.Called(ctx, email, password) + return args.Error(0) +} + +func (m *MockUserUseCase) GetUserByEmail(ctx context.Context, email string) (entities.User, error) { + args := m.Called(ctx, email) + return args.Get(0).(entities.User), args.Error(1) +} + +func (m *MockUserUseCase) GetUserByID(ctx context.Context, userID int) (entities.User, error) { + args := m.Called(ctx, userID) + return args.Get(0).(entities.User), args.Error(1) +} + +func (m *MockUserUseCase) DeleteUser(ctx context.Context, userID int) error { + args := m.Called(ctx, userID) + return args.Error(0) +} + +func (m *MockUserUseCase) UserDataVerification(email, password string) error { + args := m.Called(email, password) + return args.Error(0) +} + +func (m *MockUserUseCase) ChangePassword(ctx context.Context, userID int, password string) (entities.User, error) { + args := m.Called(ctx, userID, password) + return args.Get(0).(entities.User), args.Error(1) +} + +func (m *MockUserUseCase) UserExists(ctx context.Context, email, password string) error { + args := m.Called(ctx, email, password) + return args.Error(0) +} + +func (m *MockUserUseCase) IsEmailTaken(ctx context.Context, email string) (bool, error) { + args := m.Called(ctx, email) + return args.Bool(0), args.Error(1) +} + +func TestAuthorizationHandler_Authorize(t *testing.T) { + println("________________________________________________________________________") + mockSessionUseCase := new(MockSessionUseCase) + mockUserUseCase := new(MockUserUseCase) + + handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) + + // Тест успешной авторизации + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) + mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + + // Создаем тестовый запрос + user := entities.User{Username: "san@boy.ru", Password: "ABC123abc123!"} + jsonUser, err := json.Marshal(user) + if err != nil { + t.Fatal(err) + } + + req, err := http.NewRequest("POST", "/api/login", bytes.NewBuffer(jsonUser)) + if err != nil { + t.Fatal(err) + } + + // Создаем ResponseRecorder для записи ответа + rr := httptest.NewRecorder() + + // Добавляем запрос в контекст + ctx := context.WithValue(req.Context(), httputils.HttpRequestKey, req) + ctx = context.WithValue(ctx, httputils.ResponseWriterKey, rr) + + userResponse, err := handler.Authorize(ctx, user) + assert.NoError(t, err) + assert.Equal(t, entities.UserResponse{ID: 1, Username: "san@boy.ru"}, userResponse) + // Проверяем код ответа + assert.Equal(t, http.StatusOK, rr.Code) + + // Проверяем, что методы были вызваны с правильными аргументами + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) +} + +// Тесты для LogOut +//func TestAuthorizationHandler_LogOut(t *testing.T) { +// mockSessionUseCase := new(MockSessionUseCase) +// mockUserUseCase := new(MockUserUseCase) +// +// handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) +// +// // Тест успешного выхода из системы +// mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil) +// mockSessionUseCase.On("ClearSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) +// +// _, err := handler.LogOut(context.Background(), entities.User{}) +// assert.NoError(t, err) +// +// // Добавьте дополнительные тесты для других случаев, таких как ошибки получения сессии и ошибки очистки сессии +//} +// +//// Тесты для UpdatePassword +//func TestAuthorizationHandler_UpdatePassword(t *testing.T) { +// mockSessionUseCase := new(MockSessionUseCase) +// mockUserUseCase := new(MockUserUseCase) +// +// handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) +// +// // Тест успешного обновления пароля +// mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil) +// mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) +// mockUserUseCase.On("ChangePassword", mock.Anything, mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "testuser"}, nil) +// +// userResponse, err := handler.UpdatePassword(context.Background(), entities.User{Username: "testuser", Password: "newpassword"}) +// assert.NoError(t, err) +// assert.Equal(t, entities.UserResponse{ID: 1, Username: "testuser"}, userResponse) +// +// // Добавьте дополнительные тесты для других случаев, таких как ошибки валидации данных пользователя, ошибки изменения пароля и т.д. +//} diff --git a/internal/delivery/handlers/authorization/authorization_handler.go b/internal/delivery/handlers/authorization/authorization_handler.go index e7150ab..97abc75 100644 --- a/internal/delivery/handlers/authorization/authorization_handler.go +++ b/internal/delivery/handlers/authorization/authorization_handler.go @@ -11,11 +11,11 @@ import ( ) type AuthorizationHandler struct { - sessionUseCase *usecase.SessionUseCase - userUseCase *usecase.UserUseCase + sessionUseCase usecase.SessionInterface + userUseCase usecase.UserUseCaseInterface } -func NewAuthorizationHandler(sessionUseCase *usecase.SessionUseCase, userUseCase *usecase.UserUseCase) *AuthorizationHandler { +func NewAuthorizationHandler(sessionUseCase usecase.SessionInterface, userUseCase usecase.UserUseCaseInterface) *AuthorizationHandler { return &AuthorizationHandler{ sessionUseCase: sessionUseCase, userUseCase: userUseCase, diff --git a/internal/usecase/user_usecase.go b/internal/usecase/user_usecase.go index 1938304..3fb8266 100644 --- a/internal/usecase/user_usecase.go +++ b/internal/usecase/user_usecase.go @@ -18,7 +18,7 @@ type UserUseCaseInterface interface { GetUserByEmail(ctx context.Context, email string) (entities.User, error) GetUserByID(ctx context.Context, userID int) (entities.User, error) DeleteUser(ctx context.Context, userID int) error - UserDataVerification(ctx context.Context, email, password string) error + UserDataVerification(email, password string) error ChangePassword(ctx context.Context, userID int, password string) (entities.User, error) UserExists(ctx context.Context, email, password string) error IsEmailTaken(ctx context.Context, email string) (bool, error) From 530bb8126e16fbd23816c8943f01420f657b0356 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 28 May 2024 14:29:25 +0300 Subject: [PATCH 2/6] =?UTF-8?q?=D0=9F=D0=BE=D0=BA=D1=80=D1=8B=D1=82=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=80=D1=83=D1=87=D0=BA=D0=B8=20=D0=B0=D0=B2=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../authorization/auth_handler_test.go | 503 ++++++++++++++++-- .../authorization/authorization_handler.go | 8 +- .../storage/postgres/user/user_storage.go | 7 + internal/usecase/session_usecase.go | 5 +- internal/usecase/user_usecase.go | 6 +- utils/httputils/httputils.go | 6 +- 6 files changed, 461 insertions(+), 74 deletions(-) diff --git a/internal/delivery/handlers/authorization/auth_handler_test.go b/internal/delivery/handlers/authorization/auth_handler_test.go index 47152b1..10c7c8a 100644 --- a/internal/delivery/handlers/authorization/auth_handler_test.go +++ b/internal/delivery/handlers/authorization/auth_handler_test.go @@ -10,7 +10,9 @@ import ( "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/delivery/handlers/authorization" "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + httperrors "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/errors" "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/httputils" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ) @@ -78,82 +80,465 @@ func (m *MockUserUseCase) IsEmailTaken(ctx context.Context, email string) (bool, return args.Bool(0), args.Error(1) } +// Тесты для авторизации func TestAuthorizationHandler_Authorize(t *testing.T) { - println("________________________________________________________________________") mockSessionUseCase := new(MockSessionUseCase) mockUserUseCase := new(MockUserUseCase) handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) - // Тест успешной авторизации - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) - mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) - - // Создаем тестовый запрос user := entities.User{Username: "san@boy.ru", Password: "ABC123abc123!"} jsonUser, err := json.Marshal(user) if err != nil { - t.Fatal(err) + assert.NoError(t, err) } req, err := http.NewRequest("POST", "/api/login", bytes.NewBuffer(jsonUser)) if err != nil { - t.Fatal(err) + assert.NoError(t, err) + } + + // Создание ResponseRecorder для записи ответа + rr := httptest.NewRecorder() + + t.Run("Request without request key", func(t *testing.T) { + userResponse, err := handler.Authorize(context.Background(), user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + assert.Equal(t, "failed getting request", err.Error()) + }) + + // Добавление запроса в контекст + ctx := context.WithValue(req.Context(), httputils.HttpRequestKey, req) + + t.Run("Request without response writer key", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) + mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + + userResponse, err := handler.Authorize(ctx, user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + assert.Equal(t, "failed getting response writer", err.Error()) + }) + + // добавление ключа ответа в контекст + ctx = context.WithValue(ctx, httputils.ResponseWriterKey, rr) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Successful authorization", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) + mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + + userResponse, err := handler.Authorize(ctx, user) + assert.NoError(t, err) + assert.Equal(t, entities.UserResponse{ID: 1, Username: "san@boy.ru"}, userResponse) + assert.Equal(t, http.StatusOK, rr.Code) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Wrong username", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "user not found"}) + + userResponse, err := handler.Authorize(ctx, user) + + assert.Error(t, err) + assert.IsType(t, httperrors.HttpError{}, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "user not found", httpError.Message) + assert.Equal(t, http.StatusBadRequest, httpError.Code) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Incorrect username", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "email doesn't meet requirements"}) + + userResponse, err := handler.Authorize(ctx, user) + + assert.Error(t, err) + assert.IsType(t, httperrors.HttpError{}, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "email doesn't meet requirements", httpError.Message) + assert.Equal(t, http.StatusBadRequest, httpError.Code) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Incorrect password", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "password doesn't meet requirements"}) + + userResponse, err := handler.Authorize(ctx, user) + + assert.Error(t, err) + assert.IsType(t, httperrors.HttpError{}, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "password doesn't meet requirements", httpError.Message) + assert.Equal(t, http.StatusBadRequest, httpError.Code) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Failed getting user by username", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{}, httperrors.HttpError{Code: http.StatusBadRequest, Message: "user not found"}) + + userResponse, err := handler.Authorize(ctx, user) + + assert.Error(t, err) + assert.IsType(t, httperrors.HttpError{}, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "user not found", httpError.Message) + assert.Equal(t, http.StatusBadRequest, httpError.Code) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Failed creating session", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) + mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("unexpected error")) + + userResponse, err := handler.Authorize(ctx, user) + + assert.Error(t, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "unexpected error", httpError.Message) + assert.Equal(t, http.StatusInternalServerError, httpError.Code) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Cookie not found", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, httperrors.HttpError{Code: http.StatusBadRequest, Message: "cookie not found"}) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) + mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + + userResponse, err := handler.Authorize(ctx, user) + + assert.NoError(t, err) + assert.Equal(t, entities.UserResponse{ID: 1, Username: "san@boy.ru"}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Error decoding cookie", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, errors.New("error decoding cookie")) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) + mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + + userResponse, err := handler.Authorize(ctx, user) + + assert.NoError(t, err) + assert.Equal(t, entities.UserResponse{ID: 1, Username: "san@boy.ru"}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Unexpected error getting session", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, errors.New("unexpected error")) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) + mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + + userResponse, err := handler.Authorize(ctx, user) + + assert.Error(t, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "unexpected error", httpError.Message) + assert.Equal(t, http.StatusInternalServerError, httpError.Code) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("User is already authorised", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil) + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) + mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + + userResponse, err := handler.Authorize(ctx, user) + + assert.Error(t, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "user is already authorized", httpError.Message) + assert.Equal(t, http.StatusBadRequest, httpError.Code) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) +} + +// Тесты для выхода из аккаунта +func TestAuthorizationHandler_LogOut(t *testing.T) { + mockSessionUseCase := new(MockSessionUseCase) + mockUserUseCase := new(MockUserUseCase) + + handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) + + user := entities.User{} + jsonUser, err := json.Marshal(user) + if err != nil { + assert.NoError(t, err) } - // Создаем ResponseRecorder для записи ответа + // Создание запроса + req, err := http.NewRequest("POST", "/api/logout", bytes.NewBuffer(jsonUser)) + if err != nil { + assert.NoError(t, err) + } + + // Создание ResponseRecorder для записи ответа rr := httptest.NewRecorder() - // Добавляем запрос в контекст + t.Run("Request without request key", func(t *testing.T) { + userResponse, err := handler.LogOut(context.Background(), user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + assert.Equal(t, "failed getting request", err.Error()) + }) + + // Добавление запроса в контекст ctx := context.WithValue(req.Context(), httputils.HttpRequestKey, req) + + t.Run("Request without response writer key", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) + + userResponse, err := handler.LogOut(ctx, user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + assert.Equal(t, "failed getting response writer", err.Error()) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + // добавление ключа ответа в контекст ctx = context.WithValue(ctx, httputils.ResponseWriterKey, rr) - userResponse, err := handler.Authorize(ctx, user) - assert.NoError(t, err) - assert.Equal(t, entities.UserResponse{ID: 1, Username: "san@boy.ru"}, userResponse) - // Проверяем код ответа - assert.Equal(t, http.StatusOK, rr.Code) - - // Проверяем, что методы были вызваны с правильными аргументами - mockSessionUseCase.AssertExpectations(t) - mockUserUseCase.AssertExpectations(t) -} - -// Тесты для LogOut -//func TestAuthorizationHandler_LogOut(t *testing.T) { -// mockSessionUseCase := new(MockSessionUseCase) -// mockUserUseCase := new(MockUserUseCase) -// -// handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) -// -// // Тест успешного выхода из системы -// mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil) -// mockSessionUseCase.On("ClearSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) -// -// _, err := handler.LogOut(context.Background(), entities.User{}) -// assert.NoError(t, err) -// -// // Добавьте дополнительные тесты для других случаев, таких как ошибки получения сессии и ошибки очистки сессии -//} -// -//// Тесты для UpdatePassword -//func TestAuthorizationHandler_UpdatePassword(t *testing.T) { -// mockSessionUseCase := new(MockSessionUseCase) -// mockUserUseCase := new(MockUserUseCase) -// -// handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) -// -// // Тест успешного обновления пароля -// mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil) -// mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) -// mockUserUseCase.On("ChangePassword", mock.Anything, mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "testuser"}, nil) -// -// userResponse, err := handler.UpdatePassword(context.Background(), entities.User{Username: "testuser", Password: "newpassword"}) -// assert.NoError(t, err) -// assert.Equal(t, entities.UserResponse{ID: 1, Username: "testuser"}, userResponse) -// -// // Добавьте дополнительные тесты для других случаев, таких как ошибки валидации данных пользователя, ошибки изменения пароля и т.д. -//} + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Cookie not found", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, httperrors.HttpError{Code: http.StatusUnauthorized, Message: "cookie not found"}) + + userResponse, err := handler.LogOut(ctx, user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "cookie not found", httpError.Message) + assert.Equal(t, http.StatusUnauthorized, httpError.Code) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Error clearing session", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil) + mockSessionUseCase.On("ClearSession", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("error clearing session")) + + userResponse, err := handler.LogOut(ctx, user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "error clearing session", httpError.Message) + assert.Equal(t, http.StatusInternalServerError, httpError.Code) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Success log out", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil).Once() + mockSessionUseCase.On("ClearSession", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + + userResponse, err := handler.LogOut(ctx, user) + + assert.NoError(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) +} + +// Тесты для обновления пароля +func TestAuthorizationHandler_UpdatePassword(t *testing.T) { + mockSessionUseCase := new(MockSessionUseCase) + mockUserUseCase := new(MockUserUseCase) + + handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) + + user := entities.User{Username: "san@boys.ru", Password: "ABC123abc1234!"} + jsonUser, err := json.Marshal(user) + if err != nil { + assert.NoError(t, err) + } + + req, err := http.NewRequest("POST", "/api/login", bytes.NewBuffer(jsonUser)) + if err != nil { + assert.NoError(t, err) + } + + t.Run("Request without request key", func(t *testing.T) { + userResponse, err := handler.UpdatePassword(context.Background(), user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + assert.Equal(t, "failed getting request", err.Error()) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + // Добавление запроса в контекст + ctx := context.WithValue(req.Context(), httputils.HttpRequestKey, req) + + t.Run("Cookie nit found", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, httperrors.HttpError{Code: http.StatusBadRequest, Message: "cookie not found"}).Once() + + userResponse, err := handler.UpdatePassword(ctx, user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "cookie not found", httpError.Message) + assert.Equal(t, http.StatusBadRequest, httpError.Code) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Incorrect username", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil).Once() + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "email doesn't meet requirements"}).Once() + + userResponse, err := handler.UpdatePassword(ctx, user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "email doesn't meet requirements", httpError.Message) + assert.Equal(t, http.StatusBadRequest, httpError.Code) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Error changing password", func(t *testing.T) { + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil).Once() + mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil).Once() + mockUserUseCase.On("ChangePassword", mock.Anything, mock.Anything, mock.Anything).Return(entities.User{}, errors.New("failed changing password")).Once() + + userResponse, err := handler.UpdatePassword(ctx, user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "failed changing password", httpError.Message) + assert.Equal(t, http.StatusInternalServerError, httpError.Code) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Success changing password", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(1, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boys.ru", "ABC123abc1234!").Return(nil).Once() + mockUserUseCase.On("ChangePassword", ctx, 1, "ABC123abc1234!").Return(entities.User{ID: 1, Username: "san@boys.ru"}, nil).Once() + + userResponse, err := handler.UpdatePassword(ctx, user) + + assert.NoError(t, err) + assert.Equal(t, entities.UserResponse{ID: 1, Username: "san@boys.ru"}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) +} diff --git a/internal/delivery/handlers/authorization/authorization_handler.go b/internal/delivery/handlers/authorization/authorization_handler.go index 97abc75..5785a93 100644 --- a/internal/delivery/handlers/authorization/authorization_handler.go +++ b/internal/delivery/handlers/authorization/authorization_handler.go @@ -33,18 +33,14 @@ func (h *AuthorizationHandler) Authorize(ctx context.Context, requestData entiti sessionID, err := h.sessionUseCase.GetSession(ctx, request) if err != nil { - if !httperrors.IsHttpError(err) { - return entities.UserResponse{}, err - } - httpError := httperrors.UnwrapHttpError(err) - if httpError.Message != "Cookie not found" && httpError.Message != "Error decoding cookie" { + if httpError.Message != "cookie not found" && httpError.Message != "error decoding cookie" { return entities.UserResponse{}, httpError } } if sessionID != 0 { - return entities.UserResponse{}, httperrors.NewHttpError(http.StatusBadRequest, "User is already authorized") + return entities.UserResponse{}, httperrors.NewHttpError(http.StatusBadRequest, "user is already authorized") } if err := h.userUseCase.UserDataVerification(username, password); err != nil { diff --git a/internal/storage/postgres/user/user_storage.go b/internal/storage/postgres/user/user_storage.go index 8421a08..ca9adab 100644 --- a/internal/storage/postgres/user/user_storage.go +++ b/internal/storage/postgres/user/user_storage.go @@ -2,9 +2,13 @@ package user import ( "context" + "net/http" "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + httperrors "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/errors" + "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" + "github.com/pkg/errors" ) // UserStorage struct @@ -47,6 +51,9 @@ func (us *UserStorage) GetUserByEmail(ctx context.Context, email string) (entiti var user entities.User err := us.db.QueryRow(ctx, `SELECT id, email, passwrd, salt FROM user_data WHERE email = $1`, email).Scan(&user.ID, &user.Username, &user.Password, &user.Salt) if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + return entities.User{}, httperrors.NewHttpError(http.StatusBadRequest, "user not found") + } return entities.User{}, err } return user, nil diff --git a/internal/usecase/session_usecase.go b/internal/usecase/session_usecase.go index 30cc62c..9b10d25 100644 --- a/internal/usecase/session_usecase.go +++ b/internal/usecase/session_usecase.go @@ -2,7 +2,6 @@ package usecase import ( "context" - "fmt" "net/http" "time" @@ -59,7 +58,7 @@ func (a *SessionUseCase) GetSession(ctx context.Context, r *http.Request) (int, cookie, err := r.Cookie(sessionId) if err != nil { if errors.Is(err, http.ErrNoCookie) { - return 0, httperrors.NewHttpError(http.StatusUnauthorized, "Cookie not found") + return 0, httperrors.NewHttpError(http.StatusUnauthorized, "cookie not found") } return 0, err } @@ -68,7 +67,7 @@ func (a *SessionUseCase) GetSession(ctx context.Context, r *http.Request) (int, if err = CookieHandler.Decode(sessionId, cookie.Value, &sessionID); err == nil { return a.SessionStorage.GetSession(ctx, sessionID) } - return 0, fmt.Errorf("error decoding cookie: %w", err) + return 0, errors.New("error decoding cookie") } func (a *SessionUseCase) ClearSession(ctx context.Context, w http.ResponseWriter, r *http.Request) error { diff --git a/internal/usecase/user_usecase.go b/internal/usecase/user_usecase.go index 3fb8266..5961d38 100644 --- a/internal/usecase/user_usecase.go +++ b/internal/usecase/user_usecase.go @@ -39,7 +39,7 @@ func (u *UserUseCase) CreateUser(ctx context.Context, email, password string) er saltedPassword := password + salt hashPassword, err := bcrypt.GenerateFromPassword([]byte(saltedPassword), bcrypt.DefaultCost) if err != nil { - return errors.New("Failed creating hash password") + return errors.New("failed creating hash password") } err = u.UserStorage.SaveUser(ctx, email, string(hashPassword), salt) @@ -60,10 +60,10 @@ func (u *UserUseCase) DeleteUser(ctx context.Context, userID int) error { func (u *UserUseCase) UserDataVerification(email, password string) error { if !ValidateEmail(email) { - return httperrors.NewHttpError(http.StatusBadRequest, "Email doesn't meet requirements") + return httperrors.NewHttpError(http.StatusBadRequest, "email doesn't meet requirements") } if !ValidatePassword(password) { - return httperrors.NewHttpError(http.StatusBadRequest, "Password doesn't meet requirements") + return httperrors.NewHttpError(http.StatusBadRequest, "password doesn't meet requirements") } return nil diff --git a/utils/httputils/httputils.go b/utils/httputils/httputils.go index 494de4e..d8d3f63 100644 --- a/utils/httputils/httputils.go +++ b/utils/httputils/httputils.go @@ -20,7 +20,7 @@ func SetRequestToCtx(ctx context.Context, r *http.Request) context.Context { func GetRequestFromCtx(ctx context.Context) (*http.Request, error) { r, ok := ctx.Value(HttpRequestKey).(*http.Request) if !ok { - return nil, errors.New("Failed getting request") + return nil, errors.New("failed getting request") } return r, nil } @@ -44,7 +44,7 @@ func SetResponseWriterToCtx(ctx context.Context, w http.ResponseWriter) context. func GetResponseWriterFromCtx(ctx context.Context) (http.ResponseWriter, error) { w, ok := ctx.Value(ResponseWriterKey).(http.ResponseWriter) if !ok { - return nil, errors.New("Failed getting response writer") + return nil, errors.New("failed getting response writer") } return w, nil } @@ -53,7 +53,7 @@ func GetUserFromCtx(ctx context.Context) (int, error) { user := ctx.Value("userID") userID, ok := user.(int) if !ok { - return 0, errors.New("Failed getting user from context") + return 0, errors.New("failed getting user from context") } return userID, nil } From 5a167c2031c393b9648187d85de5cfdde8ba28dc Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 28 May 2024 15:22:33 +0300 Subject: [PATCH 3/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B9=20?= =?UTF-8?q?=D0=B2=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8,=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE?= =?UTF-8?q?=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D0=BE=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2=D0=BE=D0=B2=20?= =?UTF-8?q?=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../authorization/auth_handler_test.go | 107 ++++++++---------- 1 file changed, 49 insertions(+), 58 deletions(-) diff --git a/internal/delivery/handlers/authorization/auth_handler_test.go b/internal/delivery/handlers/authorization/auth_handler_test.go index 10c7c8a..cd9c3c8 100644 --- a/internal/delivery/handlers/authorization/auth_handler_test.go +++ b/internal/delivery/handlers/authorization/auth_handler_test.go @@ -113,11 +113,10 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { ctx := context.WithValue(req.Context(), httputils.HttpRequestKey, req) t.Run("Request without response writer key", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) - mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("UserExists", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil).Once() userResponse, err := handler.Authorize(ctx, user) @@ -133,11 +132,11 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Successful authorization", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) - mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("UserExists", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil).Once() + mockSessionUseCase.On("CreateSession", ctx, rr, 1).Return(nil).Once() userResponse, err := handler.Authorize(ctx, user) assert.NoError(t, err) @@ -152,9 +151,9 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Wrong username", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "user not found"}) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("UserExists", ctx, "san@boy.ru", "ABC123abc123!").Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "user not found"}).Once() userResponse, err := handler.Authorize(ctx, user) @@ -173,8 +172,8 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Incorrect username", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "email doesn't meet requirements"}) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "email doesn't meet requirements"}).Once() userResponse, err := handler.Authorize(ctx, user) @@ -193,8 +192,8 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Incorrect password", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "password doesn't meet requirements"}) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "password doesn't meet requirements"}).Once() userResponse, err := handler.Authorize(ctx, user) @@ -213,10 +212,10 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Failed getting user by username", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{}, httperrors.HttpError{Code: http.StatusBadRequest, Message: "user not found"}) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("UserExists", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{}, httperrors.HttpError{Code: http.StatusBadRequest, Message: "user not found"}).Once() userResponse, err := handler.Authorize(ctx, user) @@ -235,11 +234,11 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Failed creating session", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) - mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("unexpected error")) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("UserExists", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil).Once() + mockSessionUseCase.On("CreateSession", ctx, rr, 1).Return(errors.New("unexpected error")).Once() userResponse, err := handler.Authorize(ctx, user) @@ -257,11 +256,11 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Cookie not found", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, httperrors.HttpError{Code: http.StatusBadRequest, Message: "cookie not found"}) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) - mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, httperrors.HttpError{Code: http.StatusBadRequest, Message: "cookie not found"}).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("UserExists", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil).Once() + mockSessionUseCase.On("CreateSession", ctx, rr, 1).Return(nil).Once() userResponse, err := handler.Authorize(ctx, user) @@ -276,11 +275,11 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Error decoding cookie", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, errors.New("error decoding cookie")) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) - mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, errors.New("error decoding cookie")).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("UserExists", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil).Once() + mockSessionUseCase.On("CreateSession", ctx, rr, 1).Return(nil).Once() userResponse, err := handler.Authorize(ctx, user) @@ -295,11 +294,7 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Unexpected error getting session", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, errors.New("unexpected error")) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) - mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, errors.New("unexpected error")).Once() userResponse, err := handler.Authorize(ctx, user) @@ -317,11 +312,7 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("User is already authorised", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil) - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("UserExists", mock.Anything, mock.Anything, mock.Anything).Return(nil) - mockUserUseCase.On("GetUserByEmail", mock.Anything, mock.Anything).Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil) - mockSessionUseCase.On("CreateSession", mock.Anything, mock.Anything, mock.Anything).Return(nil) + mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil).Once() userResponse, err := handler.Authorize(ctx, user) @@ -370,7 +361,7 @@ func TestAuthorizationHandler_LogOut(t *testing.T) { ctx := context.WithValue(req.Context(), httputils.HttpRequestKey, req) t.Run("Request without response writer key", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, nil) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() userResponse, err := handler.LogOut(ctx, user) @@ -389,7 +380,7 @@ func TestAuthorizationHandler_LogOut(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Cookie not found", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, httperrors.HttpError{Code: http.StatusUnauthorized, Message: "cookie not found"}) + mockSessionUseCase.On("GetSession", ctx, req).Return(0, httperrors.HttpError{Code: http.StatusUnauthorized, Message: "cookie not found"}).Once() userResponse, err := handler.LogOut(ctx, user) @@ -407,8 +398,8 @@ func TestAuthorizationHandler_LogOut(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Error clearing session", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil) - mockSessionUseCase.On("ClearSession", mock.Anything, mock.Anything, mock.Anything).Return(errors.New("error clearing session")) + mockSessionUseCase.On("GetSession", ctx, req).Return(1, nil).Once() + mockSessionUseCase.On("ClearSession", ctx, rr, req).Return(errors.New("error clearing session")).Once() userResponse, err := handler.LogOut(ctx, user) @@ -426,8 +417,8 @@ func TestAuthorizationHandler_LogOut(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Success log out", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil).Once() - mockSessionUseCase.On("ClearSession", mock.Anything, mock.Anything, mock.Anything).Return(nil).Once() + mockSessionUseCase.On("GetSession", ctx, req).Return(1, nil).Once() + mockSessionUseCase.On("ClearSession", ctx, rr, req).Return(nil).Once() userResponse, err := handler.LogOut(ctx, user) @@ -472,7 +463,7 @@ func TestAuthorizationHandler_UpdatePassword(t *testing.T) { ctx := context.WithValue(req.Context(), httputils.HttpRequestKey, req) t.Run("Cookie nit found", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(0, httperrors.HttpError{Code: http.StatusBadRequest, Message: "cookie not found"}).Once() + mockSessionUseCase.On("GetSession", ctx, req).Return(0, httperrors.HttpError{Code: http.StatusBadRequest, Message: "cookie not found"}).Once() userResponse, err := handler.UpdatePassword(ctx, user) @@ -490,8 +481,8 @@ func TestAuthorizationHandler_UpdatePassword(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Incorrect username", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil).Once() - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "email doesn't meet requirements"}).Once() + mockSessionUseCase.On("GetSession", ctx, req).Return(1, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boys.ru", "ABC123abc1234!").Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "email doesn't meet requirements"}).Once() userResponse, err := handler.UpdatePassword(ctx, user) @@ -509,9 +500,9 @@ func TestAuthorizationHandler_UpdatePassword(t *testing.T) { mockSessionUseCase.Mock.ExpectedCalls = nil t.Run("Error changing password", func(t *testing.T) { - mockSessionUseCase.On("GetSession", mock.Anything, mock.Anything).Return(1, nil).Once() - mockUserUseCase.On("UserDataVerification", mock.Anything, mock.Anything).Return(nil).Once() - mockUserUseCase.On("ChangePassword", mock.Anything, mock.Anything, mock.Anything).Return(entities.User{}, errors.New("failed changing password")).Once() + mockSessionUseCase.On("GetSession", ctx, req).Return(1, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boys.ru", "ABC123abc1234!").Return(nil).Once() + mockUserUseCase.On("ChangePassword", ctx, 1, "ABC123abc1234!").Return(entities.User{}, errors.New("failed changing password")).Once() userResponse, err := handler.UpdatePassword(ctx, user) From d5ef3c5b1937f1e8de0c663475c0b9f89059fb27 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 28 May 2024 21:09:25 +0300 Subject: [PATCH 4/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=80=D1=83=D1=87=D0=BA=D0=B8=20=D1=80?= =?UTF-8?q?=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../authorization/auth_handler_test.go | 77 +--- .../registration/registration_handler.go | 12 +- .../registration/signup_handler_test.go | 329 ++++++++++++++---- 3 files changed, 266 insertions(+), 152 deletions(-) diff --git a/internal/delivery/handlers/authorization/auth_handler_test.go b/internal/delivery/handlers/authorization/auth_handler_test.go index cd9c3c8..22c3fb8 100644 --- a/internal/delivery/handlers/authorization/auth_handler_test.go +++ b/internal/delivery/handlers/authorization/auth_handler_test.go @@ -10,6 +10,7 @@ import ( "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/delivery/handlers/authorization" "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/mocks" httperrors "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/errors" "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/httputils" "github.com/pkg/errors" @@ -17,73 +18,10 @@ import ( "github.com/stretchr/testify/mock" ) -type MockSessionUseCase struct { - mock.Mock -} - -func (m *MockSessionUseCase) CreateSession(ctx context.Context, w http.ResponseWriter, userID int) error { - args := m.Called(ctx, w, userID) - return args.Error(0) -} - -func (m *MockSessionUseCase) GetSession(ctx context.Context, r *http.Request) (int, error) { - args := m.Called(ctx, r) - return args.Int(0), args.Error(1) -} - -func (m *MockSessionUseCase) ClearSession(ctx context.Context, w http.ResponseWriter, r *http.Request) error { - args := m.Called(ctx, w, r) - return args.Error(0) -} - -type MockUserUseCase struct { - mock.Mock -} - -func (m *MockUserUseCase) CreateUser(ctx context.Context, email string, password string) error { - args := m.Called(ctx, email, password) - return args.Error(0) -} - -func (m *MockUserUseCase) GetUserByEmail(ctx context.Context, email string) (entities.User, error) { - args := m.Called(ctx, email) - return args.Get(0).(entities.User), args.Error(1) -} - -func (m *MockUserUseCase) GetUserByID(ctx context.Context, userID int) (entities.User, error) { - args := m.Called(ctx, userID) - return args.Get(0).(entities.User), args.Error(1) -} - -func (m *MockUserUseCase) DeleteUser(ctx context.Context, userID int) error { - args := m.Called(ctx, userID) - return args.Error(0) -} - -func (m *MockUserUseCase) UserDataVerification(email, password string) error { - args := m.Called(email, password) - return args.Error(0) -} - -func (m *MockUserUseCase) ChangePassword(ctx context.Context, userID int, password string) (entities.User, error) { - args := m.Called(ctx, userID, password) - return args.Get(0).(entities.User), args.Error(1) -} - -func (m *MockUserUseCase) UserExists(ctx context.Context, email, password string) error { - args := m.Called(ctx, email, password) - return args.Error(0) -} - -func (m *MockUserUseCase) IsEmailTaken(ctx context.Context, email string) (bool, error) { - args := m.Called(ctx, email) - return args.Bool(0), args.Error(1) -} - // Тесты для авторизации func TestAuthorizationHandler_Authorize(t *testing.T) { - mockSessionUseCase := new(MockSessionUseCase) - mockUserUseCase := new(MockUserUseCase) + mockSessionUseCase := new(mocks.MockSessionUseCase) + mockUserUseCase := new(mocks.MockUserUseCase) handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) @@ -93,6 +31,7 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { assert.NoError(t, err) } + // Создание запроса для добавления в контекст req, err := http.NewRequest("POST", "/api/login", bytes.NewBuffer(jsonUser)) if err != nil { assert.NoError(t, err) @@ -329,8 +268,8 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { // Тесты для выхода из аккаунта func TestAuthorizationHandler_LogOut(t *testing.T) { - mockSessionUseCase := new(MockSessionUseCase) - mockUserUseCase := new(MockUserUseCase) + mockSessionUseCase := new(mocks.MockSessionUseCase) + mockUserUseCase := new(mocks.MockUserUseCase) handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) @@ -432,8 +371,8 @@ func TestAuthorizationHandler_LogOut(t *testing.T) { // Тесты для обновления пароля func TestAuthorizationHandler_UpdatePassword(t *testing.T) { - mockSessionUseCase := new(MockSessionUseCase) - mockUserUseCase := new(MockUserUseCase) + mockSessionUseCase := new(mocks.MockSessionUseCase) + mockUserUseCase := new(mocks.MockUserUseCase) handler := authorization.NewAuthorizationHandler(mockSessionUseCase, mockUserUseCase) diff --git a/internal/delivery/handlers/registration/registration_handler.go b/internal/delivery/handlers/registration/registration_handler.go index 07ff844..a8aad68 100644 --- a/internal/delivery/handlers/registration/registration_handler.go +++ b/internal/delivery/handlers/registration/registration_handler.go @@ -11,11 +11,11 @@ import ( ) type RegistrationHandler struct { - sessionUseCase *usecase.SessionUseCase - userUseCase *usecase.UserUseCase + sessionUseCase usecase.SessionInterface + userUseCase usecase.UserUseCaseInterface } -func NewRegistrationHandler(sessionUseCase *usecase.SessionUseCase, userUseCase *usecase.UserUseCase) *RegistrationHandler { +func NewRegistrationHandler(sessionUseCase usecase.SessionInterface, userUseCase usecase.UserUseCaseInterface) *RegistrationHandler { return &RegistrationHandler{ sessionUseCase: sessionUseCase, userUseCase: userUseCase, @@ -34,13 +34,13 @@ func (h *RegistrationHandler) SignUp(ctx context.Context, requestData entities.U sessionID, err := h.sessionUseCase.GetSession(ctx, request) if err != nil { httpError := httperrors.UnwrapHttpError(err) - if httpError.Message != "Session not found" && httpError.Message != "Cookie not found" && httpError.Message != "Error decoding cookie" { + if httpError.Message != "cookie not found" && httpError.Message != "error decoding cookie" { return entities.UserResponse{}, httpError } } if sessionID != 0 { - return entities.UserResponse{}, httperrors.NewHttpError(http.StatusBadRequest, "User is already authorized") + return entities.UserResponse{}, httperrors.NewHttpError(http.StatusBadRequest, "user is already authorized") } taken, err := h.userUseCase.IsEmailTaken(ctx, username) @@ -48,7 +48,7 @@ func (h *RegistrationHandler) SignUp(ctx context.Context, requestData entities.U return entities.UserResponse{}, err } if taken { - return entities.UserResponse{}, httperrors.NewHttpError(http.StatusBadRequest, "Username is taken") + return entities.UserResponse{}, httperrors.NewHttpError(http.StatusBadRequest, "username is taken") } if err := h.userUseCase.UserDataVerification(username, password); err != nil { diff --git a/internal/delivery/handlers/registration/signup_handler_test.go b/internal/delivery/handlers/registration/signup_handler_test.go index 628f664..bc1bfad 100644 --- a/internal/delivery/handlers/registration/signup_handler_test.go +++ b/internal/delivery/handlers/registration/signup_handler_test.go @@ -1,79 +1,254 @@ package registration_test -// import ( -// "context" -// "encoding/json" -// "net/http" -// "strings" -// "testing" - -// "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" -// "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/http-server/handlers/registration" -// "github.com/stretchr/testify/assert" -// ) - -// func TestSignUp(t *testing.T) { -// regHandler := registration.Registration{} - -// testCases := []struct { -// name string -// inputJSON string -// expectedStatus int -// expectedError string -// }{ -// { -// name: "Successful registration", -// inputJSON: `{"username": "testuser", "password": "testpassword"}`, -// expectedStatus: http.StatusCreated, -// expectedError: "", -// }, -// { -// name: "Empty username", -// inputJSON: `{"username": "", "password": "testpassword"}`, -// expectedStatus: http.StatusBadRequest, -// expectedError: "username and password must not be empty", -// }, -// { -// name: "Empty password", -// inputJSON: `{"username": "testuser", "password": ""}`, -// expectedStatus: http.StatusBadRequest, -// expectedError: "username and password must not be empty", -// }, -// { -// name: "User already exists", -// inputJSON: `{"username": "testuser", "password": "testpassword"}`, -// expectedStatus: http.StatusBadRequest, -// expectedError: "username already exists", -// }, -// } - -// for _, tc := range testCases { -// t.Run(tc.name, func(t *testing.T) { - -// req, err := http.NewRequest("POST", "/signup", strings.NewReader(tc.inputJSON)) -// if err != nil { -// t.Fatal(err) -// } -// req.Header.Set("Content-Type", "application/json") - -// var user entities.User -// err = json.NewDecoder(req.Body).Decode(&user) -// if err != nil { -// t.Fatal(err) -// } - -// ctx := context.WithValue(req.Context(), "requestData", user) - -// response, err := regHandler.SignUp(ctx) -// if err != nil && tc.expectedError == "" { -// t.Errorf("Ошибка при вызове SignUp: %v", err) -// } - -// assert.Equal(t, tc.expectedStatus, response.Status, "handler returned wrong status code") - -// if tc.expectedError != "" { -// assert.EqualError(t, err, tc.expectedError, "handler returned unexpected error message") -// } -// }) -// } -// } +import ( + "bytes" + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/delivery/handlers/registration" + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/mocks" + httperrors "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/errors" + "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/httputils" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" +) + +func TestRegistrationHandler_SignUp(t *testing.T) { + mockSessionUseCase := new(mocks.MockSessionUseCase) + mockUserUseCase := new(mocks.MockUserUseCase) + + handler := registration.NewRegistrationHandler(mockSessionUseCase, mockUserUseCase) + + user := entities.User{Username: "san@boy.ru", Password: "ABC123abc123!"} + jsonUser, err := json.Marshal(user) + if err != nil { + assert.NoError(t, err) + } + + // Создание запроса для добавления в контекст + req, err := http.NewRequest("POST", "/api/signup", bytes.NewBuffer(jsonUser)) + if err != nil { + assert.NoError(t, err) + } + + // Создание ResponseRecorder для записи ответа + rr := httptest.NewRecorder() + + t.Run("Request without request key", func(t *testing.T) { + userResponse, err := handler.SignUp(context.Background(), user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + assert.Equal(t, "failed getting request", err.Error()) + }) + + // Добавление запроса в контекст + ctx := context.WithValue(req.Context(), httputils.HttpRequestKey, req) + + t.Run("Request without response writer key", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("IsEmailTaken", ctx, "san@boy.ru").Return(false, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("CreateUser", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil).Once() + + userResponse, err := handler.SignUp(ctx, user) + + assert.Error(t, err) + assert.Equal(t, entities.UserResponse{}, userResponse) + assert.Equal(t, "failed getting response writer", err.Error()) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + // добавление ключа ответа в контекст + ctx = context.WithValue(ctx, httputils.ResponseWriterKey, rr) + + t.Run("Successful registration", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("IsEmailTaken", ctx, "san@boy.ru").Return(false, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("CreateUser", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil).Once() + mockSessionUseCase.On("CreateSession", ctx, rr, 1).Return(nil).Once() + + userResponse, err := handler.SignUp(ctx, user) + assert.NoError(t, err) + assert.Equal(t, entities.UserResponse{ID: 1, Username: "san@boy.ru"}, userResponse) + assert.Equal(t, http.StatusOK, rr.Code) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Cookie not found", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(0, httperrors.HttpError{Code: http.StatusBadRequest, Message: "cookie not found"}).Once() + mockUserUseCase.On("IsEmailTaken", ctx, "san@boy.ru").Return(false, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("CreateUser", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil).Once() + mockSessionUseCase.On("CreateSession", ctx, rr, 1).Return(nil).Once() + + userResponse, err := handler.SignUp(ctx, user) + assert.NoError(t, err) + assert.Equal(t, entities.UserResponse{ID: 1, Username: "san@boy.ru"}, userResponse) + assert.Equal(t, http.StatusOK, rr.Code) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Error decoding cookie", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(0, httperrors.HttpError{Code: http.StatusInternalServerError, Message: "error decoding cookie"}).Once() + mockUserUseCase.On("IsEmailTaken", ctx, "san@boy.ru").Return(false, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("CreateUser", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil).Once() + mockSessionUseCase.On("CreateSession", ctx, rr, 1).Return(nil).Once() + + userResponse, err := handler.SignUp(ctx, user) + assert.NoError(t, err) + assert.Equal(t, entities.UserResponse{ID: 1, Username: "san@boy.ru"}, userResponse) + assert.Equal(t, http.StatusOK, rr.Code) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Error getting session", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(0, errors.New("unexpected error")).Once() + + userResponse, err := handler.SignUp(ctx, user) + assert.Error(t, err) + assert.Equal(t, "unexpected error", err.Error()) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Authorized user", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(1, nil).Once() + + userResponse, err := handler.SignUp(ctx, user) + + assert.Error(t, err) + assert.Equal(t, "user is already authorized", err.Error()) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Email is taken", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("IsEmailTaken", ctx, "san@boy.ru").Return(true, nil).Once() + + userResponse, err := handler.SignUp(ctx, user) + + assert.Error(t, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "username is taken", httpError.Message) + assert.Equal(t, http.StatusBadRequest, httpError.Code) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Wrong username", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("IsEmailTaken", ctx, "san@boy.ru").Return(false, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(httperrors.HttpError{Code: http.StatusBadRequest, Message: "email doesn't meet requirements"}).Once() + + userResponse, err := handler.SignUp(ctx, user) + assert.Error(t, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "email doesn't meet requirements", httpError.Message) + assert.Equal(t, http.StatusBadRequest, httpError.Code) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Error creating user", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("IsEmailTaken", ctx, "san@boy.ru").Return(false, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("CreateUser", ctx, "san@boy.ru", "ABC123abc123!").Return(errors.New("unexpected error")).Once() + + userResponse, err := handler.SignUp(ctx, user) + assert.Error(t, err) + assert.Equal(t, "unexpected error", err.Error()) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Error getting user by email", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("IsEmailTaken", ctx, "san@boy.ru").Return(false, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("CreateUser", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{}, errors.New("unexpected error")).Once() + + userResponse, err := handler.SignUp(ctx, user) + assert.Error(t, err) + assert.Equal(t, "unexpected error", err.Error()) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) + + mockUserUseCase.Mock.ExpectedCalls = nil + mockSessionUseCase.Mock.ExpectedCalls = nil + + t.Run("Error creating session", func(t *testing.T) { + mockSessionUseCase.On("GetSession", ctx, req).Return(0, nil).Once() + mockUserUseCase.On("IsEmailTaken", ctx, "san@boy.ru").Return(false, nil).Once() + mockUserUseCase.On("UserDataVerification", "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("CreateUser", ctx, "san@boy.ru", "ABC123abc123!").Return(nil).Once() + mockUserUseCase.On("GetUserByEmail", ctx, "san@boy.ru").Return(entities.User{ID: 1, Username: "san@boy.ru"}, nil).Once() + mockSessionUseCase.On("CreateSession", ctx, rr, 1).Return(errors.New("unexpected error")).Once() + + userResponse, err := handler.SignUp(ctx, user) + assert.Error(t, err) + assert.Equal(t, "unexpected error", err.Error()) + assert.Equal(t, entities.UserResponse{}, userResponse) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) + }) +} From 684ee27292be6465ef841d863e0cae43254660e7 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 29 May 2024 13:00:04 +0300 Subject: [PATCH 5/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=80=D1=83=D1=87=D0=BA=D0=B8=20=D1=81?= =?UTF-8?q?=D0=B0=D0=B9=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 +- cmd/2024_1_ResCogitans/main.go | 14 -- config/local.yaml | 1 - go.mod | 1 - internal/config/config.go | 1 - internal/delivery/db/db.go | 2 +- .../authorization/auth_handler_test.go | 6 + .../delivery/handlers/sight/sight_handler.go | 7 +- .../handlers/sight/sight_handler_test.go | 133 ++++++++++-------- router/router.go | 2 +- 10 files changed, 98 insertions(+), 80 deletions(-) diff --git a/README.md b/README.md index b594a11..0f9bc93 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,16 @@ TODO - _UX_ * файл должен содержать абсолютный путь до файла конфигурации yaml * файл должен лежать рядом с main.go -## 1. Запуск +## 2. Поднятие баз данных через docker + +### Postgres +`docker build -t cogitans .`
+`docker run -d --name -p 5433:5432 ` + +### Redis +`docker run -d --name -p 6379:6379 redis redis-server --requirepass ` + +## 3. Запуск * go run . ## 4. Деплой * [Сайт](http://jantugan.ru) diff --git a/cmd/2024_1_ResCogitans/main.go b/cmd/2024_1_ResCogitans/main.go index fb7c24f..2394cfe 100644 --- a/cmd/2024_1_ResCogitans/main.go +++ b/cmd/2024_1_ResCogitans/main.go @@ -9,20 +9,6 @@ import ( _ "github.com/swaggo/http-swagger/example/go-chi/docs" ) -// @title Swagger Example API -// @version 1.0 -// @description This is a sample server seller server. -// @termsOfService http://swagger.io/terms/ - -// @contact.name API Support -// @contact.url http://www.swagger.io/support -// @contact.email support@swagger.io - -// @license.name Apache 2.0 -// @license.url http://www.apache.org/licenses/LICENSE-2.0.html - -// @host localhost:8080 -// @BasePath /api/v1 func main() { logger := logger.Logger() cfg, err := config.LoadConfig() diff --git a/config/local.yaml b/config/local.yaml index 0663ade..10c02ff 100644 --- a/config/local.yaml +++ b/config/local.yaml @@ -1,5 +1,4 @@ env: "local" -storage_path: "./storage/storage.db" http_server: address: "localhost:8080" timeout: 4s diff --git a/go.mod b/go.mod index 59f35a0..e445780 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/go-park-mail-ru/2024_1_ResCogitans go 1.22.0 require ( - github.com/go-chi/chi v4.1.2+incompatible github.com/go-chi/chi/v5 v5.0.12 github.com/go-redis/redis/v8 v8.11.5 github.com/gorilla/securecookie v1.1.2 diff --git a/internal/config/config.go b/internal/config/config.go index 04f7c19..2648f5f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -11,7 +11,6 @@ import ( type Config struct { Env string `yaml:"env" env:"ENV" env-required:"true"` - StoragePath string `yaml:"storage_path" env-required:"true"` HTTPServer `yaml:"http_server"` Dsn `yaml:"dsn"` Redis `yaml:"redis"` diff --git a/internal/delivery/db/db.go b/internal/delivery/db/db.go index d58e971..a5abbb1 100644 --- a/internal/delivery/db/db.go +++ b/internal/delivery/db/db.go @@ -11,7 +11,7 @@ import ( "github.com/jackc/pgx/v5/pgxpool" ) -// GetPostgress gets connection to postgres database +// GetPostgres gets connection to postgres database func GetPostgres() (*pgxpool.Pool, error) { log := logger.Logger() diff --git a/internal/delivery/handlers/authorization/auth_handler_test.go b/internal/delivery/handlers/authorization/auth_handler_test.go index 22c3fb8..a5f9afb 100644 --- a/internal/delivery/handlers/authorization/auth_handler_test.go +++ b/internal/delivery/handlers/authorization/auth_handler_test.go @@ -46,6 +46,9 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { assert.Error(t, err) assert.Equal(t, entities.UserResponse{}, userResponse) assert.Equal(t, "failed getting request", err.Error()) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) }) // Добавление запроса в контекст @@ -62,6 +65,9 @@ func TestAuthorizationHandler_Authorize(t *testing.T) { assert.Error(t, err) assert.Equal(t, entities.UserResponse{}, userResponse) assert.Equal(t, "failed getting response writer", err.Error()) + + mockSessionUseCase.AssertExpectations(t) + mockUserUseCase.AssertExpectations(t) }) // добавление ключа ответа в контекст diff --git a/internal/delivery/handlers/sight/sight_handler.go b/internal/delivery/handlers/sight/sight_handler.go index 6c027d2..df01a62 100644 --- a/internal/delivery/handlers/sight/sight_handler.go +++ b/internal/delivery/handlers/sight/sight_handler.go @@ -7,13 +7,14 @@ import ( "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/usecase" "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/httputils" + "github.com/pkg/errors" ) type SightHandler struct { - SightUseCase *usecase.SightUseCase + SightUseCase usecase.SightUseCaseInterface } -func NewSightsHandler(usecase *usecase.SightUseCase) *SightHandler { +func NewSightsHandler(usecase usecase.SightUseCaseInterface) *SightHandler { return &SightHandler{ SightUseCase: usecase, } @@ -31,7 +32,7 @@ func (h *SightHandler) GetSight(ctx context.Context, _ entities.Sight) (entities pathParams := httputils.GetPathParamsFromCtx(ctx) id, err := strconv.Atoi(pathParams["id"]) if err != nil { - return entities.SightComments{}, err + return entities.SightComments{}, errors.Wrap(err, "error getting id from parameters") } sight, err := h.SightUseCase.GetSightByID(ctx, id) if err != nil { diff --git a/internal/delivery/handlers/sight/sight_handler_test.go b/internal/delivery/handlers/sight/sight_handler_test.go index 0ba2bf1..5b1721b 100644 --- a/internal/delivery/handlers/sight/sight_handler_test.go +++ b/internal/delivery/handlers/sight/sight_handler_test.go @@ -4,76 +4,95 @@ import ( "context" "testing" + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/delivery/handlers/sight" "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" - "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/wrapper" + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/mocks" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" ) -func TestGetSights(t *testing.T) { - handler := &SightsHandler{} +func TestSightHandler_GetSights(t *testing.T) { + mockSightUseCase := new(mocks.MockSightUseCase) - ctx := context.Background() + handler := sight.NewSightsHandler(mockSightUseCase) - resp, err := handler.GetSights(ctx, entities.Sight{}) - if err != nil { - t.Fatalf("Failed to get sights: %v", err) - } + t.Run("Successfully receiving a list of sites", func(t *testing.T) { + // TODO подставить в sights значения + mockSightUseCase.On("GetSightsList", context.Background()).Return([]entities.Sight{}, nil).Once() - assert.NotEmpty(t, resp.Sight) + response, err := handler.GetSights(context.Background(), entities.Sight{}) - expectedFirstSight := entities.Sight{ - ID: 1, - Rating: 2.1, - Name: "У дяди Вани", - Description: "Ресторан с видом на Сталинскую высотку.", - CityID: 1, - CountryID: 1, - Path: "public/1.jpg", - } - assert.Equal(t, expectedFirstSight, resp.Sight[0]) + assert.NoError(t, err) + assert.Equal(t, entities.Sights{Sight: []entities.Sight{}}, response) + + mockSightUseCase.AssertExpectations(t) + }) + + mockSightUseCase.Mock.ExpectedCalls = nil + + t.Run("Error getting sight", func(t *testing.T) { + mockSightUseCase.On("GetSightsList", context.Background()).Return([]entities.Sight{}, errors.New("unexpected error")).Once() + response, err := handler.GetSights(context.Background(), entities.Sight{}) + + assert.Error(t, err) + assert.Equal(t, entities.Sights{}, response) + assert.Equal(t, "unexpected error", err.Error()) + + mockSightUseCase.AssertExpectations(t) + }) } -func TestGetSightsByID(t *testing.T) { - comm := entities.Comments{} - handler := &SightsHandler{} - - comm.Validate() - - ctx := context.Background() - param := make(map[string]string) - param["id"] = "1" - ctx = wrapper.SetPathParamsToCtx(ctx, param) - - resp, err := handler.GetSightByID(ctx, entities.Sight{}) - if err != nil { - t.Fatalf("Failed to get sights: %v", err) - } - - assert.NotEmpty(t, resp.Sight) - - expectedSight := entities.Sight{ - ID: 1, - Rating: 2.1, - Name: "У дяди Вани", - Description: "Ресторан с видом на Сталинскую высотку.", - CityID: 1, - CountryID: 1, - City: "Москва", - Country: "Россия", - Path: "public/1.jpg", - } - assert.Equal(t, expectedSight, resp.Sight) +func TestSightHandler_GetSight(t *testing.T) { + mockSightUseCase := new(mocks.MockSightUseCase) + + handler := sight.NewSightsHandler(mockSightUseCase) + + t.Run("Error getting path parameters", func(t *testing.T) { + response, err := handler.GetSight(context.Background(), entities.Sight{}) + assert.Error(t, err) + assert.Equal(t, "error getting id from parameters: strconv.Atoi: parsing \"\": invalid syntax", err.Error()) + assert.Equal(t, entities.SightComments{}, response) + }) + + // TODO создать запрос с параметром, где ключ - id, значение - 1 + //req, err := http.NewRequest("GET", "/api/sight/1", nil) + //if err != nil { + // assert.NoError(t, err) + //} + // + //params := wrapper.GetPathParams(req) + //ctx := httputils.SetPathParamsToCtx(context.Background(), params) + // + //t.Run("Successfully get sight", func(t *testing.T) { + // mockSightUseCase"" + //}) } -func TestGetSightsByIDNotInt(t *testing.T) { - handler := &SightsHandler{} +func TestSightHandler_SearchSights(t *testing.T) { + mockSightUseCase := new(mocks.MockSightUseCase) + + handler := sight.NewSightsHandler(mockSightUseCase) + + t.Run("Successfully receiving a sight", func(t *testing.T) { + // TODO подставить в sights значения + mockSightUseCase.On("SearchSights", context.Background(), "лес").Return(entities.Sights{}, nil).Once() + response, err := handler.SearchSights(context.Background(), entities.Sight{Name: "лес"}) + + assert.NoError(t, err) + assert.Equal(t, entities.Sights{}, response) + + mockSightUseCase.AssertExpectations(t) + }) + + mockSightUseCase.Mock.ExpectedCalls = nil - ctx := context.Background() - param := make(map[string]string) - param["id"] = "id" - ctx = wrapper.SetPathParamsToCtx(ctx, param) + t.Run("Error searching sight", func(t *testing.T) { + mockSightUseCase.On("SearchSights", context.Background(), "лес").Return(entities.Sights{}, errors.New("unexpected error")).Once() + response, err := handler.SearchSights(context.Background(), entities.Sight{Name: "лес"}) - _, err := handler.GetSightByID(ctx, entities.Sight{}) + assert.Error(t, err) + assert.Equal(t, entities.Sights{}, response) - assert.NotNil(t, err) + mockSightUseCase.AssertExpectations(t) + }) } diff --git a/router/router.go b/router/router.go index fc4be19..b58255a 100644 --- a/router/router.go +++ b/router/router.go @@ -3,8 +3,8 @@ package router import ( "net/http" - "github.com/go-chi/chi/middleware" "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/config" "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/delivery/handlers/authorization" user "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/delivery/handlers/avatar" From 125d8dd0009077560348c6c60b469f4e3944efa1 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 29 May 2024 17:38:59 +0300 Subject: [PATCH 6/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=80=D1=83=D1=87=D0=BA=D0=B8=20=D0=BE?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D1=81=D0=BD=D0=B8=D0=BA=D0=B0,=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC?= =?UTF-8?q?=D0=BE=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 + .../delivery/handlers/quiz/review_handler.go | 16 +- .../handlers/quiz/review_handler_test.go | 273 ++++++++++++++++++ internal/mocks/comment_mock.go | 32 ++ internal/mocks/journey_mock.go | 57 ++++ internal/mocks/question_mock.go | 32 ++ internal/mocks/session_mock.go | 27 ++ internal/mocks/sight_mock.go | 37 +++ internal/mocks/user_mock.go | 52 ++++ 9 files changed, 522 insertions(+), 8 deletions(-) create mode 100644 Dockerfile create mode 100644 internal/delivery/handlers/quiz/review_handler_test.go create mode 100644 internal/mocks/comment_mock.go create mode 100644 internal/mocks/journey_mock.go create mode 100644 internal/mocks/question_mock.go create mode 100644 internal/mocks/session_mock.go create mode 100644 internal/mocks/sight_mock.go create mode 100644 internal/mocks/user_mock.go diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..00ea919 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM postgres:latest +ENV POSTGRES_USER=admin +ENV POSTGRES_PASSWORD=AdminPassword123 +ENV POSTGRES_DB=cogitans diff --git a/internal/delivery/handlers/quiz/review_handler.go b/internal/delivery/handlers/quiz/review_handler.go index 513ea97..2b6783b 100644 --- a/internal/delivery/handlers/quiz/review_handler.go +++ b/internal/delivery/handlers/quiz/review_handler.go @@ -11,14 +11,14 @@ import ( ) type QuizHandler struct { - questionUseCase *usecase.QuestionUseCase - commentUseCase *usecase.CommentUseCase - journeyUseCase *usecase.JourneyUseCase + questionUseCase usecase.QuestionUseCaseInterface + commentUseCase usecase.CommentUseCaseInterface + journeyUseCase usecase.JourneyUseCaseInterface } -func NewQuizHandler(questionUseCase *usecase.QuestionUseCase, - commentUseCase *usecase.CommentUseCase, - journeyUseCase *usecase.JourneyUseCase) *QuizHandler { +func NewQuizHandler(questionUseCase usecase.QuestionUseCaseInterface, + commentUseCase usecase.CommentUseCaseInterface, + journeyUseCase usecase.JourneyUseCaseInterface) *QuizHandler { return &QuizHandler{ questionUseCase: questionUseCase, commentUseCase: commentUseCase, @@ -32,7 +32,7 @@ func (h *QuizHandler) CreateReview(ctx context.Context, requestData entities.Rev return false, err } if userID == 0 { - return false, httperrors.NewHttpError(http.StatusUnauthorized, "Permission denied") + return false, httperrors.NewHttpError(http.StatusUnauthorized, "permission denied") } err = h.questionUseCase.CreateReview(ctx, userID, requestData) @@ -89,7 +89,7 @@ func (h *QuizHandler) SetStat(ctx context.Context, _ entities.Statistic) ([]enti return []entities.Statistic{}, err } if userID == 0 { - return []entities.Statistic{}, httperrors.NewHttpError(http.StatusUnauthorized, "Permission denied") + return []entities.Statistic{}, httperrors.NewHttpError(http.StatusUnauthorized, "permission denied") } stat, err := h.questionUseCase.SetStat(ctx, userID) diff --git a/internal/delivery/handlers/quiz/review_handler_test.go b/internal/delivery/handlers/quiz/review_handler_test.go new file mode 100644 index 0000000..c77a23e --- /dev/null +++ b/internal/delivery/handlers/quiz/review_handler_test.go @@ -0,0 +1,273 @@ +package quiz_test + +import ( + "context" + "net/http" + "testing" + + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/delivery/handlers/quiz" + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/mocks" + httperrors "github.com/go-park-mail-ru/2024_1_ResCogitans/utils/errors" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" +) + +func TestQuizHandler_CreateReview(t *testing.T) { + mockQuestionUseCase := new(mocks.QuestionMockUseCase) + mockCommentUseCase := new(mocks.CommentMockUseCase) + mockJourneyUseCase := new(mocks.JourneyMockUseCase) + + handler := quiz.NewQuizHandler(mockQuestionUseCase, mockCommentUseCase, mockJourneyUseCase) + + t.Run("Error getting user id from context", func(t *testing.T) { + response, err := handler.CreateReview(context.Background(), entities.Review{}) + + assert.Error(t, err) + assert.Equal(t, "failed getting user from context", err.Error()) + assert.Equal(t, false, response) + }) + + wrongCtx := context.WithValue(context.Background(), "userID", 0) + + t.Run("Unauthorized user", func(t *testing.T) { + response, err := handler.CreateReview(wrongCtx, entities.Review{}) + + assert.Error(t, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "permission denied", httpError.Message) + assert.Equal(t, http.StatusUnauthorized, httpError.Code) + assert.Equal(t, false, response) + }) + + ctx := context.WithValue(context.Background(), "userID", 1) + + t.Run("Error creating review", func(t *testing.T) { + mockQuestionUseCase.On("CreateReview", ctx, 1, entities.Review{UserID: 1, Rating: 4, QuestionID: 4}).Return(errors.New("error creating review")).Once() + response, err := handler.CreateReview(ctx, entities.Review{UserID: 1, Rating: 4, QuestionID: 4}) + + assert.Error(t, err) + assert.Equal(t, "error creating review", err.Error()) + assert.Equal(t, false, response) + + mockQuestionUseCase.AssertExpectations(t) + }) + + mockQuestionUseCase.Mock.ExpectedCalls = nil + + t.Run("Successfully create review", func(t *testing.T) { + mockQuestionUseCase.On("CreateReview", ctx, 1, entities.Review{UserID: 1, Rating: 4, QuestionID: 4}).Return(nil).Once() + response, err := handler.CreateReview(ctx, entities.Review{UserID: 1, Rating: 4, QuestionID: 4}) + + assert.NoError(t, err) + assert.Equal(t, true, response) + mockQuestionUseCase.AssertExpectations(t) + }) +} + +func TestQuizHandler_CheckData(t *testing.T) { + mockQuestionUseCase := new(mocks.QuestionMockUseCase) + mockCommentUseCase := new(mocks.CommentMockUseCase) + mockJourneyUseCase := new(mocks.JourneyMockUseCase) + + handler := quiz.NewQuizHandler(mockQuestionUseCase, mockCommentUseCase, mockJourneyUseCase) + + t.Run("Error getting user id from context", func(t *testing.T) { + response, err := handler.CheckData(context.Background(), entities.Review{}) + + assert.Error(t, err) + assert.Equal(t, "failed getting user from context", err.Error()) + assert.Equal(t, entities.DataCheck{}, response) + }) + + wrongCtx := context.WithValue(context.Background(), "userID", 0) + + t.Run("Unauthorized user", func(t *testing.T) { + response, err := handler.CheckData(wrongCtx, entities.Review{}) + + assert.NoError(t, err) + assert.Equal(t, entities.DataCheck{Flag: false}, response) + }) + + ctx := context.WithValue(context.Background(), "userID", 1) + + t.Run("Error getting question", func(t *testing.T) { + mockQuestionUseCase.On("GetQuestions", ctx).Return([]entities.QuestionResponse{}, errors.New("error getting questions")).Once() + response, err := handler.CheckData(ctx, entities.Review{}) + + assert.Error(t, err) + assert.Equal(t, "error getting questions", err.Error()) + assert.Equal(t, entities.DataCheck{}, response) + mockQuestionUseCase.AssertExpectations(t) + }) + + mockQuestionUseCase.Mock.ExpectedCalls = nil + + t.Run("Review is already completed", func(t *testing.T) { + mockQuestionUseCase.On("GetQuestions", ctx).Return([]entities.QuestionResponse{}, nil).Once() + mockQuestionUseCase.On("CheckReview", ctx, 1).Return(true, nil).Once() + response, err := handler.CheckData(ctx, entities.Review{}) + + assert.NoError(t, err) + assert.Equal(t, entities.DataCheck{Flag: false}, response) + mockQuestionUseCase.AssertExpectations(t) + }) + + mockQuestionUseCase.Mock.ExpectedCalls = nil + + t.Run("Error checking review", func(t *testing.T) { + mockQuestionUseCase.On("GetQuestions", ctx).Return([]entities.QuestionResponse{}, nil).Once() + mockQuestionUseCase.On("CheckReview", ctx, 1).Return(false, errors.New("error checking review")).Once() + response, err := handler.CheckData(ctx, entities.Review{}) + + assert.Error(t, err) + assert.Equal(t, "error checking review", err.Error()) + assert.Equal(t, entities.DataCheck{Flag: false}, response) + mockQuestionUseCase.AssertExpectations(t) + }) + + mockQuestionUseCase.Mock.ExpectedCalls = nil + + t.Run("Journey was created", func(t *testing.T) { + mockQuestionUseCase.On("GetQuestions", ctx).Return([]entities.QuestionResponse{}, nil).Once() + mockQuestionUseCase.On("CheckReview", ctx, 1).Return(false, nil).Once() + mockJourneyUseCase.On("CheckJourney", ctx, 1).Return(true, nil).Once() + response, err := handler.CheckData(ctx, entities.Review{}) + + assert.NoError(t, err) + assert.Equal(t, entities.DataCheck{Questions: []entities.QuestionResponse{}, Flag: true}, response) + + mockQuestionUseCase.AssertExpectations(t) + mockJourneyUseCase.AssertExpectations(t) + }) + + mockQuestionUseCase.Mock.ExpectedCalls = nil + mockJourneyUseCase.Mock.ExpectedCalls = nil + + t.Run("Error checking journey", func(t *testing.T) { + mockQuestionUseCase.On("GetQuestions", ctx).Return([]entities.QuestionResponse{}, nil).Once() + mockQuestionUseCase.On("CheckReview", ctx, 1).Return(false, nil).Once() + mockJourneyUseCase.On("CheckJourney", ctx, 1).Return(false, errors.New("error checking journey")).Once() + response, err := handler.CheckData(ctx, entities.Review{}) + + assert.Error(t, err) + assert.Equal(t, "error checking journey", err.Error()) + assert.Equal(t, entities.DataCheck{Flag: false}, response) + + mockQuestionUseCase.AssertExpectations(t) + mockJourneyUseCase.AssertExpectations(t) + }) + + mockQuestionUseCase.Mock.ExpectedCalls = nil + mockJourneyUseCase.Mock.ExpectedCalls = nil + + t.Run("Comment was created", func(t *testing.T) { + mockQuestionUseCase.On("GetQuestions", ctx).Return([]entities.QuestionResponse{}, nil).Once() + mockQuestionUseCase.On("CheckReview", ctx, 1).Return(false, nil).Once() + mockJourneyUseCase.On("CheckJourney", ctx, 1).Return(false, nil).Once() + mockCommentUseCase.On("CheckCommentByUserID", ctx, 1).Return(true, nil).Once() + response, err := handler.CheckData(ctx, entities.Review{}) + + assert.NoError(t, err) + assert.Equal(t, entities.DataCheck{Questions: []entities.QuestionResponse{}, Flag: true}, response) + + mockQuestionUseCase.AssertExpectations(t) + mockJourneyUseCase.AssertExpectations(t) + mockCommentUseCase.AssertExpectations(t) + }) + + mockQuestionUseCase.Mock.ExpectedCalls = nil + mockJourneyUseCase.Mock.ExpectedCalls = nil + mockCommentUseCase.Mock.ExpectedCalls = nil + + t.Run("Error checking comments", func(t *testing.T) { + mockQuestionUseCase.On("GetQuestions", ctx).Return([]entities.QuestionResponse{}, nil).Once() + mockQuestionUseCase.On("CheckReview", ctx, 1).Return(false, nil).Once() + mockJourneyUseCase.On("CheckJourney", ctx, 1).Return(false, nil).Once() + mockCommentUseCase.On("CheckCommentByUserID", ctx, 1).Return(false, errors.New("error checking comments")).Once() + response, err := handler.CheckData(ctx, entities.Review{}) + + assert.Error(t, err) + assert.Equal(t, "error checking comments", err.Error()) + assert.Equal(t, entities.DataCheck{Flag: false}, response) + + mockQuestionUseCase.AssertExpectations(t) + mockJourneyUseCase.AssertExpectations(t) + mockCommentUseCase.AssertExpectations(t) + }) + + mockQuestionUseCase.Mock.ExpectedCalls = nil + mockJourneyUseCase.Mock.ExpectedCalls = nil + mockCommentUseCase.Mock.ExpectedCalls = nil + + t.Run("Not active user", func(t *testing.T) { + mockQuestionUseCase.On("GetQuestions", ctx).Return([]entities.QuestionResponse{}, nil).Once() + mockQuestionUseCase.On("CheckReview", ctx, 1).Return(false, nil).Once() + mockJourneyUseCase.On("CheckJourney", ctx, 1).Return(false, nil).Once() + mockCommentUseCase.On("CheckCommentByUserID", ctx, 1).Return(false, nil).Once() + response, err := handler.CheckData(ctx, entities.Review{}) + + assert.NoError(t, err) + assert.Equal(t, entities.DataCheck{Flag: false}, response) + + mockQuestionUseCase.AssertExpectations(t) + mockJourneyUseCase.AssertExpectations(t) + mockCommentUseCase.AssertExpectations(t) + }) + + mockQuestionUseCase.Mock.ExpectedCalls = nil + mockJourneyUseCase.Mock.ExpectedCalls = nil + mockCommentUseCase.Mock.ExpectedCalls = nil +} + +func TestQuizHandler_SetStat(t *testing.T) { + mockQuestionUseCase := new(mocks.QuestionMockUseCase) + mockCommentUseCase := new(mocks.CommentMockUseCase) + mockJourneyUseCase := new(mocks.JourneyMockUseCase) + + handler := quiz.NewQuizHandler(mockQuestionUseCase, mockCommentUseCase, mockJourneyUseCase) + + t.Run("Error getting request from context", func(t *testing.T) { + response, err := handler.SetStat(context.Background(), entities.Statistic{}) + + assert.Error(t, err) + assert.Equal(t, "failed getting user from context", err.Error()) + assert.Equal(t, []entities.Statistic{}, response) + }) + + wrongCtx := context.WithValue(context.Background(), "userID", 0) + + t.Run("Unauthorized user", func(t *testing.T) { + response, err := handler.SetStat(wrongCtx, entities.Statistic{}) + + assert.Error(t, err) + httpError := httperrors.UnwrapHttpError(err) + assert.Equal(t, "permission denied", httpError.Message) + assert.Equal(t, http.StatusUnauthorized, httpError.Code) + assert.Equal(t, []entities.Statistic{}, response) + }) + + ctx := context.WithValue(context.Background(), "userID", 1) + + t.Run("Error setting stat", func(t *testing.T) { + mockQuestionUseCase.On("SetStat", ctx, 1).Return([]entities.Statistic{}, errors.New("error setting stat")).Once() + response, err := handler.SetStat(ctx, entities.Statistic{}) + + assert.Error(t, err) + assert.Equal(t, "error setting stat", err.Error()) + assert.Equal(t, []entities.Statistic{}, response) + + mockQuestionUseCase.AssertExpectations(t) + }) + + mockQuestionUseCase.Mock.ExpectedCalls = nil + + t.Run("Success setting stat", func(t *testing.T) { + mockQuestionUseCase.On("SetStat", ctx, 1).Return([]entities.Statistic{{}}, nil) + response, err := handler.SetStat(ctx, entities.Statistic{}) + + assert.NoError(t, err) + assert.Equal(t, []entities.Statistic{{}}, response) + mockQuestionUseCase.AssertExpectations(t) + }) +} diff --git a/internal/mocks/comment_mock.go b/internal/mocks/comment_mock.go new file mode 100644 index 0000000..23f4efe --- /dev/null +++ b/internal/mocks/comment_mock.go @@ -0,0 +1,32 @@ +package mocks + +import ( + "context" + + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + "github.com/stretchr/testify/mock" +) + +type CommentMockUseCase struct { + mock.Mock +} + +func (m *CommentMockUseCase) CreateCommentBySightID(ctx context.Context, sightID int, comment entities.Comment) error { + args := m.Called(ctx, sightID, comment) + return args.Error(0) +} + +func (m *CommentMockUseCase) EditCommentByCommentID(ctx context.Context, commentID int, comment entities.Comment) error { + args := m.Called(ctx, commentID, comment) + return args.Error(0) +} + +func (m *CommentMockUseCase) DeleteCommentByCommentID(ctx context.Context, commentID int) error { + args := m.Called(ctx, commentID) + return args.Error(0) +} + +func (m *CommentMockUseCase) CheckCommentByUserID(ctx context.Context, userID int) (bool, error) { + args := m.Called(ctx, userID) + return args.Bool(0), args.Error(1) +} diff --git a/internal/mocks/journey_mock.go b/internal/mocks/journey_mock.go new file mode 100644 index 0000000..3e8d001 --- /dev/null +++ b/internal/mocks/journey_mock.go @@ -0,0 +1,57 @@ +package mocks + +import ( + "context" + + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + "github.com/stretchr/testify/mock" +) + +type JourneyMockUseCase struct { + mock.Mock +} + +func (m *JourneyMockUseCase) CreateJourney(ctx context.Context, journey entities.Journey) (entities.Journey, error) { + args := m.Called(ctx, journey) + return args.Get(0).(entities.Journey), args.Error(1) +} + +func (m *JourneyMockUseCase) DeleteJourneyByID(ctx context.Context, journeyID int) error { + args := m.Called(ctx, journeyID) + return args.Error(0) +} + +func (m *JourneyMockUseCase) GetJourneys(ctx context.Context, userID int) ([]entities.Journey, error) { + args := m.Called(ctx, userID) + return args.Get(0).([]entities.Journey), args.Error(1) +} + +func (m *JourneyMockUseCase) AddJourneySight(ctx context.Context, journeyID int, ids []int) error { + args := m.Called(ctx, journeyID, ids) + return args.Error(0) +} + +func (m *JourneyMockUseCase) EditJourney(ctx context.Context, journeyID int, name, description string) error { + args := m.Called(ctx, journeyID, name, description) + return args.Error(0) +} + +func (m *JourneyMockUseCase) DeleteJourneySight(ctx context.Context, journeyID int, sight entities.JourneySight) error { + args := m.Called(ctx, journeyID, sight) + return args.Error(0) +} + +func (m *JourneyMockUseCase) GetJourneySights(ctx context.Context, journeyID int) ([]entities.Sight, error) { + args := m.Called(ctx, journeyID) + return args.Get(0).([]entities.Sight), args.Error(1) +} + +func (m *JourneyMockUseCase) GetJourney(ctx context.Context, journeyID int) (entities.Journey, error) { + args := m.Called(ctx, journeyID) + return args.Get(0).(entities.Journey), args.Error(1) +} + +func (m *JourneyMockUseCase) CheckJourney(ctx context.Context, userID int) (bool, error) { + args := m.Called(ctx, userID) + return args.Bool(0), args.Error(1) +} diff --git a/internal/mocks/question_mock.go b/internal/mocks/question_mock.go new file mode 100644 index 0000000..0e9c389 --- /dev/null +++ b/internal/mocks/question_mock.go @@ -0,0 +1,32 @@ +package mocks + +import ( + "context" + + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + "github.com/stretchr/testify/mock" +) + +type QuestionMockUseCase struct { + mock.Mock +} + +func (m *QuestionMockUseCase) CreateReview(ctx context.Context, userID int, review entities.Review) error { + args := m.Called(ctx, userID, review) + return args.Error(0) +} + +func (m *QuestionMockUseCase) GetQuestions(ctx context.Context) ([]entities.QuestionResponse, error) { + args := m.Called(ctx) + return args.Get(0).([]entities.QuestionResponse), args.Error(1) +} + +func (m *QuestionMockUseCase) CheckReview(ctx context.Context, userID int) (bool, error) { + args := m.Called(ctx, userID) + return args.Bool(0), args.Error(1) +} + +func (m *QuestionMockUseCase) SetStat(ctx context.Context, userID int) ([]entities.Statistic, error) { + args := m.Called(ctx, userID) + return args.Get(0).([]entities.Statistic), args.Error(1) +} diff --git a/internal/mocks/session_mock.go b/internal/mocks/session_mock.go new file mode 100644 index 0000000..0f2584f --- /dev/null +++ b/internal/mocks/session_mock.go @@ -0,0 +1,27 @@ +package mocks + +import ( + "context" + "net/http" + + "github.com/stretchr/testify/mock" +) + +type MockSessionUseCase struct { + mock.Mock +} + +func (m *MockSessionUseCase) CreateSession(ctx context.Context, w http.ResponseWriter, userID int) error { + args := m.Called(ctx, w, userID) + return args.Error(0) +} + +func (m *MockSessionUseCase) GetSession(ctx context.Context, r *http.Request) (int, error) { + args := m.Called(ctx, r) + return args.Int(0), args.Error(1) +} + +func (m *MockSessionUseCase) ClearSession(ctx context.Context, w http.ResponseWriter, r *http.Request) error { + args := m.Called(ctx, w, r) + return args.Error(0) +} diff --git a/internal/mocks/sight_mock.go b/internal/mocks/sight_mock.go new file mode 100644 index 0000000..918c6d6 --- /dev/null +++ b/internal/mocks/sight_mock.go @@ -0,0 +1,37 @@ +package mocks + +import ( + "context" + + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + "github.com/stretchr/testify/mock" +) + +type MockSightUseCase struct { + mock.Mock +} + +func (m *MockSightUseCase) GetSightByID(ctx context.Context, sightID int) (entities.Sight, error) { + args := m.Called(ctx, sightID) + return args.Get(0).(entities.Sight), args.Error(1) +} + +func (m *MockSightUseCase) GetCommentsBySightID(ctx context.Context, commentID int) ([]entities.Comment, error) { + args := m.Called(ctx, commentID) + return args.Get(0).([]entities.Comment), args.Error(1) +} + +func (m *MockSightUseCase) GetCommentsByUserID(ctx context.Context, userID int) ([]entities.Comment, error) { + args := m.Called(ctx, userID) + return args.Get(0).([]entities.Comment), args.Error(1) +} + +func (m *MockSightUseCase) GetSightsList(ctx context.Context) ([]entities.Sight, error) { + args := m.Called(ctx) + return args.Get(0).([]entities.Sight), args.Error(1) +} + +func (m *MockSightUseCase) SearchSights(ctx context.Context, str string) (entities.Sights, error) { + args := m.Called(ctx, str) + return args.Get(0).(entities.Sights), args.Error(1) +} diff --git a/internal/mocks/user_mock.go b/internal/mocks/user_mock.go new file mode 100644 index 0000000..9c068bf --- /dev/null +++ b/internal/mocks/user_mock.go @@ -0,0 +1,52 @@ +package mocks + +import ( + "context" + + "github.com/go-park-mail-ru/2024_1_ResCogitans/internal/entities" + "github.com/stretchr/testify/mock" +) + +type MockUserUseCase struct { + mock.Mock +} + +func (m *MockUserUseCase) CreateUser(ctx context.Context, email string, password string) error { + args := m.Called(ctx, email, password) + return args.Error(0) +} + +func (m *MockUserUseCase) GetUserByEmail(ctx context.Context, email string) (entities.User, error) { + args := m.Called(ctx, email) + return args.Get(0).(entities.User), args.Error(1) +} + +func (m *MockUserUseCase) GetUserByID(ctx context.Context, userID int) (entities.User, error) { + args := m.Called(ctx, userID) + return args.Get(0).(entities.User), args.Error(1) +} + +func (m *MockUserUseCase) DeleteUser(ctx context.Context, userID int) error { + args := m.Called(ctx, userID) + return args.Error(0) +} + +func (m *MockUserUseCase) UserDataVerification(email, password string) error { + args := m.Called(email, password) + return args.Error(0) +} + +func (m *MockUserUseCase) ChangePassword(ctx context.Context, userID int, password string) (entities.User, error) { + args := m.Called(ctx, userID, password) + return args.Get(0).(entities.User), args.Error(1) +} + +func (m *MockUserUseCase) UserExists(ctx context.Context, email, password string) error { + args := m.Called(ctx, email, password) + return args.Error(0) +} + +func (m *MockUserUseCase) IsEmailTaken(ctx context.Context, email string) (bool, error) { + args := m.Called(ctx, email) + return args.Bool(0), args.Error(1) +}