docs: add integration test run instructions to README.md
- Added section 8 'Тестирование' with run instructions, structure, features, and diagnostics - Also includes test file route path adjustments and import reordering
This commit is contained in:
@@ -1,251 +1,233 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"api_yal/tests/testutils"
|
||||
"fmt"
|
||||
"testing"
|
||||
"api_yal/tests/testutils"
|
||||
)
|
||||
|
||||
// TestRatingEndpoints тестирует все эндпоинты для работы с рейтингами и голосованием
|
||||
// Включает создание рейтинга, голосование, изменение голоса и получение статистики
|
||||
func TestRatingEndpoints(t *testing.T) {
|
||||
config := testutils.NewTestConfig()
|
||||
config := testutils.NewTestConfig()
|
||||
|
||||
// CreateRating тестирует создание нового рейтинга для объекта
|
||||
t.Run("CreateRating", func(t *testing.T) {
|
||||
user := config.CreateTestUser(t)
|
||||
defer config.CleanupTestUser(t, user)
|
||||
t.Run("CreateRating", func(t *testing.T) {
|
||||
user := config.CreateTestUser(t)
|
||||
defer config.CleanupTestUser(t, user)
|
||||
|
||||
objectID := config.CreateTestObject(t, user.Token)
|
||||
objectID := config.CreateTestObject(t, user.Token)
|
||||
|
||||
ratingData := map[string]interface{}{
|
||||
"object_id": objectID,
|
||||
"platform": "tourist",
|
||||
}
|
||||
ratingData := map[string]interface{}{
|
||||
"object_id": objectID,
|
||||
"platform": "tourist",
|
||||
}
|
||||
|
||||
resp, err := config.Request("POST", "/ratings", ratingData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create rating: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
resp, err := config.Request("POST", "/ratings", ratingData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create rating: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 201 {
|
||||
t.Errorf("Expected status 201, got %d", resp.StatusCode)
|
||||
}
|
||||
})
|
||||
if resp.StatusCode != 201 {
|
||||
t.Errorf("Expected status 201, got %d", resp.StatusCode)
|
||||
}
|
||||
})
|
||||
|
||||
// CastVote тестирует голосование в рейтинге
|
||||
t.Run("CastVote", func(t *testing.T) {
|
||||
user := config.CreateTestUser(t)
|
||||
defer config.CleanupTestUser(t, user)
|
||||
t.Run("CastVote", func(t *testing.T) {
|
||||
user := config.CreateTestUser(t)
|
||||
defer config.CleanupTestUser(t, user)
|
||||
|
||||
objectID := config.CreateTestObject(t, user.Token)
|
||||
objectID := config.CreateTestObject(t, user.Token)
|
||||
|
||||
// Сначала создаем рейтинг
|
||||
ratingData := map[string]interface{}{
|
||||
"object_id": objectID,
|
||||
"platform": "tourist",
|
||||
}
|
||||
resp, err := config.Request("POST", "/ratings", ratingData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create rating: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ratingData := map[string]interface{}{
|
||||
"object_id": objectID,
|
||||
"platform": "tourist",
|
||||
}
|
||||
resp, err := config.Request("POST", "/ratings", ratingData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create rating: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var createdRating map[string]interface{}
|
||||
if err := config.ParseResponse(resp, &createdRating); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
var createdRating map[string]interface{}
|
||||
if err := config.ParseResponse(resp, &createdRating); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
|
||||
ratingID := createdRating["id"].(float64)
|
||||
ratingID := createdRating["id"].(float64)
|
||||
|
||||
// Голосуем с оценкой 5
|
||||
voteData := map[string]interface{}{
|
||||
"score": 5,
|
||||
}
|
||||
voteData := map[string]interface{}{
|
||||
"score": 5,
|
||||
}
|
||||
|
||||
voteResp, err := config.Request("POST", "/ratings/"+string(rune(ratingID))+"/vote/tourist", voteData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to cast vote: %v", err)
|
||||
}
|
||||
defer voteResp.Body.Close()
|
||||
voteResp, err := config.Request("POST", "/ratings/"+fmt.Sprintf("%.0f", ratingID)+"/vote/tourist", voteData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to cast vote: %v", err)
|
||||
}
|
||||
defer voteResp.Body.Close()
|
||||
|
||||
if voteResp.StatusCode != 200 {
|
||||
t.Errorf("Expected status 200, got %d", voteResp.StatusCode)
|
||||
}
|
||||
})
|
||||
if voteResp.StatusCode != 200 {
|
||||
t.Errorf("Expected status 200, got %d", voteResp.StatusCode)
|
||||
}
|
||||
})
|
||||
|
||||
// GetMyVote тестирует получение голоса текущего пользователя
|
||||
t.Run("GetMyVote", func(t *testing.T) {
|
||||
user := config.CreateTestUser(t)
|
||||
defer config.CleanupTestUser(t, user)
|
||||
t.Run("GetMyVote", func(t *testing.T) {
|
||||
user := config.CreateTestUser(t)
|
||||
defer config.CleanupTestUser(t, user)
|
||||
|
||||
objectID := config.CreateTestObject(t, user.Token)
|
||||
objectID := config.CreateTestObject(t, user.Token)
|
||||
|
||||
// Создаем рейтинг и голосуем
|
||||
ratingData := map[string]interface{}{
|
||||
"object_id": objectID,
|
||||
"platform": "tourist",
|
||||
}
|
||||
resp, err := config.Request("POST", "/ratings", ratingData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create rating: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ratingData := map[string]interface{}{
|
||||
"object_id": objectID,
|
||||
"platform": "tourist",
|
||||
}
|
||||
resp, err := config.Request("POST", "/ratings", ratingData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create rating: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var createdRating map[string]interface{}
|
||||
if err := config.ParseResponse(resp, &createdRating); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
var createdRating map[string]interface{}
|
||||
if err := config.ParseResponse(resp, &createdRating); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
|
||||
ratingID := createdRating["id"].(float64)
|
||||
ratingID := createdRating["id"].(float64)
|
||||
|
||||
voteData := map[string]interface{}{
|
||||
"score": 5,
|
||||
}
|
||||
_, err = config.Request("POST", "/ratings/"+string(rune(ratingID))+"/vote/tourist", voteData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to cast vote: %v", err)
|
||||
}
|
||||
voteData := map[string]interface{}{
|
||||
"score": 5,
|
||||
}
|
||||
_, err = config.Request("POST", "/ratings/"+fmt.Sprintf("%.0f", ratingID)+"/vote/tourist", voteData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to cast vote: %v", err)
|
||||
}
|
||||
|
||||
// Получаем мой голос
|
||||
myVoteResp, err := config.Request("GET", "/ratings/"+string(rune(ratingID))+"/my-vote/tourist", nil, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get my vote: %v", err)
|
||||
}
|
||||
defer myVoteResp.Body.Close()
|
||||
myVoteResp, err := config.Request("GET", "/ratings/"+fmt.Sprintf("%.0f", ratingID)+"/my-vote/tourist", nil, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get my vote: %v", err)
|
||||
}
|
||||
defer myVoteResp.Body.Close()
|
||||
|
||||
if myVoteResp.StatusCode != 200 {
|
||||
t.Errorf("Expected status 200, got %d", myVoteResp.StatusCode)
|
||||
}
|
||||
if myVoteResp.StatusCode != 200 {
|
||||
t.Errorf("Expected status 200, got %d", myVoteResp.StatusCode)
|
||||
}
|
||||
|
||||
var voteInfo map[string]interface{}
|
||||
if err := config.ParseResponse(myVoteResp, &voteInfo); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
var voteInfo map[string]interface{}
|
||||
if err := config.ParseResponse(myVoteResp, &voteInfo); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
|
||||
// Проверяем, что пользователь уже голосовал
|
||||
if hasVoted, ok := voteInfo["has_voted"].(bool); !ok || !hasVoted {
|
||||
t.Error("has_voted should be true")
|
||||
}
|
||||
})
|
||||
if hasVoted, ok := voteInfo["has_voted"].(bool); !ok || !hasVoted {
|
||||
t.Error("has_voted should be true")
|
||||
}
|
||||
})
|
||||
|
||||
// UpdateMyVote тестирует обновление голоса пользователя
|
||||
t.Run("UpdateMyVote", func(t *testing.T) {
|
||||
user := config.CreateTestUser(t)
|
||||
defer config.CleanupTestUser(t, user)
|
||||
t.Run("UpdateMyVote", func(t *testing.T) {
|
||||
user := config.CreateTestUser(t)
|
||||
defer config.CleanupTestUser(t, user)
|
||||
|
||||
objectID := config.CreateTestObject(t, user.Token)
|
||||
objectID := config.CreateTestObject(t, user.Token)
|
||||
|
||||
ratingData := map[string]interface{}{
|
||||
"object_id": objectID,
|
||||
"platform": "tourist",
|
||||
}
|
||||
resp, err := config.Request("POST", "/ratings", ratingData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create rating: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ratingData := map[string]interface{}{
|
||||
"object_id": objectID,
|
||||
"platform": "tourist",
|
||||
}
|
||||
resp, err := config.Request("POST", "/ratings", ratingData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create rating: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var createdRating map[string]interface{}
|
||||
if err := config.ParseResponse(resp, &createdRating); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
var createdRating map[string]interface{}
|
||||
if err := config.ParseResponse(resp, &createdRating); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
|
||||
ratingID := createdRating["id"].(float64)
|
||||
ratingID := createdRating["id"].(float64)
|
||||
|
||||
// Голосуем
|
||||
voteData := map[string]interface{}{
|
||||
"score": 5,
|
||||
}
|
||||
_, err = config.Request("POST", "/ratings/"+string(rune(ratingID))+"/vote/tourist", voteData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to cast vote: %v", err)
|
||||
}
|
||||
voteData := map[string]interface{}{
|
||||
"score": 5,
|
||||
}
|
||||
_, err = config.Request("POST", "/ratings/"+fmt.Sprintf("%.0f", ratingID)+"/vote/tourist", voteData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to cast vote: %v", err)
|
||||
}
|
||||
|
||||
// Обновляем голос с оценки 5 на 4
|
||||
updateData := map[string]interface{}{
|
||||
"score": 4,
|
||||
}
|
||||
updateResp, err := config.Request("PUT", "/ratings/"+string(rune(ratingID))+"/my-vote/tourist", updateData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to update vote: %v", err)
|
||||
}
|
||||
defer updateResp.Body.Close()
|
||||
updateData := map[string]interface{}{
|
||||
"score": 4,
|
||||
}
|
||||
updateResp, err := config.Request("PUT", "/ratings/"+fmt.Sprintf("%.0f", ratingID)+"/my-vote/tourist", updateData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to update vote: %v", err)
|
||||
}
|
||||
defer updateResp.Body.Close()
|
||||
|
||||
if updateResp.StatusCode != 200 {
|
||||
t.Errorf("Expected status 200, got %d", updateResp.StatusCode)
|
||||
}
|
||||
})
|
||||
if updateResp.StatusCode != 200 {
|
||||
t.Errorf("Expected status 200, got %d", updateResp.StatusCode)
|
||||
}
|
||||
})
|
||||
|
||||
// GetRatingStats тестирует получение статистики по рейтингам
|
||||
t.Run("GetRatingStats", func(t *testing.T) {
|
||||
resp, err := config.Request("GET", "/ratings/stats", nil, "")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get rating stats: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
t.Run("GetRatingStats", func(t *testing.T) {
|
||||
resp, err := config.Request("GET", "/ratings/stats", nil, "")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get rating stats: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
||||
}
|
||||
if resp.StatusCode != 200 {
|
||||
t.Errorf("Expected status 200, got %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
var stats map[string]interface{}
|
||||
if err := config.ParseResponse(resp, &stats); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
var stats map[string]interface{}
|
||||
if err := config.ParseResponse(resp, &stats); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
|
||||
// Проверяем наличие полей статистики
|
||||
expectedFields := []string{"total_ratings", "total_votes", "platform_distribution"}
|
||||
for _, field := range expectedFields {
|
||||
if _, ok := stats[field]; !ok {
|
||||
t.Errorf("Expected field %s not found", field)
|
||||
}
|
||||
}
|
||||
})
|
||||
expectedFields := []string{"total_ratings", "total_votes", "platform_distribution"}
|
||||
for _, field := range expectedFields {
|
||||
if _, ok := stats[field]; !ok {
|
||||
t.Errorf("Expected field %s not found", field)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// DeleteMyVote тестирует удаление голоса пользователя
|
||||
t.Run("DeleteMyVote", func(t *testing.T) {
|
||||
user := config.CreateTestUser(t)
|
||||
defer config.CleanupTestUser(t, user)
|
||||
t.Run("DeleteMyVote", func(t *testing.T) {
|
||||
user := config.CreateTestUser(t)
|
||||
defer config.CleanupTestUser(t, user)
|
||||
|
||||
objectID := config.CreateTestObject(t, user.Token)
|
||||
objectID := config.CreateTestObject(t, user.Token)
|
||||
|
||||
ratingData := map[string]interface{}{
|
||||
"object_id": objectID,
|
||||
"platform": "tourist",
|
||||
}
|
||||
resp, err := config.Request("POST", "/ratings", ratingData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create rating: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
ratingData := map[string]interface{}{
|
||||
"object_id": objectID,
|
||||
"platform": "tourist",
|
||||
}
|
||||
resp, err := config.Request("POST", "/ratings", ratingData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create rating: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var createdRating map[string]interface{}
|
||||
if err := config.ParseResponse(resp, &createdRating); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
var createdRating map[string]interface{}
|
||||
if err := config.ParseResponse(resp, &createdRating); err != nil {
|
||||
t.Fatalf("Failed to parse response: %v", err)
|
||||
}
|
||||
|
||||
ratingID := createdRating["id"].(float64)
|
||||
ratingID := createdRating["id"].(float64)
|
||||
|
||||
// Голосуем
|
||||
voteData := map[string]interface{}{
|
||||
"score": 5,
|
||||
}
|
||||
_, err = config.Request("POST", "/ratings/"+string(rune(ratingID))+"/vote/tourist", voteData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to cast vote: %v", err)
|
||||
}
|
||||
voteData := map[string]interface{}{
|
||||
"score": 5,
|
||||
}
|
||||
_, err = config.Request("POST", "/ratings/"+fmt.Sprintf("%.0f", ratingID)+"/vote/tourist", voteData, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to cast vote: %v", err)
|
||||
}
|
||||
|
||||
// Удаляем голос
|
||||
deleteResp, err := config.Request("DELETE", "/ratings/"+string(rune(ratingID))+"/my-vote/tourist", nil, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to delete vote: %v", err)
|
||||
}
|
||||
defer deleteResp.Body.Close()
|
||||
deleteResp, err := config.Request("DELETE", "/ratings/"+fmt.Sprintf("%.0f", ratingID)+"/my-vote/tourist", nil, user.Token)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to delete vote: %v", err)
|
||||
}
|
||||
defer deleteResp.Body.Close()
|
||||
|
||||
// Ожидаем статус 204 No Content при успешном удалении
|
||||
if deleteResp.StatusCode != 204 {
|
||||
t.Errorf("Expected status 204, got %d", deleteResp.StatusCode)
|
||||
}
|
||||
})
|
||||
}
|
||||
if deleteResp.StatusCode != 204 {
|
||||
t.Errorf("Expected status 204, got %d", deleteResp.StatusCode)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user