veza/veza-backend-api/internal/services/track_like_service_test.go

593 lines
14 KiB
Go

package services
import (
"context"
"fmt"
"github.com/google/uuid"
"testing"
"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"
)
func setupTestTrackLikeService(t *testing.T) (*TrackLikeService, *gorm.DB, func()) {
// Setup in-memory SQLite database
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
require.NoError(t, err)
// Auto-migrate
err = db.AutoMigrate(&models.User{}, &models.Track{}, &models.TrackLike{})
require.NoError(t, err)
// Setup logger
logger := zap.NewNop()
// Setup service
service := NewTrackLikeService(db, logger)
// Cleanup function
cleanup := func() {
// Database will be closed automatically
}
return service, db, cleanup
}
func TestTrackLikeService_LikeTrack_Success(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test user
user := &models.User{
ID: userID,
Username: "testuser",
Email: "test@example.com",
IsActive: true,
}
err := db.Create(user).Error
require.NoError(t, err)
// Create test track
track := &models.Track{
UserID: userID,
Title: "Test Track",
FilePath: "/test/track.mp3",
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
LikeCount: 0,
}
err = db.Create(track).Error
require.NoError(t, err)
// Like track
err = service.LikeTrack(ctx, userID, track.ID)
assert.NoError(t, err)
// Verify like was created
var like models.TrackLike
err = db.Where("user_id = ? AND track_id = ?", userID, track.ID).First(&like).Error
assert.NoError(t, err)
assert.Equal(t, userID, like.UserID)
assert.Equal(t, track.ID, like.TrackID)
// Verify track like_count was updated
var updatedTrack models.Track
err = db.First(&updatedTrack, "id = ?", track.ID).Error
assert.NoError(t, err)
assert.Equal(t, int64(1), updatedTrack.LikeCount)
}
func TestTrackLikeService_LikeTrack_AlreadyLiked(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test user
user := &models.User{
ID: userID,
Username: "testuser",
Email: "test@example.com",
IsActive: true,
}
err := db.Create(user).Error
require.NoError(t, err)
// Create test track
track := &models.Track{
UserID: userID,
Title: "Test Track",
FilePath: "/test/track.mp3",
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
LikeCount: 0,
}
err = db.Create(track).Error
require.NoError(t, err)
// Like track first time
err = service.LikeTrack(ctx, userID, track.ID)
assert.NoError(t, err)
// Try to like again (should be idempotent)
err = service.LikeTrack(ctx, userID, track.ID)
assert.NoError(t, err)
// Verify only one like exists
var count int64
db.Model(&models.TrackLike{}).Where("user_id = ? AND track_id = ?", userID, track.ID).Count(&count)
assert.Equal(t, int64(1), count)
}
func TestTrackLikeService_LikeTrack_TrackNotFound(t *testing.T) {
service, _, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
// Try to like non-existent track
err := service.LikeTrack(ctx, uuid.New(), uuid.New())
assert.Error(t, err)
assert.Contains(t, err.Error(), "track not found")
}
func TestTrackLikeService_UnlikeTrack_Success(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test user
user := &models.User{
ID: userID,
Username: "testuser",
Email: "test@example.com",
IsActive: true,
}
err := db.Create(user).Error
require.NoError(t, err)
// Create test track
track := &models.Track{
UserID: userID,
Title: "Test Track",
FilePath: "/test/track.mp3",
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
LikeCount: 1,
}
err = db.Create(track).Error
require.NoError(t, err)
// Create like
like := &models.TrackLike{
UserID: userID,
TrackID: track.ID,
}
err = db.Create(like).Error
require.NoError(t, err)
// Unlike track
err = service.UnlikeTrack(ctx, userID, track.ID)
assert.NoError(t, err)
// Verify like was deleted
var count int64
db.Model(&models.TrackLike{}).Where("user_id = ? AND track_id = ?", userID, track.ID).Count(&count)
assert.Equal(t, int64(0), count)
// Verify track like_count was updated
var updatedTrack models.Track
err = db.First(&updatedTrack, "id = ?", track.ID).Error
assert.NoError(t, err)
assert.Equal(t, int64(0), updatedTrack.LikeCount)
}
func TestTrackLikeService_UnlikeTrack_NotLiked(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test user
user := &models.User{
ID: userID,
Username: "testuser",
Email: "test@example.com",
IsActive: true,
}
err := db.Create(user).Error
require.NoError(t, err)
// Create test track
track := &models.Track{
UserID: userID,
Title: "Test Track",
FilePath: "/test/track.mp3",
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
LikeCount: 0,
}
err = db.Create(track).Error
require.NoError(t, err)
// Try to unlike (should be idempotent)
err = service.UnlikeTrack(ctx, userID, track.ID)
assert.NoError(t, err)
}
func TestTrackLikeService_IsLiked_True(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test user
user := &models.User{
ID: userID,
Username: "testuser",
Email: "test@example.com",
IsActive: true,
}
err := db.Create(user).Error
require.NoError(t, err)
// Create test track
track := &models.Track{
UserID: userID,
Title: "Test Track",
FilePath: "/test/track.mp3",
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
}
err = db.Create(track).Error
require.NoError(t, err)
// Create like
like := &models.TrackLike{
UserID: userID,
TrackID: track.ID,
}
err = db.Create(like).Error
require.NoError(t, err)
// Check if liked
isLiked, err := service.IsLiked(ctx, userID, track.ID)
assert.NoError(t, err)
assert.True(t, isLiked)
}
func TestTrackLikeService_IsLiked_False(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test user
user := &models.User{
ID: userID,
Username: "testuser",
Email: "test@example.com",
IsActive: true,
}
err := db.Create(user).Error
require.NoError(t, err)
// Create test track
track := &models.Track{
UserID: userID,
Title: "Test Track",
FilePath: "/test/track.mp3",
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
}
err = db.Create(track).Error
require.NoError(t, err)
// Check if liked (should be false)
isLiked, err := service.IsLiked(ctx, userID, track.ID)
assert.NoError(t, err)
assert.False(t, isLiked)
}
func TestTrackLikeService_GetTrackLikesCount(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID1 := uuid.New()
userID2 := uuid.New()
// Create test users
user1 := &models.User{
ID: userID1,
Username: "testuser1",
Email: "test1@example.com",
IsActive: true,
}
err := db.Create(user1).Error
require.NoError(t, err)
user2 := &models.User{
ID: userID2,
Username: "testuser2",
Email: "test2@example.com",
IsActive: true,
}
err = db.Create(user2).Error
require.NoError(t, err)
// Create test track
track := &models.Track{
UserID: userID1,
Title: "Test Track",
FilePath: "/test/track.mp3",
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
}
err = db.Create(track).Error
require.NoError(t, err)
// Create likes
like1 := &models.TrackLike{UserID: userID1, TrackID: track.ID}
err = db.Create(like1).Error
require.NoError(t, err)
like2 := &models.TrackLike{UserID: userID2, TrackID: track.ID}
err = db.Create(like2).Error
require.NoError(t, err)
// Get likes count
count, err := service.GetTrackLikesCount(ctx, track.ID)
assert.NoError(t, err)
assert.Equal(t, int64(2), count)
}
func TestTrackLikeService_GetTrackLikesCount_Zero(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test track
track := &models.Track{
UserID: userID,
Title: "Test Track",
FilePath: "/test/track.mp3",
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
}
err := db.Create(track).Error
require.NoError(t, err)
// Get likes count (should be 0)
count, err := service.GetTrackLikesCount(ctx, track.ID)
assert.NoError(t, err)
assert.Equal(t, int64(0), count)
}
func TestTrackLikeService_GetUserLikedTracks(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test user
user := &models.User{
ID: userID,
Username: "testuser",
Email: "test@example.com",
IsActive: true,
}
err := db.Create(user).Error
require.NoError(t, err)
// Create test tracks
track1 := &models.Track{
UserID: userID,
Title: "Track 1",
FilePath: "/test/track1.mp3",
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
}
err = db.Create(track1).Error
require.NoError(t, err)
track2 := &models.Track{
UserID: userID,
Title: "Track 2",
FilePath: "/test/track2.mp3",
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
}
err = db.Create(track2).Error
require.NoError(t, err)
// Create likes
like1 := &models.TrackLike{UserID: userID, TrackID: track1.ID}
err = db.Create(like1).Error
require.NoError(t, err)
like2 := &models.TrackLike{UserID: userID, TrackID: track2.ID}
err = db.Create(like2).Error
require.NoError(t, err)
// Get user liked tracks
tracks, err := service.GetUserLikedTracks(ctx, userID, 10, 0)
assert.NoError(t, err)
assert.Equal(t, 2, len(tracks))
}
func TestTrackLikeService_GetUserLikedTracks_WithLimit(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test user
user := &models.User{
ID: userID,
Username: "testuser",
Email: "test@example.com",
IsActive: true,
}
err := db.Create(user).Error
require.NoError(t, err)
// Create test tracks
for i := 1; i <= 5; i++ {
track := &models.Track{
UserID: userID,
Title: fmt.Sprintf("Track %d", i),
FilePath: fmt.Sprintf("/test/track%d.mp3", i),
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
}
err = db.Create(track).Error
require.NoError(t, err)
like := &models.TrackLike{UserID: userID, TrackID: track.ID}
err = db.Create(like).Error
require.NoError(t, err)
}
// Get user liked tracks with limit
tracks, err := service.GetUserLikedTracks(ctx, userID, 3, 0)
assert.NoError(t, err)
assert.Equal(t, 3, len(tracks))
}
func TestTrackLikeService_GetUserLikedTracks_WithOffset(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test user
user := &models.User{
ID: userID,
Username: "testuser",
Email: "test@example.com",
IsActive: true,
}
err := db.Create(user).Error
require.NoError(t, err)
// Create test tracks
for i := 1; i <= 5; i++ {
track := &models.Track{
UserID: userID,
Title: fmt.Sprintf("Track %d", i),
FilePath: fmt.Sprintf("/test/track%d.mp3", i),
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
}
err = db.Create(track).Error
require.NoError(t, err)
like := &models.TrackLike{UserID: userID, TrackID: track.ID}
err = db.Create(like).Error
require.NoError(t, err)
}
// Get user liked tracks with offset
tracks, err := service.GetUserLikedTracks(ctx, userID, 3, 2)
assert.NoError(t, err)
assert.Equal(t, 3, len(tracks))
}
func TestTrackLikeService_GetUserLikedTracksCount(t *testing.T) {
service, db, cleanup := setupTestTrackLikeService(t)
defer cleanup()
ctx := context.Background()
userID := uuid.New()
// Create test user
user := &models.User{
ID: userID,
Username: "testuser",
Email: "test@example.com",
IsActive: true,
}
err := db.Create(user).Error
require.NoError(t, err)
// Create test tracks
for i := 1; i <= 3; i++ {
track := &models.Track{
UserID: userID,
Title: fmt.Sprintf("Track %d", i),
FilePath: fmt.Sprintf("/test/track%d.mp3", i),
FileSize: 5 * 1024 * 1024,
Format: "MP3",
Duration: 180,
IsPublic: true,
Status: models.TrackStatusCompleted,
}
err = db.Create(track).Error
require.NoError(t, err)
like := &models.TrackLike{UserID: userID, TrackID: track.ID}
err = db.Create(like).Error
require.NoError(t, err)
}
// Get user liked tracks count
count, err := service.GetUserLikedTracksCount(ctx, userID)
assert.NoError(t, err)
assert.Equal(t, int64(3), count)
}