veza/veza-backend-api/internal/utils/playlist_validator_test.go
2025-12-03 20:29:37 +01:00

237 lines
5.5 KiB
Go

package utils
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestValidatePlaylistTitle(t *testing.T) {
tests := []struct {
name string
title string
wantError bool
errorType error
}{
{
name: "valid title",
title: "My Awesome Playlist",
wantError: false,
},
{
name: "valid title with special characters",
title: "Playlist #1 - Best Songs",
wantError: false,
},
{
name: "valid title exactly 200 characters",
title: strings.Repeat("a", 200),
wantError: false,
},
{
name: "empty title",
title: "",
wantError: true,
errorType: ErrPlaylistTitleRequired,
},
{
name: "title with only spaces",
title: " ",
wantError: true,
errorType: ErrPlaylistTitleRequired,
},
{
name: "title with only tabs",
title: "\t\t\t",
wantError: true,
errorType: ErrPlaylistTitleRequired,
},
{
name: "title too long",
title: strings.Repeat("a", 201),
wantError: true,
errorType: ErrPlaylistTitleTooLong,
},
{
name: "title with leading/trailing spaces but valid",
title: " My Playlist ",
wantError: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidatePlaylistTitle(tt.title)
if tt.wantError {
assert.Error(t, err)
if tt.errorType != nil {
assert.Equal(t, tt.errorType, err)
}
} else {
assert.NoError(t, err)
}
})
}
}
func TestValidatePlaylistDescription(t *testing.T) {
tests := []struct {
name string
description string
wantError bool
errorType error
}{
{
name: "valid description",
description: "This is a great playlist with amazing songs",
wantError: false,
},
{
name: "empty description",
description: "",
wantError: false, // Description is optional
},
{
name: "valid description exactly 2000 characters",
description: strings.Repeat("a", 2000),
wantError: false,
},
{
name: "description too long",
description: strings.Repeat("a", 2001),
wantError: true,
errorType: ErrPlaylistDescTooLong,
},
{
name: "description with special characters",
description: "Playlist with émojis 🎵 and special chars: !@#$%",
wantError: false,
},
{
name: "description with newlines",
description: "Line 1\nLine 2\nLine 3",
wantError: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidatePlaylistDescription(tt.description)
if tt.wantError {
assert.Error(t, err)
if tt.errorType != nil {
assert.Equal(t, tt.errorType, err)
}
} else {
assert.NoError(t, err)
}
})
}
}
func TestValidateCoverURL(t *testing.T) {
tests := []struct {
name string
coverURL string
wantError bool
errorType error
}{
{
name: "valid HTTPS URL",
coverURL: "https://example.com/cover.jpg",
wantError: false,
},
{
name: "valid HTTP URL",
coverURL: "http://example.com/cover.jpg",
wantError: false,
},
{
name: "valid URL with query parameters",
coverURL: "https://example.com/cover.jpg?w=500&h=500",
wantError: false,
},
{
name: "valid URL with path",
coverURL: "https://cdn.example.com/images/covers/playlist-123.jpg",
wantError: false,
},
{
name: "empty URL",
coverURL: "",
wantError: false, // Cover URL is optional
},
{
name: "invalid URL - no scheme",
coverURL: "example.com/cover.jpg",
wantError: true,
errorType: ErrInvalidCoverURL,
},
{
name: "invalid URL - invalid scheme",
coverURL: "ftp://example.com/cover.jpg",
wantError: true,
errorType: ErrInvalidCoverURL,
},
{
name: "invalid URL - malformed",
coverURL: "not a valid url",
wantError: true,
errorType: ErrInvalidCoverURL,
},
{
name: "URL too long",
coverURL: "https://example.com/" + strings.Repeat("a", 500),
wantError: true,
errorType: ErrCoverURLTooLong,
},
{
name: "valid URL exactly 500 characters",
coverURL: "https://example.com/" + strings.Repeat("a", 500-22), // 22 = len("https://example.com/")
wantError: false,
},
{
name: "invalid URL - file scheme",
coverURL: "file:///path/to/cover.jpg",
wantError: true,
errorType: ErrInvalidCoverURL,
},
{
name: "invalid URL - javascript scheme",
coverURL: "javascript:alert('xss')",
wantError: true,
errorType: ErrInvalidCoverURL,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateCoverURL(tt.coverURL)
if tt.wantError {
assert.Error(t, err)
if tt.errorType != nil {
assert.Equal(t, tt.errorType, err)
}
} else {
assert.NoError(t, err)
}
})
}
}
// Test pour vérifier que les erreurs sont bien exportées
func TestPlaylistValidatorErrors(t *testing.T) {
assert.NotNil(t, ErrPlaylistTitleRequired)
assert.NotNil(t, ErrPlaylistTitleTooLong)
assert.NotNil(t, ErrPlaylistDescTooLong)
assert.NotNil(t, ErrInvalidCoverURL)
assert.NotNil(t, ErrCoverURLTooLong)
// Vérifier les messages d'erreur
assert.Contains(t, ErrPlaylistTitleRequired.Error(), "title is required")
assert.Contains(t, ErrPlaylistTitleTooLong.Error(), "title must be less than 200")
assert.Contains(t, ErrPlaylistDescTooLong.Error(), "description must be less than 2000")
assert.Contains(t, ErrInvalidCoverURL.Error(), "invalid cover URL")
assert.Contains(t, ErrCoverURLTooLong.Error(), "cover URL must be less than 500")
}