492 lines
13 KiB
Go
492 lines
13 KiB
Go
package testutils
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"veza-backend-api/internal/models"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// CreateTestUser crée un utilisateur de test avec des valeurs par défaut
|
|
func CreateTestUser(db *gorm.DB) (*models.User, error) {
|
|
// Make username and email unique to avoid constraint violations when tests share the same DB
|
|
uniqueID := strings.ReplaceAll(uuid.New().String()[:8], "-", "")
|
|
uniqueUsername := fmt.Sprintf("testuser_%s", uniqueID)
|
|
uniqueEmail := fmt.Sprintf("test_%s@example.com", uniqueID)
|
|
// Slug must also be unique - use the same uniqueID to ensure uniqueness
|
|
uniqueSlug := fmt.Sprintf("testuser-%s", uniqueID)
|
|
|
|
user := &models.User{
|
|
Username: uniqueUsername,
|
|
Slug: uniqueSlug,
|
|
Email: uniqueEmail,
|
|
PasswordHash: "$2a$10$examplehash", // Hash bcrypt factice
|
|
TokenVersion: 0,
|
|
FirstName: "Test",
|
|
LastName: "User",
|
|
Role: "user",
|
|
IsActive: true,
|
|
IsVerified: true,
|
|
IsAdmin: false,
|
|
}
|
|
|
|
if err := db.Create(user).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
// CreateTestUserWithCustomData crée un utilisateur de test avec des données personnalisées
|
|
func CreateTestUserWithCustomData(db *gorm.DB, username, email string) (*models.User, error) {
|
|
// Make username and email unique to avoid constraint violations
|
|
// Username must match ^[a-zA-Z0-9_]{3,30}$ (no dashes, only alphanum + underscore)
|
|
uniqueID := strings.ReplaceAll(uuid.New().String()[:8], "-", "") // Remove dashes from UUID
|
|
// Ensure username doesn't exceed 30 chars (constraint limit)
|
|
maxUsernameLen := 30
|
|
uniqueUsername := fmt.Sprintf("%s_%s", username, uniqueID)
|
|
if len(uniqueUsername) > maxUsernameLen {
|
|
// Truncate username part if needed
|
|
maxUsernamePartLen := maxUsernameLen - len(uniqueID) - 1 // -1 for underscore
|
|
if maxUsernamePartLen < 1 {
|
|
maxUsernamePartLen = 1
|
|
}
|
|
uniqueUsername = fmt.Sprintf("%s_%s", username[:maxUsernamePartLen], uniqueID)
|
|
}
|
|
|
|
// Extract email parts and add unique ID
|
|
emailParts := strings.Split(email, "@")
|
|
if len(emailParts) != 2 {
|
|
return nil, fmt.Errorf("invalid email format: %s", email)
|
|
}
|
|
uniqueEmail := fmt.Sprintf("%s_%s@%s", emailParts[0], uniqueID, emailParts[1])
|
|
|
|
// Slug must also be unique - generate from username with uniqueID
|
|
// Slugify converts underscores to dashes, so "customuser_abc123" becomes "customuser-abc123"
|
|
uniqueSlug := fmt.Sprintf("%s-%s", strings.ToLower(username), uniqueID)
|
|
|
|
user := &models.User{
|
|
Username: uniqueUsername,
|
|
Slug: uniqueSlug,
|
|
Email: uniqueEmail,
|
|
PasswordHash: "$2a$10$examplehash",
|
|
TokenVersion: 0,
|
|
FirstName: "Test",
|
|
LastName: "User",
|
|
Role: "user",
|
|
IsActive: true,
|
|
IsVerified: true,
|
|
IsAdmin: false,
|
|
}
|
|
|
|
if err := db.Create(user).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
// CreateTestAdmin crée un utilisateur administrateur de test
|
|
func CreateTestAdmin(db *gorm.DB) (*models.User, error) {
|
|
// Make username and email unique to avoid constraint violations when tests share the same DB
|
|
uniqueID := strings.ReplaceAll(uuid.New().String()[:8], "-", "")
|
|
uniqueUsername := fmt.Sprintf("admin_%s", uniqueID)
|
|
uniqueEmail := fmt.Sprintf("admin_%s@example.com", uniqueID)
|
|
// Slug must also be unique - use the same uniqueID to ensure uniqueness
|
|
uniqueSlug := fmt.Sprintf("admin-%s", uniqueID)
|
|
|
|
user := &models.User{
|
|
Username: uniqueUsername,
|
|
Slug: uniqueSlug,
|
|
Email: uniqueEmail,
|
|
PasswordHash: "$2a$10$examplehash",
|
|
TokenVersion: 0,
|
|
FirstName: "Admin",
|
|
LastName: "User",
|
|
Role: "admin",
|
|
IsActive: true,
|
|
IsVerified: true,
|
|
IsAdmin: true,
|
|
}
|
|
|
|
if err := db.Create(user).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return user, nil
|
|
}
|
|
|
|
// CreateTestTrack crée un track de test
|
|
func CreateTestTrack(db *gorm.DB, userID uuid.UUID) (*models.Track, error) {
|
|
track := &models.Track{
|
|
UserID: userID,
|
|
Title: "Test Track",
|
|
Artist: "Test Artist",
|
|
Duration: 180, // 3 minutes
|
|
FilePath: "uploads/test_track.mp3",
|
|
FileSize: 1024 * 1024 * 5, // 5MB
|
|
Format: "mp3",
|
|
}
|
|
|
|
if err := db.Create(track).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return track, nil
|
|
}
|
|
|
|
// CreateTestTrackWithCustomData crée un track de test avec des données personnalisées
|
|
func CreateTestTrackWithCustomData(db *gorm.DB, userID uuid.UUID, title, artist string) (*models.Track, error) {
|
|
track := &models.Track{
|
|
UserID: userID,
|
|
Title: title,
|
|
Artist: artist,
|
|
Duration: 180,
|
|
FilePath: "uploads/test_track.mp3",
|
|
FileSize: 1024 * 1024 * 5,
|
|
Format: "mp3",
|
|
}
|
|
|
|
if err := db.Create(track).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return track, nil
|
|
}
|
|
|
|
// CreateTestPlaylist crée une playlist de test
|
|
func CreateTestPlaylist(db *gorm.DB, userID uuid.UUID) (*models.Playlist, error) {
|
|
playlist := &models.Playlist{
|
|
UserID: userID,
|
|
Title: "Test Playlist",
|
|
Description: "A test playlist",
|
|
}
|
|
|
|
if err := db.Create(playlist).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return playlist, nil
|
|
}
|
|
|
|
// CreateTestRoom crée une room de test
|
|
func CreateTestRoom(db *gorm.DB, createdBy uuid.UUID) (*models.Room, error) {
|
|
room := &models.Room{
|
|
Name: "Test Room",
|
|
Description: "A test room",
|
|
Type: "public",
|
|
IsPrivate: false,
|
|
CreatedBy: createdBy,
|
|
}
|
|
|
|
if err := db.Create(room).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return room, nil
|
|
}
|
|
|
|
// CreateTestMessage crée un message de test
|
|
func CreateTestMessage(db *gorm.DB, roomID uuid.UUID, userID uuid.UUID, content string) (*models.Message, error) {
|
|
message := &models.Message{
|
|
RoomID: roomID,
|
|
UserID: userID,
|
|
Content: content,
|
|
Type: "text",
|
|
IsEdited: false,
|
|
IsDeleted: false,
|
|
}
|
|
|
|
if err := db.Create(message).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return message, nil
|
|
}
|
|
|
|
// CreateTestSession crée une session de test
|
|
func CreateTestSession(db *gorm.DB, userID uuid.UUID) (*models.Session, error) {
|
|
session := &models.Session{
|
|
UserID: userID,
|
|
Token: "test_hash_" + uuid.New().String(),
|
|
IPAddress: "127.0.0.1",
|
|
UserAgent: "test-agent",
|
|
ExpiresAt: time.Now().Add(24 * time.Hour),
|
|
}
|
|
|
|
if err := db.Create(session).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return session, nil
|
|
}
|
|
|
|
// CreateMultipleTestUsers crée plusieurs utilisateurs de test
|
|
func CreateMultipleTestUsers(db *gorm.DB, count int) ([]*models.User, error) {
|
|
users := make([]*models.User, 0, count)
|
|
|
|
for i := 1; i <= count; i++ {
|
|
// Make username and email unique to avoid constraint violations when tests share the same DB
|
|
uniqueID := strings.ReplaceAll(uuid.New().String()[:8], "-", "")
|
|
uniqueUsername := fmt.Sprintf("testuser%d_%s", i, uniqueID)
|
|
uniqueEmail := fmt.Sprintf("test%d_%s@example.com", i, uniqueID)
|
|
uniqueSlug := fmt.Sprintf("testuser%d-%s", i, uniqueID)
|
|
|
|
user := &models.User{
|
|
Username: uniqueUsername,
|
|
Slug: uniqueSlug,
|
|
Email: uniqueEmail,
|
|
PasswordHash: "$2a$10$examplehash",
|
|
TokenVersion: 0,
|
|
FirstName: "Test",
|
|
LastName: "User",
|
|
Role: "user",
|
|
IsActive: true,
|
|
IsVerified: true,
|
|
IsAdmin: false,
|
|
}
|
|
|
|
if err := db.Create(user).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
users = append(users, user)
|
|
}
|
|
|
|
return users, nil
|
|
}
|
|
|
|
// CreateMultipleTestTracks crée plusieurs tracks de test pour un créateur
|
|
func CreateMultipleTestTracks(db *gorm.DB, userID uuid.UUID, count int) ([]*models.Track, error) {
|
|
tracks := make([]*models.Track, 0, count)
|
|
|
|
for i := 1; i <= count; i++ {
|
|
track := &models.Track{
|
|
UserID: userID,
|
|
Title: fmt.Sprintf("Test Track %d", i),
|
|
Artist: "Test Artist",
|
|
Duration: 180,
|
|
FilePath: "uploads/test_track.mp3",
|
|
FileSize: 1024 * 1024,
|
|
Format: "mp3",
|
|
}
|
|
|
|
if err := db.Create(track).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tracks = append(tracks, track)
|
|
}
|
|
|
|
return tracks, nil
|
|
}
|
|
|
|
// UserFactory crée des utilisateurs de test avec pattern Builder
|
|
type UserFactory struct {
|
|
user *models.User
|
|
}
|
|
|
|
// NewUserFactory crée un nouveau factory avec valeurs par défaut
|
|
func NewUserFactory() *UserFactory {
|
|
return &UserFactory{
|
|
user: &models.User{
|
|
Username: "testuser",
|
|
Email: "test@example.com",
|
|
PasswordHash: "$2a$10$examplehash",
|
|
TokenVersion: 0,
|
|
FirstName: "Test",
|
|
LastName: "User",
|
|
Role: "user",
|
|
IsActive: true,
|
|
IsVerified: true,
|
|
IsAdmin: false,
|
|
},
|
|
}
|
|
}
|
|
|
|
// WithUsername définit le username
|
|
func (f *UserFactory) WithUsername(username string) *UserFactory {
|
|
f.user.Username = username
|
|
return f
|
|
}
|
|
|
|
// WithEmail définit l'email
|
|
func (f *UserFactory) WithEmail(email string) *UserFactory {
|
|
f.user.Email = email
|
|
return f
|
|
}
|
|
|
|
// WithRole définit le rôle
|
|
func (f *UserFactory) WithRole(role string) *UserFactory {
|
|
f.user.Role = role
|
|
if role == "admin" {
|
|
f.user.IsAdmin = true
|
|
}
|
|
return f
|
|
}
|
|
|
|
// WithPasswordHash définit le hash du mot de passe
|
|
func (f *UserFactory) WithPasswordHash(hash string) *UserFactory {
|
|
f.user.PasswordHash = hash
|
|
return f
|
|
}
|
|
|
|
// WithFirstName définit le prénom
|
|
func (f *UserFactory) WithFirstName(firstName string) *UserFactory {
|
|
f.user.FirstName = firstName
|
|
return f
|
|
}
|
|
|
|
// WithLastName définit le nom
|
|
func (f *UserFactory) WithLastName(lastName string) *UserFactory {
|
|
f.user.LastName = lastName
|
|
return f
|
|
}
|
|
|
|
// WithIsActive définit si l'utilisateur est actif
|
|
func (f *UserFactory) WithIsActive(isActive bool) *UserFactory {
|
|
f.user.IsActive = isActive
|
|
return f
|
|
}
|
|
|
|
// WithIsVerified définit si l'utilisateur est vérifié
|
|
func (f *UserFactory) WithIsVerified(isVerified bool) *UserFactory {
|
|
f.user.IsVerified = isVerified
|
|
return f
|
|
}
|
|
|
|
// Build construit l'utilisateur sans sauvegarder
|
|
func (f *UserFactory) Build() *models.User {
|
|
return f.user
|
|
}
|
|
|
|
// MustBuild construit et sauvegarde en DB
|
|
func (f *UserFactory) MustBuild(db *gorm.DB) *models.User {
|
|
user := f.Build()
|
|
if err := db.Create(user).Error; err != nil {
|
|
panic(err)
|
|
}
|
|
return user
|
|
}
|
|
|
|
// TrackFactory crée des tracks de test avec pattern Builder
|
|
type TrackFactory struct {
|
|
track *models.Track
|
|
}
|
|
|
|
// NewTrackFactory crée un nouveau factory avec valeurs par défaut
|
|
func NewTrackFactory(userID uuid.UUID) *TrackFactory {
|
|
return &TrackFactory{
|
|
track: &models.Track{
|
|
UserID: userID,
|
|
Title: "Test Track",
|
|
Artist: "Test Artist",
|
|
Duration: 180, // 3 minutes
|
|
FilePath: "uploads/test_track.mp3",
|
|
FileSize: 1024 * 1024,
|
|
Format: "mp3",
|
|
},
|
|
}
|
|
}
|
|
|
|
// WithTitle définit le titre
|
|
func (f *TrackFactory) WithTitle(title string) *TrackFactory {
|
|
f.track.Title = title
|
|
return f
|
|
}
|
|
|
|
// WithArtist définit l'artiste
|
|
func (f *TrackFactory) WithArtist(artist string) *TrackFactory {
|
|
f.track.Artist = artist
|
|
return f
|
|
}
|
|
|
|
// WithDuration définit la durée en secondes
|
|
func (f *TrackFactory) WithDuration(duration int) *TrackFactory {
|
|
f.track.Duration = duration
|
|
return f
|
|
}
|
|
|
|
// Build construit le track sans sauvegarder
|
|
func (f *TrackFactory) Build() *models.Track {
|
|
return f.track
|
|
}
|
|
|
|
// MustBuild construit et sauvegarde en DB
|
|
func (f *TrackFactory) MustBuild(db *gorm.DB) *models.Track {
|
|
track := f.Build()
|
|
if err := db.Create(track).Error; err != nil {
|
|
panic(err)
|
|
}
|
|
return track
|
|
}
|
|
|
|
// PlaylistFactory crée des playlists de test avec pattern Builder
|
|
type PlaylistFactory struct {
|
|
playlist *models.Playlist
|
|
}
|
|
|
|
// NewPlaylistFactory crée un nouveau factory avec valeurs par défaut
|
|
func NewPlaylistFactory(userID uuid.UUID) *PlaylistFactory {
|
|
return &PlaylistFactory{
|
|
playlist: &models.Playlist{
|
|
UserID: userID,
|
|
Title: "Test Playlist",
|
|
Description: "A test playlist",
|
|
},
|
|
}
|
|
}
|
|
|
|
// WithName définit le titre (Mapped to Title)
|
|
func (f *PlaylistFactory) WithName(name string) *PlaylistFactory {
|
|
f.playlist.Title = name
|
|
return f
|
|
}
|
|
|
|
// WithDescription définit la description
|
|
func (f *PlaylistFactory) WithDescription(description string) *PlaylistFactory {
|
|
f.playlist.Description = description
|
|
return f
|
|
}
|
|
|
|
// Build construit la playlist sans sauvegarder
|
|
func (f *PlaylistFactory) Build() *models.Playlist {
|
|
return f.playlist
|
|
}
|
|
|
|
// MustBuild construit et sauvegarde en DB
|
|
func (f *PlaylistFactory) MustBuild(db *gorm.DB) *models.Playlist {
|
|
playlist := f.Build()
|
|
if err := db.Create(playlist).Error; err != nil {
|
|
panic(err)
|
|
}
|
|
return playlist
|
|
}
|
|
|
|
// CreateUsers crée N utilisateurs avec factories
|
|
func CreateUsers(db *gorm.DB, count int) []*models.User {
|
|
users := make([]*models.User, count)
|
|
for i := 0; i < count; i++ {
|
|
factory := NewUserFactory().
|
|
WithUsername(fmt.Sprintf("user%d", i)).
|
|
WithEmail(fmt.Sprintf("user%d@example.com", i))
|
|
users[i] = factory.MustBuild(db)
|
|
}
|
|
return users
|
|
}
|
|
|
|
// CreateTracks crée N tracks avec factories
|
|
func CreateTracks(db *gorm.DB, userID uuid.UUID, count int) []*models.Track {
|
|
tracks := make([]*models.Track, count)
|
|
for i := 0; i < count; i++ {
|
|
factory := NewTrackFactory(userID).
|
|
WithTitle(fmt.Sprintf("Test Track %d", i+1)).
|
|
WithArtist(fmt.Sprintf("Test Artist %d", i+1))
|
|
tracks[i] = factory.MustBuild(db)
|
|
}
|
|
return tracks
|
|
}
|