243 lines
6.2 KiB
Go
243 lines
6.2 KiB
Go
package accountapiimp
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/tech/sendico/pkg/model"
|
|
"github.com/tech/sendico/server/interface/api/srequest"
|
|
)
|
|
|
|
// Helper function to create string pointers
|
|
func stringPtr(s string) *string {
|
|
return &s
|
|
}
|
|
|
|
// TestTimezoneValidation tests timezone validation logic separately
|
|
func TestTimezoneValidation(t *testing.T) {
|
|
t.Run("ValidTimezones", func(t *testing.T) {
|
|
validTimezones := []string{
|
|
"UTC",
|
|
"America/New_York",
|
|
"Europe/London",
|
|
"Asia/Tokyo",
|
|
"Australia/Sydney",
|
|
}
|
|
|
|
for _, tz := range validTimezones {
|
|
t.Run(tz, func(t *testing.T) {
|
|
_, err := time.LoadLocation(tz)
|
|
assert.NoError(t, err, "Timezone %s should be valid", tz)
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("InvalidTimezones", func(t *testing.T) {
|
|
invalidTimezones := []string{
|
|
"Invalid/Timezone",
|
|
"Not/A/Timezone",
|
|
"BadTimezone",
|
|
"America/NotACity",
|
|
}
|
|
|
|
for _, tz := range invalidTimezones {
|
|
t.Run(tz, func(t *testing.T) {
|
|
_, err := time.LoadLocation(tz)
|
|
assert.Error(t, err, "Timezone %s should be invalid", tz)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// TestCreateValidSignupRequest tests the helper function for creating valid requests
|
|
func TestCreateValidSignupRequest(t *testing.T) {
|
|
request := srequest.Signup{
|
|
Account: model.AccountData{
|
|
LoginData: model.LoginData{
|
|
UserDataBase: model.UserDataBase{
|
|
Login: "test@example.com",
|
|
},
|
|
Password: "TestPassword123!",
|
|
},
|
|
Name: "Test User",
|
|
},
|
|
OrganizationName: "Test Organization",
|
|
OrganizationTimeZone: "UTC",
|
|
AnonymousUser: model.Describable{
|
|
Name: "Anonymous User",
|
|
},
|
|
OwnerRole: model.Describable{
|
|
Name: "Owner",
|
|
},
|
|
AnonymousRole: model.Describable{
|
|
Name: "Anonymous",
|
|
},
|
|
}
|
|
|
|
// Validate the request structure
|
|
assert.Equal(t, "test@example.com", request.Account.Login)
|
|
assert.Equal(t, "TestPassword123!", request.Account.Password)
|
|
assert.Equal(t, "Test User", request.Account.Name)
|
|
assert.Equal(t, "Test Organization", request.OrganizationName)
|
|
assert.Equal(t, "UTC", request.OrganizationTimeZone)
|
|
}
|
|
|
|
// TestSignupRequestValidation tests various signup request validation scenarios
|
|
func TestSignupRequestValidation(t *testing.T) {
|
|
t.Run("ValidRequest", func(t *testing.T) {
|
|
request := srequest.Signup{
|
|
Account: model.AccountData{
|
|
LoginData: model.LoginData{
|
|
UserDataBase: model.UserDataBase{
|
|
Login: "test@example.com",
|
|
},
|
|
Password: "TestPassword123!",
|
|
},
|
|
Name: "Test User",
|
|
},
|
|
OrganizationName: "Test Organization",
|
|
OrganizationTimeZone: "UTC",
|
|
}
|
|
|
|
// Basic validation - all required fields present
|
|
assert.NotEmpty(t, request.Account.Login)
|
|
assert.NotEmpty(t, request.Account.Password)
|
|
assert.NotEmpty(t, request.Account.Name)
|
|
assert.NotEmpty(t, request.OrganizationName)
|
|
assert.NotEmpty(t, request.OrganizationTimeZone)
|
|
})
|
|
|
|
t.Run("EmailFormats", func(t *testing.T) {
|
|
validEmails := []string{
|
|
"test@example.com",
|
|
"user.name@example.com",
|
|
"user+tag@example.org",
|
|
"test123@domain.co.uk",
|
|
}
|
|
|
|
for _, email := range validEmails {
|
|
t.Run(email, func(t *testing.T) {
|
|
request := srequest.Signup{
|
|
Account: model.AccountData{
|
|
LoginData: model.LoginData{
|
|
UserDataBase: model.UserDataBase{
|
|
Login: email,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
assert.Equal(t, email, request.Account.Login)
|
|
assert.Contains(t, email, "@")
|
|
assert.Contains(t, email, ".")
|
|
})
|
|
}
|
|
})
|
|
|
|
t.Run("PasswordComplexity", func(t *testing.T) {
|
|
passwordTests := []struct {
|
|
name string
|
|
password string
|
|
valid bool
|
|
}{
|
|
{"Strong", "TestPassword123!", true},
|
|
{"WithNumbers", "MyPass123!", true},
|
|
{"WithSymbols", "Complex@Pass1", true},
|
|
{"TooShort", "Test1!", false},
|
|
{"NoNumbers", "TestPassword!", false},
|
|
{"NoSymbols", "TestPassword123", false},
|
|
{"NoUppercase", "testpassword123!", false},
|
|
{"NoLowercase", "TESTPASSWORD123!", false},
|
|
}
|
|
|
|
for _, tt := range passwordTests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
request := srequest.Signup{
|
|
Account: model.AccountData{
|
|
LoginData: model.LoginData{
|
|
Password: tt.password,
|
|
},
|
|
},
|
|
}
|
|
|
|
// Basic structure validation
|
|
assert.Equal(t, tt.password, request.Account.Password)
|
|
|
|
if tt.valid {
|
|
assert.True(t, len(tt.password) >= 8, "Password should be at least 8 characters")
|
|
} else {
|
|
// For invalid passwords, at least one condition should fail
|
|
hasDigit := false
|
|
hasUpper := false
|
|
hasLower := false
|
|
hasSpecial := false
|
|
|
|
for _, char := range tt.password {
|
|
switch {
|
|
case char >= '0' && char <= '9':
|
|
hasDigit = true
|
|
case char >= 'A' && char <= 'Z':
|
|
hasUpper = true
|
|
case char >= 'a' && char <= 'z':
|
|
hasLower = true
|
|
case char >= '!' && char <= '/' || char >= ':' && char <= '@':
|
|
hasSpecial = true
|
|
}
|
|
}
|
|
|
|
// At least one requirement should fail for invalid passwords
|
|
if len(tt.password) >= 8 {
|
|
assert.False(t, hasDigit && hasUpper && hasLower && hasSpecial,
|
|
"Password %s should fail at least one requirement", tt.password)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// TestAccountDataToAccount tests the ToAccount method
|
|
func TestAccountDataToAccount(t *testing.T) {
|
|
accountData := model.AccountData{
|
|
LoginData: model.LoginData{
|
|
UserDataBase: model.UserDataBase{
|
|
Login: "test@example.com",
|
|
},
|
|
Password: "TestPassword123!",
|
|
},
|
|
Name: "Test User",
|
|
}
|
|
|
|
account := accountData.ToAccount()
|
|
|
|
assert.Equal(t, accountData.Login, account.Login)
|
|
assert.Equal(t, accountData.Password, account.Password)
|
|
assert.Equal(t, accountData.Name, account.Name)
|
|
|
|
// Verify the account has proper structure
|
|
assert.NotNil(t, account)
|
|
assert.IsType(t, &model.Account{}, account)
|
|
}
|
|
|
|
// TestColorValidation tests that colors are properly formatted
|
|
func TestColorValidation(t *testing.T) {
|
|
validColors := []string{
|
|
"#FF0000", // Red
|
|
"#00FF00", // Green
|
|
"#0000FF", // Blue
|
|
"#FFFFFF", // White
|
|
"#000000", // Black
|
|
"#FF8000", // Orange
|
|
}
|
|
|
|
for _, color := range validColors {
|
|
t.Run(color, func(t *testing.T) {
|
|
colorPtr := stringPtr(color)
|
|
assert.NotNil(t, colorPtr)
|
|
assert.Equal(t, color, *colorPtr)
|
|
assert.True(t, len(color) == 7, "Color should be 7 characters long")
|
|
assert.True(t, color[0] == '#', "Color should start with #")
|
|
})
|
|
}
|
|
}
|