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")) }