d1e45c7686
modified: main_dc/yalarba/api_yal/cmd/testrunner/main.go modified: main_dc/yalarba/api_yal/cmd/testrunner/runner.go modified: main_dc/yalarba/api_yal/tests/integration/account_test.go modified: main_dc/yalarba/api_yal/tests/integration/appeal_test.go modified: main_dc/yalarba/api_yal/tests/integration/auth_test.go modified: main_dc/yalarba/api_yal/tests/integration/comment_test.go modified: main_dc/yalarba/api_yal/tests/integration/feedback_test.go modified: main_dc/yalarba/api_yal/tests/integration/object_test.go modified: main_dc/yalarba/api_yal/tests/integration/rating_test.go deleted: main_dc/yalarba/api_yal/tests/testutils/client.go modified: main_dc/yalarba/api_yal/tests/testutils/fixtures.go modified: main_dc/yalarba/api_yal/tests/testutils/setup.go write comments for and into test's functions
228 lines
8.2 KiB
Go
228 lines
8.2 KiB
Go
package integration
|
|
|
|
import (
|
|
"testing"
|
|
"api_yal/tests/testutils"
|
|
)
|
|
|
|
// TestAuthFlow тестирует полный поток аутентификации пользователя
|
|
// Включает регистрацию, логин, обновление токена, выход, сброс пароля и мобильную авторизацию
|
|
func TestAuthFlow(t *testing.T) {
|
|
config := testutils.NewTestConfig()
|
|
|
|
// Register тестирует регистрацию нового пользователя
|
|
t.Run("Register", func(t *testing.T) {
|
|
testData := map[string]interface{}{
|
|
"email": "testflow@example.com",
|
|
"password": "test123456",
|
|
"first_name": "Flow",
|
|
"last_name": "Test",
|
|
}
|
|
|
|
resp, err := config.Request("POST", "/auth/register", testData, "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to register: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
// Ожидаем статус 201 Created при успешной регистрации
|
|
if resp.StatusCode != 201 {
|
|
t.Errorf("Expected status 201, got %d", resp.StatusCode)
|
|
}
|
|
|
|
var result map[string]interface{}
|
|
if err := config.ParseResponse(resp, &result); err != nil {
|
|
t.Fatalf("Failed to parse response: %v", err)
|
|
}
|
|
|
|
// Проверяем наличие токена и данных пользователя в ответе
|
|
if _, ok := result["token"]; !ok {
|
|
t.Error("Token not found in response")
|
|
}
|
|
|
|
if _, ok := result["user"]; !ok {
|
|
t.Error("User data not found in response")
|
|
}
|
|
})
|
|
|
|
// Login тестирует вход существующего пользователя
|
|
t.Run("Login", func(t *testing.T) {
|
|
// Сначала создаем пользователя
|
|
user := config.CreateTestUser(t)
|
|
defer config.CleanupTestUser(t, user)
|
|
|
|
// Тестируем логин
|
|
resp, err := config.Request("POST", "/auth/login", map[string]interface{}{
|
|
"email": user.Email,
|
|
"password": user.Password,
|
|
}, "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to login: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != 200 {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
|
|
var result map[string]interface{}
|
|
if err := config.ParseResponse(resp, &result); err != nil {
|
|
t.Fatalf("Failed to parse response: %v", err)
|
|
}
|
|
|
|
if _, ok := result["token"]; !ok {
|
|
t.Error("Token not found in response")
|
|
}
|
|
|
|
// Проверяем, что refresh token установлен в cookie
|
|
cookies := resp.Cookies()
|
|
foundRefreshToken := false
|
|
for _, cookie := range cookies {
|
|
if cookie.Name == "refresh_token" {
|
|
foundRefreshToken = true
|
|
break
|
|
}
|
|
}
|
|
if !foundRefreshToken {
|
|
t.Error("Refresh token cookie not set")
|
|
}
|
|
})
|
|
|
|
// RefreshToken тестирует обновление access токена через refresh token
|
|
t.Run("RefreshToken", func(t *testing.T) {
|
|
user := config.CreateTestUser(t)
|
|
defer config.CleanupTestUser(t, user)
|
|
|
|
// Логинимся для получения refresh token в cookie
|
|
_, err := config.Request("POST", "/auth/login", map[string]interface{}{
|
|
"email": user.Email,
|
|
"password": user.Password,
|
|
}, "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to login: %v", err)
|
|
}
|
|
|
|
// Обновляем токен
|
|
resp, err := config.Request("POST", "/auth/refresh", nil, "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to refresh token: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != 200 {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
})
|
|
|
|
// Logout тестирует выход пользователя из системы
|
|
t.Run("Logout", func(t *testing.T) {
|
|
user := config.CreateTestUser(t)
|
|
defer config.CleanupTestUser(t, user)
|
|
|
|
resp, err := config.Request("POST", "/auth/logout", nil, user.Token)
|
|
if err != nil {
|
|
t.Fatalf("Failed to logout: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != 200 {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
|
|
var result map[string]interface{}
|
|
if err := config.ParseResponse(resp, &result); err != nil {
|
|
t.Fatalf("Failed to parse response: %v", err)
|
|
}
|
|
|
|
// Проверяем сообщение о успешном выходе
|
|
if msg, ok := result["message"]; !ok || msg != "Successfully logged out" {
|
|
t.Error("Logout message not as expected")
|
|
}
|
|
})
|
|
|
|
// PasswordReset тестирует полный поток сброса пароля
|
|
t.Run("PasswordReset", func(t *testing.T) {
|
|
user := config.CreateTestUser(t)
|
|
defer config.CleanupTestUser(t, user)
|
|
|
|
// Запрос сброса пароля
|
|
resp, err := config.Request("POST", "/auth/password-reset/request", map[string]interface{}{
|
|
"email": user.Email,
|
|
}, "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to request password reset: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != 200 {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
|
|
var result map[string]interface{}
|
|
if err := config.ParseResponse(resp, &result); err != nil {
|
|
t.Fatalf("Failed to parse response: %v", err)
|
|
}
|
|
|
|
// Получаем токен сброса из ответа (в реальном API он приходит на email)
|
|
resetToken, ok := result["token"].(string)
|
|
if !ok {
|
|
t.Fatal("Reset token not found in response")
|
|
}
|
|
|
|
// Подтверждение сброса пароля с новым паролем
|
|
newPassword := "newpassword789"
|
|
resp, err = config.Request("POST", "/auth/password-reset/confirm", map[string]interface{}{
|
|
"token": resetToken,
|
|
"new_password": newPassword,
|
|
}, "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to confirm password reset: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != 200 {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
|
|
// Проверяем, что можно войти с новым паролем
|
|
newToken, err := config.GetAuthToken(user.Email, newPassword)
|
|
if err != nil {
|
|
t.Errorf("Failed to login with new password: %v", err)
|
|
}
|
|
if newToken == "" {
|
|
t.Error("Failed to get token with new password")
|
|
}
|
|
})
|
|
|
|
// MobileLogin тестирует мобильную авторизацию (возвращает access и refresh токены)
|
|
t.Run("MobileLogin", func(t *testing.T) {
|
|
user := config.CreateTestUser(t)
|
|
defer config.CleanupTestUser(t, user)
|
|
|
|
resp, err := config.Request("POST", "/auth/mobile/login", map[string]interface{}{
|
|
"email": user.Email,
|
|
"password": user.Password,
|
|
}, "")
|
|
if err != nil {
|
|
t.Fatalf("Failed to mobile login: %v", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != 200 {
|
|
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
|
}
|
|
|
|
var result map[string]interface{}
|
|
if err := config.ParseResponse(resp, &result); err != nil {
|
|
t.Fatalf("Failed to parse response: %v", err)
|
|
}
|
|
|
|
// Для мобильной авторизации ожидаем специальные поля
|
|
requiredFields := []string{"access_token", "refresh_token", "expires_at", "user"}
|
|
for _, field := range requiredFields {
|
|
if _, ok := result[field]; !ok {
|
|
t.Errorf("Required field %s not found in response", field)
|
|
}
|
|
}
|
|
})
|
|
} |