268 lines
6.5 KiB
Go
268 lines
6.5 KiB
Go
package handlers
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"github.com/google/uuid"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
"veza-backend-api/internal/models"
|
|
"veza-backend-api/internal/services"
|
|
)
|
|
|
|
func setupTestPlaylistHandlers(t *testing.T) (*services.PlaylistService, *gorm.DB, func()) {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
// Setup in-memory SQLite database
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
|
|
assert.NoError(t, err)
|
|
|
|
// Enable foreign keys for SQLite
|
|
db.Exec("PRAGMA foreign_keys = ON")
|
|
|
|
// Auto-migrate
|
|
err = db.AutoMigrate(&models.User{}, &models.Track{}, &models.Playlist{}, &models.PlaylistTrack{}, &models.PlaylistCollaborator{})
|
|
assert.NoError(t, err)
|
|
|
|
// Create test user
|
|
user := &models.User{
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
PasswordHash: "hash",
|
|
Slug: "testuser",
|
|
IsActive: true,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
err = db.Create(user).Error
|
|
assert.NoError(t, err)
|
|
|
|
// Setup logger
|
|
logger := zap.NewNop()
|
|
|
|
// Setup service
|
|
playlistService := services.NewPlaylistServiceWithDB(db, logger)
|
|
|
|
// Cleanup function
|
|
cleanup := func() {
|
|
// Database will be closed automatically
|
|
}
|
|
|
|
return playlistService, db, cleanup
|
|
}
|
|
|
|
func TestHandlers_CreatePlaylist_Success(t *testing.T) {
|
|
service, _, cleanup := setupTestPlaylistHandlers(t)
|
|
defer cleanup()
|
|
|
|
// Use local struct matching the handler implementation
|
|
type CreatePlaylistRequest struct {
|
|
Title string `json:"title"`
|
|
Description string `json:"description,omitempty"`
|
|
IsPublic bool `json:"is_public"`
|
|
}
|
|
|
|
reqBody := CreatePlaylistRequest{
|
|
Title: "My Playlist",
|
|
Description: "A test playlist",
|
|
IsPublic: true,
|
|
}
|
|
body, _ := json.Marshal(reqBody)
|
|
|
|
req := httptest.NewRequest("POST", "/api/v1/playlists", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
c, _ := gin.CreateTestContext(httptest.NewRecorder())
|
|
c.Request = req
|
|
c.Set("user_id", 1) // Set user_id as int
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = req
|
|
c.Set("user_id", 1) // Set user_id as int
|
|
|
|
CreatePlaylist(service)(c)
|
|
|
|
assert.Equal(t, http.StatusCreated, w.Code)
|
|
var response map[string]interface{}
|
|
json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NotNil(t, response["playlist"])
|
|
}
|
|
|
|
func TestHandlers_GetPlaylists_Success(t *testing.T) {
|
|
service, db, cleanup := setupTestPlaylistHandlers(t)
|
|
defer cleanup()
|
|
|
|
// Create test playlists
|
|
playlist1 := &models.Playlist{
|
|
UserID: 1,
|
|
Title: "Public Playlist",
|
|
IsPublic: true,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
db.Create(playlist1)
|
|
|
|
req := httptest.NewRequest("GET", "/api/v1/playlists", nil)
|
|
c, _ := gin.CreateTestContext(httptest.NewRecorder())
|
|
c.Request = req
|
|
c.Set("user_id", 1)
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = req
|
|
c.Set("user_id", 1)
|
|
|
|
GetPlaylists(service)(c)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
var response map[string]interface{}
|
|
json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NotNil(t, response["playlists"])
|
|
}
|
|
|
|
func TestHandlers_GetPlaylist_Success(t *testing.T) {
|
|
service, db, cleanup := setupTestPlaylistHandlers(t)
|
|
defer cleanup()
|
|
|
|
// Create test playlist
|
|
playlist := &models.Playlist{
|
|
UserID: 1,
|
|
Title: "My Playlist",
|
|
IsPublic: true,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
db.Create(playlist)
|
|
|
|
req := httptest.NewRequest("GET", "/api/v1/playlists/1", nil)
|
|
c, _ := gin.CreateTestContext(httptest.NewRecorder())
|
|
c.Request = req
|
|
c.Set("user_id", 1)
|
|
c.Params = gin.Params{gin.Param{Key: "id", Value: "1"}}
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = req
|
|
c.Set("user_id", 1)
|
|
c.Params = gin.Params{gin.Param{Key: "id", Value: "1"}}
|
|
|
|
GetPlaylist(service)(c)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
var response map[string]interface{}
|
|
json.Unmarshal(w.Body.Bytes(), &response)
|
|
assert.NotNil(t, response["playlist"])
|
|
}
|
|
|
|
func TestHandlers_AddTrack_Success(t *testing.T) {
|
|
service, db, cleanup := setupTestPlaylistHandlers(t)
|
|
defer cleanup()
|
|
|
|
// Create test track
|
|
track := &models.Track{
|
|
UserID: 1,
|
|
Title: "Test Track",
|
|
FilePath: "/test/track.mp3",
|
|
Format: "mp3",
|
|
IsPublic: true,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
db.Create(track)
|
|
|
|
// Create test playlist
|
|
playlist := &models.Playlist{
|
|
UserID: 1,
|
|
Title: "My Playlist",
|
|
IsPublic: true,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
db.Create(playlist)
|
|
|
|
// Handler uses AddTrackToPlaylistRequest
|
|
type AddTrackToPlaylistRequest struct {
|
|
TrackID int64 `json:"track_id"`
|
|
Position int `json:"position,omitempty"`
|
|
}
|
|
reqBody := AddTrackToPlaylistRequest{
|
|
TrackID: track.ID,
|
|
}
|
|
body, _ := json.Marshal(reqBody)
|
|
|
|
req := httptest.NewRequest("POST", "/api/v1/playlists/1/tracks", bytes.NewBuffer(body))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
c, _ := gin.CreateTestContext(httptest.NewRecorder())
|
|
c.Request = req
|
|
c.Set("user_id", 1)
|
|
c.Params = gin.Params{gin.Param{Key: "id", Value: "1"}}
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = req
|
|
c.Set("user_id", 1)
|
|
c.Params = gin.Params{gin.Param{Key: "id", Value: "1"}}
|
|
|
|
AddTrackToPlaylist(service)(c)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|
|
|
|
func TestHandlers_RemoveTrack_Success(t *testing.T) {
|
|
service, db, cleanup := setupTestPlaylistHandlers(t)
|
|
defer cleanup()
|
|
|
|
// Create test track
|
|
track := &models.Track{
|
|
UserID: 1,
|
|
Title: "Test Track",
|
|
FilePath: "/test/track.mp3",
|
|
Format: "mp3",
|
|
IsPublic: true,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
db.Create(track)
|
|
|
|
// Create test playlist
|
|
playlist := &models.Playlist{
|
|
UserID: 1,
|
|
Title: "My Playlist",
|
|
IsPublic: true,
|
|
CreatedAt: time.Now(),
|
|
}
|
|
db.Create(playlist)
|
|
|
|
// Add track to playlist using repository directly to setup state
|
|
err := db.Create(&models.PlaylistTrack{
|
|
PlaylistID: playlist.ID,
|
|
TrackID: track.ID,
|
|
Position: 1,
|
|
}).Error
|
|
require.NoError(t, err)
|
|
|
|
req := httptest.NewRequest("DELETE", "/api/v1/playlists/1/tracks/1", nil)
|
|
c, _ := gin.CreateTestContext(httptest.NewRecorder())
|
|
c.Request = req
|
|
c.Set("user_id", 1)
|
|
c.Params = gin.Params{
|
|
gin.Param{Key: "id", Value: "1"},
|
|
gin.Param{Key: "track_id", Value: "1"},
|
|
}
|
|
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Request = req
|
|
c.Set("user_id", 1)
|
|
c.Params = gin.Params{
|
|
gin.Param{Key: "id", Value: "1"},
|
|
gin.Param{Key: "track_id", Value: "1"},
|
|
}
|
|
|
|
RemoveTrackFromPlaylist(service)(c)
|
|
|
|
assert.Equal(t, http.StatusOK, w.Code)
|
|
}
|