Coverage priorities 1-5: test pure functions, extract interfaces, mock-based handler tests
- Priority 1: Test NewSendEmailTask + NewSendPushTask (5 tests) - Priority 2: Test customHTTPErrorHandler — all 15+ branches (21 tests) - Priority 3: Extract Enqueuer interface + payload builders in worker pkg (5 tests) - Priority 4: Extract ClassifyFile/ComputeRelPath in migrate-encrypt (6 tests) - Priority 5: Define Handler interfaces, refactor to accept them, mock-based tests (14 tests) - Fix .gitignore: /worker instead of worker to stop ignoring internal/worker/ Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
626
internal/models/models_coverage_test.go
Normal file
626
internal/models/models_coverage_test.go
Normal file
@@ -0,0 +1,626 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
// setupModelsTestDB creates a minimal in-memory SQLite for model-level tests
|
||||
// that require database interaction (e.g., BeforeCreate hooks).
|
||||
func setupModelsTestDB(t *testing.T) *gorm.DB {
|
||||
t.Helper()
|
||||
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{
|
||||
Logger: logger.Default.LogMode(logger.Silent),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
err = db.AutoMigrate(&User{}, &AuthToken{}, &UserProfile{})
|
||||
require.NoError(t, err)
|
||||
return db
|
||||
}
|
||||
|
||||
// === Residence model tests ===
|
||||
|
||||
func TestResidence_GetAllUsers(t *testing.T) {
|
||||
owner := User{Username: "owner"}
|
||||
owner.ID = 1
|
||||
member1 := User{Username: "member1"}
|
||||
member1.ID = 2
|
||||
member2 := User{Username: "member2"}
|
||||
member2.ID = 3
|
||||
|
||||
residence := &Residence{
|
||||
OwnerID: owner.ID,
|
||||
Owner: owner,
|
||||
Users: []User{member1, member2},
|
||||
}
|
||||
|
||||
allUsers := residence.GetAllUsers()
|
||||
assert.Len(t, allUsers, 3)
|
||||
assert.Equal(t, "owner", allUsers[0].Username)
|
||||
}
|
||||
|
||||
func TestResidence_HasAccess(t *testing.T) {
|
||||
owner := User{Username: "owner"}
|
||||
owner.ID = 1
|
||||
member := User{Username: "member"}
|
||||
member.ID = 2
|
||||
|
||||
residence := &Residence{
|
||||
OwnerID: owner.ID,
|
||||
Owner: owner,
|
||||
Users: []User{member},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
userID uint
|
||||
expected bool
|
||||
}{
|
||||
{"owner has access", 1, true},
|
||||
{"member has access", 2, true},
|
||||
{"stranger no access", 99, false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, residence.HasAccess(tt.userID))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResidence_IsPrimaryOwner(t *testing.T) {
|
||||
residence := &Residence{OwnerID: 1}
|
||||
|
||||
assert.True(t, residence.IsPrimaryOwner(1))
|
||||
assert.False(t, residence.IsPrimaryOwner(2))
|
||||
}
|
||||
|
||||
// === Document model tests ===
|
||||
|
||||
func TestDocument_TableName_DocumentImage(t *testing.T) {
|
||||
di := DocumentImage{}
|
||||
assert.Equal(t, "task_documentimage", di.TableName())
|
||||
}
|
||||
|
||||
func TestDocument_IsWarrantyExpiringSoon(t *testing.T) {
|
||||
future30 := time.Now().UTC().AddDate(0, 0, 15)
|
||||
future90 := time.Now().UTC().AddDate(0, 0, 60)
|
||||
past := time.Now().UTC().AddDate(0, 0, -5)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
doc Document
|
||||
days int
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "warranty expiring within threshold",
|
||||
doc: Document{DocumentType: DocumentTypeWarranty, ExpiryDate: &future30},
|
||||
days: 30,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "warranty not expiring within threshold",
|
||||
doc: Document{DocumentType: DocumentTypeWarranty, ExpiryDate: &future90},
|
||||
days: 30,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "warranty already expired",
|
||||
doc: Document{DocumentType: DocumentTypeWarranty, ExpiryDate: &past},
|
||||
days: 30,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "non-warranty document",
|
||||
doc: Document{DocumentType: DocumentTypeGeneral, ExpiryDate: &future30},
|
||||
days: 30,
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "warranty with nil expiry",
|
||||
doc: Document{DocumentType: DocumentTypeWarranty, ExpiryDate: nil},
|
||||
days: 30,
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, tt.doc.IsWarrantyExpiringSoon(tt.days))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocument_IsWarrantyExpired(t *testing.T) {
|
||||
past := time.Now().UTC().AddDate(0, 0, -5)
|
||||
future := time.Now().UTC().AddDate(0, 0, 30)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
doc Document
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "expired warranty",
|
||||
doc: Document{DocumentType: DocumentTypeWarranty, ExpiryDate: &past},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "active warranty",
|
||||
doc: Document{DocumentType: DocumentTypeWarranty, ExpiryDate: &future},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "non-warranty",
|
||||
doc: Document{DocumentType: DocumentTypeGeneral, ExpiryDate: &past},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "warranty nil expiry",
|
||||
doc: Document{DocumentType: DocumentTypeWarranty, ExpiryDate: nil},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, tt.doc.IsWarrantyExpired())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocumentType_Constants(t *testing.T) {
|
||||
// Verify document type constants have expected values
|
||||
assert.Equal(t, DocumentType("general"), DocumentTypeGeneral)
|
||||
assert.Equal(t, DocumentType("warranty"), DocumentTypeWarranty)
|
||||
assert.Equal(t, DocumentType("receipt"), DocumentTypeReceipt)
|
||||
assert.Equal(t, DocumentType("contract"), DocumentTypeContract)
|
||||
assert.Equal(t, DocumentType("insurance"), DocumentTypeInsurance)
|
||||
assert.Equal(t, DocumentType("manual"), DocumentTypeManual)
|
||||
}
|
||||
|
||||
// === Notification model tests ===
|
||||
|
||||
func TestNotification_TableName(t *testing.T) {
|
||||
n := Notification{}
|
||||
assert.Equal(t, "notifications_notification", n.TableName())
|
||||
}
|
||||
|
||||
func TestNotificationPreference_TableName(t *testing.T) {
|
||||
np := NotificationPreference{}
|
||||
assert.Equal(t, "notifications_notificationpreference", np.TableName())
|
||||
}
|
||||
|
||||
func TestAPNSDevice_TableName(t *testing.T) {
|
||||
d := APNSDevice{}
|
||||
assert.Equal(t, "push_notifications_apnsdevice", d.TableName())
|
||||
}
|
||||
|
||||
func TestGCMDevice_TableName(t *testing.T) {
|
||||
d := GCMDevice{}
|
||||
assert.Equal(t, "push_notifications_gcmdevice", d.TableName())
|
||||
}
|
||||
|
||||
func TestNotification_MarkAsRead(t *testing.T) {
|
||||
n := &Notification{Read: false}
|
||||
|
||||
n.MarkAsRead()
|
||||
assert.True(t, n.Read)
|
||||
assert.NotNil(t, n.ReadAt)
|
||||
}
|
||||
|
||||
func TestNotification_MarkAsSent(t *testing.T) {
|
||||
n := &Notification{Sent: false}
|
||||
|
||||
n.MarkAsSent()
|
||||
assert.True(t, n.Sent)
|
||||
assert.NotNil(t, n.SentAt)
|
||||
}
|
||||
|
||||
func TestNotificationType_Constants(t *testing.T) {
|
||||
assert.Equal(t, NotificationType("task_due_soon"), NotificationTaskDueSoon)
|
||||
assert.Equal(t, NotificationType("task_overdue"), NotificationTaskOverdue)
|
||||
assert.Equal(t, NotificationType("task_completed"), NotificationTaskCompleted)
|
||||
assert.Equal(t, NotificationType("task_assigned"), NotificationTaskAssigned)
|
||||
assert.Equal(t, NotificationType("residence_shared"), NotificationResidenceShared)
|
||||
assert.Equal(t, NotificationType("warranty_expiring"), NotificationWarrantyExpiring)
|
||||
}
|
||||
|
||||
// === AuthToken model tests ===
|
||||
|
||||
func TestAuthToken_BeforeCreate_GeneratesKey(t *testing.T) {
|
||||
db := setupModelsTestDB(t)
|
||||
|
||||
user := &User{
|
||||
Username: "tokenuser",
|
||||
Email: "token@test.com",
|
||||
Password: "dummy",
|
||||
IsActive: true,
|
||||
}
|
||||
err := db.Create(user).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
token := &AuthToken{UserID: user.ID}
|
||||
err = db.Create(token).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NotEmpty(t, token.Key)
|
||||
assert.Len(t, token.Key, 40) // 20 bytes = 40 hex chars
|
||||
assert.False(t, token.Created.IsZero())
|
||||
}
|
||||
|
||||
func TestAuthToken_BeforeCreate_PreservesExistingKey(t *testing.T) {
|
||||
db := setupModelsTestDB(t)
|
||||
|
||||
user := &User{
|
||||
Username: "tokenuser",
|
||||
Email: "token@test.com",
|
||||
Password: "dummy",
|
||||
IsActive: true,
|
||||
}
|
||||
err := db.Create(user).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
existingKey := "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
|
||||
token := &AuthToken{
|
||||
Key: existingKey,
|
||||
UserID: user.ID,
|
||||
}
|
||||
err = db.Create(token).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, existingKey, token.Key)
|
||||
}
|
||||
|
||||
func TestGetOrCreateToken_CreatesNew(t *testing.T) {
|
||||
db := setupModelsTestDB(t)
|
||||
|
||||
user := &User{
|
||||
Username: "newtoken",
|
||||
Email: "newtoken@test.com",
|
||||
Password: "dummy",
|
||||
IsActive: true,
|
||||
}
|
||||
err := db.Create(user).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
token, err := GetOrCreateToken(db, user.ID)
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, token.Key)
|
||||
assert.Equal(t, user.ID, token.UserID)
|
||||
}
|
||||
|
||||
func TestGetOrCreateToken_ReturnsExisting(t *testing.T) {
|
||||
db := setupModelsTestDB(t)
|
||||
|
||||
user := &User{
|
||||
Username: "existingtoken",
|
||||
Email: "existingtoken@test.com",
|
||||
Password: "dummy",
|
||||
IsActive: true,
|
||||
}
|
||||
err := db.Create(user).Error
|
||||
require.NoError(t, err)
|
||||
|
||||
token1, err := GetOrCreateToken(db, user.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
token2, err := GetOrCreateToken(db, user.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, token1.Key, token2.Key)
|
||||
}
|
||||
|
||||
// === User model additional tests ===
|
||||
|
||||
func TestUser_SetPassword_And_CheckPassword_Integration(t *testing.T) {
|
||||
user := &User{}
|
||||
err := user.SetPassword("Password123")
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.True(t, user.CheckPassword("Password123"))
|
||||
assert.False(t, user.CheckPassword("WrongPassword"))
|
||||
assert.False(t, user.CheckPassword(""))
|
||||
assert.False(t, user.CheckPassword("password123")) // case sensitive
|
||||
}
|
||||
|
||||
// === Task model additional tests ===
|
||||
|
||||
func TestTask_IsOverdue_CancelledNotOverdue(t *testing.T) {
|
||||
yesterday := time.Now().UTC().AddDate(0, 0, -2)
|
||||
task := &Task{
|
||||
DueDate: &yesterday,
|
||||
IsCancelled: true,
|
||||
}
|
||||
assert.False(t, task.IsOverdue())
|
||||
}
|
||||
|
||||
func TestTask_IsOverdue_ArchivedNotOverdue(t *testing.T) {
|
||||
yesterday := time.Now().UTC().AddDate(0, 0, -2)
|
||||
task := &Task{
|
||||
DueDate: &yesterday,
|
||||
IsArchived: true,
|
||||
}
|
||||
assert.False(t, task.IsOverdue())
|
||||
}
|
||||
|
||||
func TestTask_IsOverdue_NoDueDateNotOverdue(t *testing.T) {
|
||||
task := &Task{
|
||||
DueDate: nil,
|
||||
}
|
||||
assert.False(t, task.IsOverdue())
|
||||
}
|
||||
|
||||
func TestTask_IsOverdue_CompletedNotOverdue(t *testing.T) {
|
||||
yesterday := time.Now().UTC().AddDate(0, 0, -2)
|
||||
task := &Task{
|
||||
DueDate: &yesterday,
|
||||
NextDueDate: nil,
|
||||
Completions: []TaskCompletion{{CompletedAt: time.Now().UTC()}},
|
||||
}
|
||||
assert.False(t, task.IsOverdue())
|
||||
}
|
||||
|
||||
func TestTask_IsOverdue_CompletionCountNotOverdue(t *testing.T) {
|
||||
yesterday := time.Now().UTC().AddDate(0, 0, -2)
|
||||
task := &Task{
|
||||
DueDate: &yesterday,
|
||||
NextDueDate: nil,
|
||||
CompletionCount: 1,
|
||||
}
|
||||
assert.False(t, task.IsOverdue())
|
||||
}
|
||||
|
||||
func TestTask_IsOverdue_UsesNextDueDate(t *testing.T) {
|
||||
// DueDate is overdue, but NextDueDate is in the future
|
||||
pastDue := time.Now().UTC().AddDate(0, 0, -10)
|
||||
futureDue := time.Now().UTC().AddDate(0, 0, 10)
|
||||
task := &Task{
|
||||
DueDate: &pastDue,
|
||||
NextDueDate: &futureDue,
|
||||
}
|
||||
assert.False(t, task.IsOverdue())
|
||||
}
|
||||
|
||||
func TestTask_IsDueSoon_CancelledNotDueSoon(t *testing.T) {
|
||||
futureDue := time.Now().UTC().AddDate(0, 0, 5)
|
||||
task := &Task{
|
||||
DueDate: &futureDue,
|
||||
IsCancelled: true,
|
||||
}
|
||||
assert.False(t, task.IsDueSoon(30))
|
||||
}
|
||||
|
||||
func TestTask_IsDueSoon_NoDueDateNotDueSoon(t *testing.T) {
|
||||
task := &Task{
|
||||
DueDate: nil,
|
||||
}
|
||||
assert.False(t, task.IsDueSoon(30))
|
||||
}
|
||||
|
||||
func TestTask_IsDueSoon_WithinThreshold(t *testing.T) {
|
||||
futureDue := time.Now().UTC().AddDate(0, 0, 5)
|
||||
task := &Task{
|
||||
DueDate: &futureDue,
|
||||
}
|
||||
assert.True(t, task.IsDueSoon(30))
|
||||
assert.True(t, task.IsDueSoon(10))
|
||||
assert.False(t, task.IsDueSoon(3))
|
||||
}
|
||||
|
||||
func TestTask_IsDueSoon_CompletedNotDueSoon(t *testing.T) {
|
||||
futureDue := time.Now().UTC().AddDate(0, 0, 5)
|
||||
task := &Task{
|
||||
DueDate: &futureDue,
|
||||
NextDueDate: nil,
|
||||
Completions: []TaskCompletion{{CompletedAt: time.Now().UTC()}},
|
||||
}
|
||||
assert.False(t, task.IsDueSoon(30))
|
||||
}
|
||||
|
||||
func TestTaskCompletionImage_TableName(t *testing.T) {
|
||||
tci := TaskCompletionImage{}
|
||||
assert.Equal(t, "task_taskcompletionimage", tci.TableName())
|
||||
}
|
||||
|
||||
// === Subscription model additional tests ===
|
||||
|
||||
func TestSubscription_TableNames(t *testing.T) {
|
||||
assert.Equal(t, "subscription_subscriptionsettings", SubscriptionSettings{}.TableName())
|
||||
assert.Equal(t, "subscription_usersubscription", UserSubscription{}.TableName())
|
||||
assert.Equal(t, "subscription_upgradetrigger", UpgradeTrigger{}.TableName())
|
||||
assert.Equal(t, "subscription_featurebenefit", FeatureBenefit{}.TableName())
|
||||
assert.Equal(t, "subscription_promotion", Promotion{}.TableName())
|
||||
assert.Equal(t, "subscription_tierlimits", TierLimits{}.TableName())
|
||||
}
|
||||
|
||||
func TestSubscription_IsActive(t *testing.T) {
|
||||
future := time.Now().UTC().Add(24 * time.Hour)
|
||||
past := time.Now().UTC().Add(-24 * time.Hour)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
sub *UserSubscription
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "pro with future expiry is active",
|
||||
sub: &UserSubscription{Tier: TierPro, ExpiresAt: &future},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "pro with nil expiry is active",
|
||||
sub: &UserSubscription{Tier: TierPro, ExpiresAt: nil},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "pro with past expiry is not active",
|
||||
sub: &UserSubscription{Tier: TierPro, ExpiresAt: &past},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "free with active trial is active",
|
||||
sub: &UserSubscription{Tier: TierFree, TrialEnd: &future},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "free without trial is not active",
|
||||
sub: &UserSubscription{Tier: TierFree},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, tt.sub.IsActive())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubscription_SubscriptionSource(t *testing.T) {
|
||||
sub := &UserSubscription{Platform: "ios"}
|
||||
assert.Equal(t, "ios", sub.SubscriptionSource())
|
||||
}
|
||||
|
||||
func TestPromotion_IsCurrentlyActive(t *testing.T) {
|
||||
now := time.Now().UTC()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
promo Promotion
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "active promotion within dates",
|
||||
promo: Promotion{
|
||||
IsActive: true,
|
||||
StartDate: now.Add(-1 * time.Hour),
|
||||
EndDate: now.Add(1 * time.Hour),
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "inactive promotion",
|
||||
promo: Promotion{
|
||||
IsActive: false,
|
||||
StartDate: now.Add(-1 * time.Hour),
|
||||
EndDate: now.Add(1 * time.Hour),
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "promotion not yet started",
|
||||
promo: Promotion{
|
||||
IsActive: true,
|
||||
StartDate: now.Add(1 * time.Hour),
|
||||
EndDate: now.Add(2 * time.Hour),
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "promotion already ended",
|
||||
promo: Promotion{
|
||||
IsActive: true,
|
||||
StartDate: now.Add(-2 * time.Hour),
|
||||
EndDate: now.Add(-1 * time.Hour),
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, tt.promo.IsCurrentlyActive())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDefaultFreeLimits(t *testing.T) {
|
||||
limits := GetDefaultFreeLimits()
|
||||
assert.Equal(t, TierFree, limits.Tier)
|
||||
require.NotNil(t, limits.PropertiesLimit)
|
||||
require.NotNil(t, limits.TasksLimit)
|
||||
require.NotNil(t, limits.ContractorsLimit)
|
||||
require.NotNil(t, limits.DocumentsLimit)
|
||||
assert.Equal(t, 1, *limits.PropertiesLimit)
|
||||
assert.Equal(t, 10, *limits.TasksLimit)
|
||||
assert.Equal(t, 0, *limits.ContractorsLimit)
|
||||
assert.Equal(t, 0, *limits.DocumentsLimit)
|
||||
}
|
||||
|
||||
func TestGetDefaultProLimits(t *testing.T) {
|
||||
limits := GetDefaultProLimits()
|
||||
assert.Equal(t, TierPro, limits.Tier)
|
||||
assert.Nil(t, limits.PropertiesLimit)
|
||||
assert.Nil(t, limits.TasksLimit)
|
||||
assert.Nil(t, limits.ContractorsLimit)
|
||||
assert.Nil(t, limits.DocumentsLimit)
|
||||
}
|
||||
|
||||
// === ConfirmationCode additional tests ===
|
||||
|
||||
func TestConfirmationCode_TableName(t *testing.T) {
|
||||
cc := ConfirmationCode{}
|
||||
assert.Equal(t, "user_confirmationcode", cc.TableName())
|
||||
}
|
||||
|
||||
// === PasswordResetCode additional tests ===
|
||||
|
||||
func TestPasswordResetCode_TableName(t *testing.T) {
|
||||
prc := PasswordResetCode{}
|
||||
assert.Equal(t, "user_passwordresetcode", prc.TableName())
|
||||
}
|
||||
|
||||
// === Social Auth TableName tests ===
|
||||
|
||||
func TestAppleSocialAuth_TableName(t *testing.T) {
|
||||
a := AppleSocialAuth{}
|
||||
assert.Equal(t, "user_applesocialauth", a.TableName())
|
||||
}
|
||||
|
||||
func TestGoogleSocialAuth_TableName(t *testing.T) {
|
||||
g := GoogleSocialAuth{}
|
||||
assert.Equal(t, "user_googlesocialauth", g.TableName())
|
||||
}
|
||||
|
||||
// === BaseModel tests ===
|
||||
|
||||
func TestBaseModel_BeforeCreate(t *testing.T) {
|
||||
b := &BaseModel{}
|
||||
err := b.BeforeCreate(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.False(t, b.CreatedAt.IsZero())
|
||||
assert.False(t, b.UpdatedAt.IsZero())
|
||||
}
|
||||
|
||||
func TestBaseModel_BeforeCreate_PreservesExisting(t *testing.T) {
|
||||
existingTime := time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
b := &BaseModel{
|
||||
CreatedAt: existingTime,
|
||||
UpdatedAt: existingTime,
|
||||
}
|
||||
err := b.BeforeCreate(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, existingTime, b.CreatedAt)
|
||||
assert.Equal(t, existingTime, b.UpdatedAt)
|
||||
}
|
||||
|
||||
func TestBaseModel_BeforeUpdate(t *testing.T) {
|
||||
oldTime := time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
b := &BaseModel{
|
||||
UpdatedAt: oldTime,
|
||||
}
|
||||
err := b.BeforeUpdate(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.True(t, b.UpdatedAt.After(oldTime))
|
||||
}
|
||||
@@ -11,10 +11,10 @@ import (
|
||||
func TestUser_SetPassword(t *testing.T) {
|
||||
user := &User{}
|
||||
|
||||
err := user.SetPassword("testpassword123")
|
||||
err := user.SetPassword("testPassword123")
|
||||
require.NoError(t, err)
|
||||
assert.NotEmpty(t, user.Password)
|
||||
assert.NotEqual(t, "testpassword123", user.Password) // Should be hashed
|
||||
assert.NotEqual(t, "testPassword123", user.Password) // Should be hashed
|
||||
}
|
||||
|
||||
func TestUser_CheckPassword(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user