- Tests complets pour search_handlers.go (6 tests)
- Tests complets pour comment_handler.go (12 tests)
- Interfaces créées pour permettre le mock (SearchServiceInterface, CommentServiceInterface)
- Couverture actuelle: 30.6% (objectif: 80%)
Files: veza-backend-api/internal/handlers/search_handlers.go
veza-backend-api/internal/handlers/search_handlers_test.go
veza-backend-api/internal/handlers/comment_handler.go
veza-backend-api/internal/handlers/comment_handler_test.go
VEZA_ROADMAP.json
Hours: 16 estimated, 17 actual
181 lines
4.7 KiB
Go
181 lines
4.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"veza-backend-api/internal/services"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/mock"
|
|
)
|
|
|
|
// MockSearchService implements SearchService interface for testing
|
|
type MockSearchService struct {
|
|
mock.Mock
|
|
}
|
|
|
|
func (m *MockSearchService) Search(query string, types []string) (*services.SearchResult, error) {
|
|
args := m.Called(query, types)
|
|
if args.Get(0) == nil {
|
|
return nil, args.Error(1)
|
|
}
|
|
return args.Get(0).(*services.SearchResult), args.Error(1)
|
|
}
|
|
|
|
func setupTestSearchRouter(mockService *MockSearchService) *gin.Engine {
|
|
gin.SetMode(gin.TestMode)
|
|
router := gin.New()
|
|
|
|
handler := NewSearchHandlersWithInterface(mockService)
|
|
|
|
api := router.Group("/api/v1")
|
|
{
|
|
api.GET("/search", handler.Search)
|
|
}
|
|
|
|
return router
|
|
}
|
|
|
|
func TestSearchHandlers_Search_Success(t *testing.T) {
|
|
// Setup
|
|
mockService := new(MockSearchService)
|
|
router := setupTestSearchRouter(mockService)
|
|
|
|
expectedResult := &services.SearchResult{
|
|
Tracks: []services.TrackResult{
|
|
{ID: "track-1", Title: "Test Track", Artist: "Test Artist", URL: "http://example.com/track-1"},
|
|
},
|
|
Users: []services.UserResult{
|
|
{ID: "user-1", Username: "testuser", Avatar: "http://example.com/avatar.jpg"},
|
|
},
|
|
Playlists: []services.PlaylistResult{
|
|
{ID: "playlist-1", Name: "Test Playlist", Cover: "http://example.com/cover.jpg"},
|
|
},
|
|
}
|
|
|
|
mockService.On("Search", "test", []string(nil)).Return(expectedResult, nil)
|
|
|
|
// Execute
|
|
req, _ := http.NewRequest("GET", "/api/v1/search?q=test", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
// Assert
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestSearchHandlers_Search_WithTypes(t *testing.T) {
|
|
// Setup
|
|
mockService := new(MockSearchService)
|
|
router := setupTestSearchRouter(mockService)
|
|
|
|
expectedResult := &services.SearchResult{
|
|
Tracks: []services.TrackResult{
|
|
{ID: "track-1", Title: "Test Track", Artist: "Test Artist", URL: "http://example.com/track-1"},
|
|
},
|
|
Users: []services.UserResult{},
|
|
Playlists: []services.PlaylistResult{},
|
|
}
|
|
|
|
mockService.On("Search", "test", []string{"track"}).Return(expectedResult, nil)
|
|
|
|
// Execute
|
|
req, _ := http.NewRequest("GET", "/api/v1/search?q=test&type=track", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
// Assert
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestSearchHandlers_Search_MissingQuery(t *testing.T) {
|
|
// Setup
|
|
mockService := new(MockSearchService)
|
|
router := setupTestSearchRouter(mockService)
|
|
|
|
// Execute
|
|
req, _ := http.NewRequest("GET", "/api/v1/search", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
// Assert
|
|
assert.Equal(t, http.StatusBadRequest, w.Code)
|
|
mockService.AssertNotCalled(t, "Search")
|
|
}
|
|
|
|
func TestSearchHandlers_Search_EmptyQuery(t *testing.T) {
|
|
// Setup
|
|
mockService := new(MockSearchService)
|
|
router := setupTestSearchRouter(mockService)
|
|
|
|
// Execute
|
|
req, _ := http.NewRequest("GET", "/api/v1/search?q=", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
// Assert
|
|
assert.Equal(t, http.StatusBadRequest, w.Code)
|
|
mockService.AssertNotCalled(t, "Search")
|
|
}
|
|
|
|
func TestSearchHandlers_Search_ServiceError(t *testing.T) {
|
|
// Setup
|
|
mockService := new(MockSearchService)
|
|
router := setupTestSearchRouter(mockService)
|
|
|
|
mockService.On("Search", "test", []string(nil)).Return(nil, assert.AnError)
|
|
|
|
// Execute
|
|
req, _ := http.NewRequest("GET", "/api/v1/search?q=test", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
// Assert
|
|
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestSearchHandlers_Search_MultipleTypes(t *testing.T) {
|
|
// Setup
|
|
mockService := new(MockSearchService)
|
|
router := setupTestSearchRouter(mockService)
|
|
|
|
expectedResult := &services.SearchResult{
|
|
Tracks: []services.TrackResult{
|
|
{ID: "track-1", Title: "Test Track", Artist: "Test Artist", URL: "http://example.com/track-1"},
|
|
},
|
|
Users: []services.UserResult{
|
|
{ID: "user-1", Username: "testuser", Avatar: "http://example.com/avatar.jpg"},
|
|
},
|
|
Playlists: []services.PlaylistResult{},
|
|
}
|
|
|
|
mockService.On("Search", "test", []string{"track", "user"}).Return(expectedResult, nil)
|
|
|
|
// Execute
|
|
req, _ := http.NewRequest("GET", "/api/v1/search?q=test&type=track&type=user", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
// Assert
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
mockService.AssertExpectations(t)
|
|
}
|
|
|
|
func TestNewSearchHandlers(t *testing.T) {
|
|
// Setup
|
|
mockService := &services.SearchService{}
|
|
|
|
// Execute
|
|
NewSearchHandlers(mockService)
|
|
|
|
// Assert
|
|
assert.NotNil(t, SearchHandlersInstance)
|
|
assert.NotNil(t, SearchHandlersInstance.searchService)
|
|
}
|
|
|