- 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>
187 lines
4.4 KiB
Go
187 lines
4.4 KiB
Go
package middleware
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/treytartt/honeydue-api/internal/models"
|
|
)
|
|
|
|
func TestUserCache_SetAndGet(t *testing.T) {
|
|
cache := NewUserCache(1 * time.Minute)
|
|
|
|
user := &models.User{Username: "testuser", Email: "test@test.com"}
|
|
user.ID = 1
|
|
|
|
cache.Set(user)
|
|
|
|
cached := cache.Get(1)
|
|
require.NotNil(t, cached)
|
|
assert.Equal(t, "testuser", cached.Username)
|
|
assert.Equal(t, "test@test.com", cached.Email)
|
|
}
|
|
|
|
func TestUserCache_GetNonExistent_ReturnsNil(t *testing.T) {
|
|
cache := NewUserCache(1 * time.Minute)
|
|
|
|
cached := cache.Get(999)
|
|
assert.Nil(t, cached)
|
|
}
|
|
|
|
func TestUserCache_Expired_ReturnsNil(t *testing.T) {
|
|
// Very short TTL
|
|
cache := NewUserCache(1 * time.Millisecond)
|
|
|
|
user := &models.User{Username: "expiring_user"}
|
|
user.ID = 1
|
|
|
|
cache.Set(user)
|
|
|
|
// Wait for expiry
|
|
time.Sleep(5 * time.Millisecond)
|
|
|
|
cached := cache.Get(1)
|
|
assert.Nil(t, cached, "expired entry should return nil")
|
|
}
|
|
|
|
func TestUserCache_Invalidate(t *testing.T) {
|
|
cache := NewUserCache(1 * time.Minute)
|
|
|
|
user := &models.User{Username: "to_invalidate"}
|
|
user.ID = 1
|
|
|
|
cache.Set(user)
|
|
|
|
// Verify it's cached
|
|
require.NotNil(t, cache.Get(1))
|
|
|
|
// Invalidate
|
|
cache.Invalidate(1)
|
|
|
|
// Should be gone
|
|
assert.Nil(t, cache.Get(1))
|
|
}
|
|
|
|
func TestUserCache_ReturnsCopy_NotOriginal(t *testing.T) {
|
|
cache := NewUserCache(1 * time.Minute)
|
|
|
|
user := &models.User{Username: "original"}
|
|
user.ID = 1
|
|
|
|
cache.Set(user)
|
|
|
|
// Modify the returned copy
|
|
cached := cache.Get(1)
|
|
require.NotNil(t, cached)
|
|
cached.Username = "modified"
|
|
|
|
// Original cache entry should be unaffected
|
|
cached2 := cache.Get(1)
|
|
require.NotNil(t, cached2)
|
|
assert.Equal(t, "original", cached2.Username, "cache should return a copy, not the original")
|
|
}
|
|
|
|
func TestUserCache_SetCopiesInput(t *testing.T) {
|
|
cache := NewUserCache(1 * time.Minute)
|
|
|
|
user := &models.User{Username: "original"}
|
|
user.ID = 1
|
|
|
|
cache.Set(user)
|
|
|
|
// Modify the input after setting
|
|
user.Username = "modified_after_set"
|
|
|
|
// Cache should still have the original value
|
|
cached := cache.Get(1)
|
|
require.NotNil(t, cached)
|
|
assert.Equal(t, "original", cached.Username, "cache should store a copy of the input")
|
|
}
|
|
|
|
func TestUserCache_MultipleUsers(t *testing.T) {
|
|
cache := NewUserCache(1 * time.Minute)
|
|
|
|
user1 := &models.User{Username: "user1"}
|
|
user1.ID = 1
|
|
user2 := &models.User{Username: "user2"}
|
|
user2.ID = 2
|
|
|
|
cache.Set(user1)
|
|
cache.Set(user2)
|
|
|
|
cached1 := cache.Get(1)
|
|
cached2 := cache.Get(2)
|
|
|
|
require.NotNil(t, cached1)
|
|
require.NotNil(t, cached2)
|
|
assert.Equal(t, "user1", cached1.Username)
|
|
assert.Equal(t, "user2", cached2.Username)
|
|
}
|
|
|
|
func TestUserCache_OverwriteEntry(t *testing.T) {
|
|
cache := NewUserCache(1 * time.Minute)
|
|
|
|
user := &models.User{Username: "original"}
|
|
user.ID = 1
|
|
|
|
cache.Set(user)
|
|
|
|
// Overwrite with new data
|
|
updated := &models.User{Username: "updated"}
|
|
updated.ID = 1
|
|
|
|
cache.Set(updated)
|
|
|
|
cached := cache.Get(1)
|
|
require.NotNil(t, cached)
|
|
assert.Equal(t, "updated", cached.Username)
|
|
}
|
|
|
|
func TestTimezoneCache_GetAndCompare_NewEntry(t *testing.T) {
|
|
tc := NewTimezoneCache()
|
|
|
|
// First call should return false (not cached yet)
|
|
unchanged := tc.GetAndCompare(1, "America/New_York")
|
|
assert.False(t, unchanged, "first call should indicate a change")
|
|
}
|
|
|
|
func TestTimezoneCache_GetAndCompare_SameValue(t *testing.T) {
|
|
tc := NewTimezoneCache()
|
|
|
|
// First call sets the value
|
|
tc.GetAndCompare(1, "America/New_York")
|
|
|
|
// Second call with same value should return true (unchanged)
|
|
unchanged := tc.GetAndCompare(1, "America/New_York")
|
|
assert.True(t, unchanged, "same value should indicate no change")
|
|
}
|
|
|
|
func TestTimezoneCache_GetAndCompare_DifferentValue(t *testing.T) {
|
|
tc := NewTimezoneCache()
|
|
|
|
// Set initial value
|
|
tc.GetAndCompare(1, "America/New_York")
|
|
|
|
// Update to different value
|
|
unchanged := tc.GetAndCompare(1, "America/Chicago")
|
|
assert.False(t, unchanged, "different value should indicate a change")
|
|
|
|
// Now the new value is cached
|
|
unchanged = tc.GetAndCompare(1, "America/Chicago")
|
|
assert.True(t, unchanged, "same value should indicate no change")
|
|
}
|
|
|
|
func TestTimezoneCache_GetAndCompare_DifferentUsers(t *testing.T) {
|
|
tc := NewTimezoneCache()
|
|
|
|
tc.GetAndCompare(1, "America/New_York")
|
|
tc.GetAndCompare(2, "Europe/London")
|
|
|
|
assert.True(t, tc.GetAndCompare(1, "America/New_York"))
|
|
assert.True(t, tc.GetAndCompare(2, "Europe/London"))
|
|
assert.False(t, tc.GetAndCompare(1, "Europe/London"))
|
|
}
|