INT-04: Fixed nil UserID panic in AuditService (re-enabled 2 tests). Added INT-04 comments explaining skip reasons for tests requiring PostgreSQL, real file headers, or external services.
317 lines
9.5 KiB
Go
317 lines
9.5 KiB
Go
package services
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
|
|
"veza-backend-api/internal/database"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func setupTestEmailService(t *testing.T) *EmailService {
|
|
testDB := &database.Database{}
|
|
logger := zap.NewNop()
|
|
|
|
// Set environment variables for testing
|
|
os.Setenv("FRONTEND_URL", "http://localhost:5173")
|
|
os.Setenv("SMTP_HOST", "")
|
|
os.Setenv("SMTP_PORT", "587")
|
|
os.Setenv("FROM_EMAIL", "test@veza.com")
|
|
os.Setenv("FROM_NAME", "Veza Test")
|
|
|
|
return NewEmailService(testDB, logger)
|
|
}
|
|
|
|
func TestEmailService_NewEmailService(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
assert.NotNil(t, service)
|
|
assert.NotNil(t, service.logger)
|
|
assert.NotNil(t, service.db)
|
|
}
|
|
|
|
func TestEmailService_SendVerificationEmail_NoSMTP(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
// Without SMTP configured, should not error (just logs)
|
|
err := service.SendVerificationEmail("test@example.com", "test-token-123")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEmailService_SendVerificationEmail_WithFRONTEND_URL(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
os.Setenv("FRONTEND_URL", "https://app.veza.com")
|
|
err := service.SendVerificationEmail("test@example.com", "test-token-123")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEmailService_SendVerificationEmail_DefaultURL(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
os.Unsetenv("FRONTEND_URL")
|
|
err := service.SendVerificationEmail("test@example.com", "test-token-123")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEmailService_buildVerificationEmailHTML_Success(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
verifyURL := "https://app.veza.com/verify-email?token=test-token-123"
|
|
html := service.buildVerificationEmailHTML(verifyURL)
|
|
|
|
assert.Contains(t, html, "<!DOCTYPE html>")
|
|
assert.Contains(t, html, "<html>")
|
|
assert.Contains(t, html, "Verify your Veza account")
|
|
assert.Contains(t, html, "Verify Email Address")
|
|
assert.Contains(t, html, verifyURL)
|
|
assert.Contains(t, html, "This link will expire in 24 hours")
|
|
}
|
|
|
|
func TestEmailService_buildVerificationEmailHTML_TemplateFallback(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
verifyURL := "https://app.veza.com/verify-email?token=test-token-123"
|
|
html := service.buildVerificationEmailHTML(verifyURL)
|
|
|
|
// Should contain the URL even if template parsing fails
|
|
assert.Contains(t, html, verifyURL)
|
|
}
|
|
|
|
func TestEmailService_SendWelcomeEmail_NoSMTP(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
err := service.SendWelcomeEmail("test@example.com", "testuser")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEmailService_buildWelcomeEmailHTML_Success(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
username := "testuser"
|
|
html := service.buildWelcomeEmailHTML(username)
|
|
|
|
assert.Contains(t, html, "<!DOCTYPE html>")
|
|
assert.Contains(t, html, "<html>")
|
|
assert.Contains(t, html, "Welcome to Veza")
|
|
assert.Contains(t, html, username)
|
|
assert.Contains(t, html, "Get Started")
|
|
assert.Contains(t, html, "Uploading your first track")
|
|
assert.Contains(t, html, "Creating playlists")
|
|
assert.Contains(t, html, "Discovering new music")
|
|
}
|
|
|
|
func TestEmailService_buildWelcomeEmailHTML_WithFRONTEND_URL(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
os.Setenv("FRONTEND_URL", "https://app.veza.com")
|
|
username := "testuser"
|
|
html := service.buildWelcomeEmailHTML(username)
|
|
|
|
assert.Contains(t, html, "https://app.veza.com")
|
|
}
|
|
|
|
func TestEmailService_buildWelcomeEmailHTML_DefaultURL(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
os.Unsetenv("FRONTEND_URL")
|
|
username := "testuser"
|
|
html := service.buildWelcomeEmailHTML(username)
|
|
|
|
assert.Contains(t, html, "http://localhost:5173")
|
|
}
|
|
|
|
func TestEmailService_SendNotificationEmail_NoSMTP(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
err := service.SendNotificationEmail("test@example.com", "Test Subject", "Test message", "track_like")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEmailService_buildNotificationEmailHTML_TrackLike(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
message := "Someone liked your track"
|
|
html := service.buildNotificationEmailHTML(message, "track_like")
|
|
|
|
assert.Contains(t, html, "<!DOCTYPE html>")
|
|
assert.Contains(t, html, "<html>")
|
|
assert.Contains(t, html, message)
|
|
assert.Contains(t, html, "❤️")
|
|
assert.Contains(t, html, "View on Veza")
|
|
}
|
|
|
|
func TestEmailService_buildNotificationEmailHTML_NewFollower(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
message := "You have a new follower"
|
|
html := service.buildNotificationEmailHTML(message, "new_follower")
|
|
|
|
assert.Contains(t, html, message)
|
|
assert.Contains(t, html, "👤")
|
|
}
|
|
|
|
func TestEmailService_buildNotificationEmailHTML_PlaylistUpdate(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
message := "A playlist was updated"
|
|
html := service.buildNotificationEmailHTML(message, "playlist_update")
|
|
|
|
assert.Contains(t, html, message)
|
|
assert.Contains(t, html, "🎵")
|
|
}
|
|
|
|
func TestEmailService_buildNotificationEmailHTML_CommentReply(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
message := "Someone replied to your comment"
|
|
html := service.buildNotificationEmailHTML(message, "comment_reply")
|
|
|
|
assert.Contains(t, html, message)
|
|
assert.Contains(t, html, "💬")
|
|
}
|
|
|
|
func TestEmailService_buildNotificationEmailHTML_Default(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
message := "You have a notification"
|
|
html := service.buildNotificationEmailHTML(message, "unknown_type")
|
|
|
|
assert.Contains(t, html, message)
|
|
assert.Contains(t, html, "🔔")
|
|
}
|
|
|
|
func TestEmailService_buildNotificationEmailHTML_WithFRONTEND_URL(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
os.Setenv("FRONTEND_URL", "https://app.veza.com")
|
|
message := "Test notification"
|
|
html := service.buildNotificationEmailHTML(message, "track_like")
|
|
|
|
assert.Contains(t, html, "https://app.veza.com")
|
|
}
|
|
|
|
func TestEmailService_buildNotificationEmailHTML_DefaultURL(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
os.Unsetenv("FRONTEND_URL")
|
|
message := "Test notification"
|
|
html := service.buildNotificationEmailHTML(message, "track_like")
|
|
|
|
assert.Contains(t, html, "http://localhost:5173")
|
|
}
|
|
|
|
func TestEmailService_sendEmail_NoSMTP(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
// Without SMTP configured, should not error (just logs)
|
|
err := service.sendEmail("test@example.com", "Test Subject", "Test Body")
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
func TestEmailService_generateVerificationToken(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
token1, err1 := service.generateVerificationToken()
|
|
assert.NoError(t, err1)
|
|
assert.NotEmpty(t, token1)
|
|
|
|
token2, err2 := service.generateVerificationToken()
|
|
assert.NoError(t, err2)
|
|
assert.NotEmpty(t, token2)
|
|
|
|
// Tokens should be different
|
|
assert.NotEqual(t, token1, token2)
|
|
}
|
|
|
|
func TestEmailService_generateVerificationToken_Length(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
token, err := service.generateVerificationToken()
|
|
assert.NoError(t, err)
|
|
assert.Greater(t, len(token), 20) // Base64 encoded 32 bytes should be ~44 chars
|
|
}
|
|
|
|
func TestEmailService_SendVerificationEmailWithUserID_NoSMTP(t *testing.T) {
|
|
// INT-04: Skip - requires real DB to store verification tokens; covered by integration tests.
|
|
t.Skip("requires real database connection for token storage")
|
|
}
|
|
|
|
func TestEmailService_buildVerificationEmailHTML_ContainsToken(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
testToken := "test-verification-token-12345"
|
|
verifyURL := "https://app.veza.com/verify-email?token=" + testToken
|
|
html := service.buildVerificationEmailHTML(verifyURL)
|
|
|
|
assert.Contains(t, html, testToken)
|
|
assert.Contains(t, html, "verify-email?token="+testToken)
|
|
}
|
|
|
|
func TestEmailService_buildVerificationEmailHTML_URLAppearsTwice(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
verifyURL := "https://app.veza.com/verify-email?token=test-token"
|
|
html := service.buildVerificationEmailHTML(verifyURL)
|
|
|
|
// URL should appear at least twice (button and text)
|
|
urlCount := strings.Count(html, verifyURL)
|
|
assert.GreaterOrEqual(t, urlCount, 2, "Verify URL should appear at least twice (button and text)")
|
|
}
|
|
|
|
func TestEmailService_buildWelcomeEmailHTML_ContainsUsername(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
username := "testuser123"
|
|
html := service.buildWelcomeEmailHTML(username)
|
|
|
|
assert.Contains(t, html, username)
|
|
}
|
|
|
|
func TestEmailService_buildNotificationEmailHTML_ContainsMessage(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
message := "Custom notification message"
|
|
html := service.buildNotificationEmailHTML(message, "track_like")
|
|
|
|
assert.Contains(t, html, message)
|
|
}
|
|
|
|
func TestEmailService_buildNotificationEmailHTML_NotificationPreferences(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
message := "Test notification"
|
|
html := service.buildNotificationEmailHTML(message, "track_like")
|
|
|
|
assert.Contains(t, html, "notification preferences")
|
|
assert.Contains(t, html, "account settings")
|
|
}
|
|
|
|
func TestEmailService_EmailService_Fields(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
assert.NotNil(t, service.db)
|
|
assert.NotNil(t, service.logger)
|
|
// SMTP fields may be empty if not configured
|
|
}
|
|
|
|
func TestEmailService_buildVerificationEmailHTML_ExpirationMessage(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
verifyURL := "https://app.veza.com/verify-email?token=test"
|
|
html := service.buildVerificationEmailHTML(verifyURL)
|
|
|
|
assert.Contains(t, html, "24 hours")
|
|
}
|
|
|
|
func TestEmailService_buildPasswordResetEmail_ExpirationMessage(t *testing.T) {
|
|
service := setupTestEmailService(t)
|
|
|
|
resetURL := "https://app.veza.com/reset-password?token=test"
|
|
html := service.buildPasswordResetEmail(resetURL)
|
|
|
|
assert.Contains(t, html, "1 hour")
|
|
}
|