238 lines
5.5 KiB
Go
238 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")
|
||
|
|
}
|