package cache import ( "testing" "time" "git.nakama.town/fmartingr/butterrobot/internal/db" ) func TestCache(t *testing.T) { // Create temporary database for testing database, err := db.New("test_cache.db") if err != nil { t.Fatalf("Failed to create test database: %v", err) } defer func() { database.Close() // Clean up test database file // os.Remove("test_cache.db") }() // Create cache instance cache := New(database, "test.plugin") // Test data testKey := "test_key" testValue := map[string]interface{}{ "name": "Test Game", "time": 42, } // Test Set and Get t.Run("Set and Get", func(t *testing.T) { err := cache.Set(testKey, testValue, nil) if err != nil { t.Errorf("Failed to set cache value: %v", err) } var retrieved map[string]interface{} err = cache.Get(testKey, &retrieved) if err != nil { t.Errorf("Failed to get cache value: %v", err) } if retrieved["name"] != testValue["name"] { t.Errorf("Expected name %v, got %v", testValue["name"], retrieved["name"]) } if int(retrieved["time"].(float64)) != testValue["time"].(int) { t.Errorf("Expected time %v, got %v", testValue["time"], retrieved["time"]) } }) // Test SetWithTTL and expiration t.Run("SetWithTTL and expiration", func(t *testing.T) { expiredKey := "expired_key" // Set with very short TTL err := cache.SetWithTTL(expiredKey, testValue, time.Millisecond) if err != nil { t.Errorf("Failed to set cache value with TTL: %v", err) } // Wait for expiration time.Sleep(2 * time.Millisecond) // Try to get - should fail var retrieved map[string]interface{} err = cache.Get(expiredKey, &retrieved) if err == nil { t.Errorf("Expected cache miss for expired key, but got value") } }) // Test Exists t.Run("Exists", func(t *testing.T) { existsKey := "exists_key" // Should not exist initially exists, err := cache.Exists(existsKey) if err != nil { t.Errorf("Failed to check if key exists: %v", err) } if exists { t.Errorf("Expected key to not exist, but it does") } // Set value err = cache.Set(existsKey, testValue, nil) if err != nil { t.Errorf("Failed to set cache value: %v", err) } // Should exist now exists, err = cache.Exists(existsKey) if err != nil { t.Errorf("Failed to check if key exists: %v", err) } if !exists { t.Errorf("Expected key to exist, but it doesn't") } }) // Test Delete t.Run("Delete", func(t *testing.T) { deleteKey := "delete_key" // Set value err := cache.Set(deleteKey, testValue, nil) if err != nil { t.Errorf("Failed to set cache value: %v", err) } // Delete value err = cache.Delete(deleteKey) if err != nil { t.Errorf("Failed to delete cache value: %v", err) } // Should not exist anymore var retrieved map[string]interface{} err = cache.Get(deleteKey, &retrieved) if err == nil { t.Errorf("Expected cache miss for deleted key, but got value") } }) // Test plugin ID prefixing t.Run("Plugin ID prefixing", func(t *testing.T) { cache1 := New(database, "plugin1") cache2 := New(database, "plugin2") sameKey := "same_key" value1 := "value1" value2 := "value2" // Set same key in both caches err := cache1.Set(sameKey, value1, nil) if err != nil { t.Errorf("Failed to set cache1 value: %v", err) } err = cache2.Set(sameKey, value2, nil) if err != nil { t.Errorf("Failed to set cache2 value: %v", err) } // Retrieve from both caches var retrieved1, retrieved2 string err = cache1.Get(sameKey, &retrieved1) if err != nil { t.Errorf("Failed to get cache1 value: %v", err) } err = cache2.Get(sameKey, &retrieved2) if err != nil { t.Errorf("Failed to get cache2 value: %v", err) } // Values should be different due to plugin ID prefixing if retrieved1 != value1 { t.Errorf("Expected cache1 value %v, got %v", value1, retrieved1) } if retrieved2 != value2 { t.Errorf("Expected cache2 value %v, got %v", value2, retrieved2) } }) }