mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-25 10:20:03 -06:00
118 lines
4.2 KiB
TypeScript
118 lines
4.2 KiB
TypeScript
import KeyvRedis from "@keyv/redis";
|
|
import { createCache } from "cache-manager";
|
|
import { Keyv } from "keyv";
|
|
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
import { logger } from "@formbricks/logger";
|
|
|
|
// Mock dependencies
|
|
vi.mock("keyv");
|
|
vi.mock("@keyv/redis");
|
|
vi.mock("cache-manager");
|
|
vi.mock("@formbricks/logger");
|
|
|
|
const mockCacheInstance = {
|
|
set: vi.fn(),
|
|
get: vi.fn(),
|
|
del: vi.fn(),
|
|
};
|
|
|
|
const CACHE_TTL_SECONDS = 60 * 60 * 24; // 24 hours
|
|
const CACHE_TTL_MS = CACHE_TTL_SECONDS * 1000;
|
|
|
|
describe("Cache Service", () => {
|
|
let originalRedisUrl: string | undefined;
|
|
|
|
beforeEach(() => {
|
|
originalRedisUrl = process.env.REDIS_URL;
|
|
vi.resetAllMocks();
|
|
vi.resetModules(); // Crucial for re-running module initialization logic
|
|
|
|
// Setup default mock implementations
|
|
vi.mocked(createCache).mockReturnValue(mockCacheInstance as any);
|
|
vi.mocked(Keyv).mockClear(); // Clear any previous calls
|
|
vi.mocked(KeyvRedis).mockClear(); // Clear any previous calls
|
|
vi.mocked(logger.warn).mockClear(); // Clear logger warnings
|
|
});
|
|
|
|
afterEach(() => {
|
|
process.env.REDIS_URL = originalRedisUrl;
|
|
});
|
|
|
|
describe("Initialization and getCache", () => {
|
|
test("should use Redis store and return it via getCache if REDIS_URL is set", async () => {
|
|
process.env.REDIS_URL = "redis://localhost:6379";
|
|
const { getCache } = await import("./service"); // Dynamically import
|
|
|
|
expect(KeyvRedis).toHaveBeenCalledWith("redis://localhost:6379");
|
|
expect(Keyv).toHaveBeenCalledWith({
|
|
store: expect.any(KeyvRedis),
|
|
ttl: CACHE_TTL_MS,
|
|
});
|
|
expect(createCache).toHaveBeenCalledWith({
|
|
stores: [expect.any(Keyv)],
|
|
ttl: CACHE_TTL_MS,
|
|
});
|
|
expect(logger.warn).not.toHaveBeenCalled();
|
|
expect(logger.info).toHaveBeenCalledWith("Successfully connected to Redis cache");
|
|
expect(getCache()).toBe(mockCacheInstance);
|
|
});
|
|
|
|
test("should fall back to memory store if Redis connection fails", async () => {
|
|
process.env.REDIS_URL = "redis://localhost:6379";
|
|
const mockError = new Error("Connection refused");
|
|
vi.mocked(KeyvRedis).mockImplementation(() => {
|
|
throw mockError;
|
|
});
|
|
|
|
const { getCache } = await import("./service"); // Dynamically import
|
|
|
|
expect(KeyvRedis).toHaveBeenCalledWith("redis://localhost:6379");
|
|
expect(logger.error).toHaveBeenCalledWith("Failed to connect to Redis cache:", mockError);
|
|
expect(logger.warn).toHaveBeenCalledWith(
|
|
"Falling back to in-memory cache due to Redis connection failure"
|
|
);
|
|
expect(Keyv).toHaveBeenCalledWith({
|
|
ttl: CACHE_TTL_MS,
|
|
});
|
|
expect(createCache).toHaveBeenCalledWith({
|
|
stores: [expect.any(Keyv)],
|
|
ttl: CACHE_TTL_MS,
|
|
});
|
|
expect(getCache()).toBe(mockCacheInstance);
|
|
});
|
|
|
|
test("should use memory store, log warning, and return it via getCache if REDIS_URL is not set", async () => {
|
|
delete process.env.REDIS_URL;
|
|
const { getCache } = await import("./service"); // Dynamically import
|
|
|
|
expect(KeyvRedis).not.toHaveBeenCalled();
|
|
expect(Keyv).toHaveBeenCalledWith({
|
|
ttl: CACHE_TTL_MS,
|
|
});
|
|
expect(createCache).toHaveBeenCalledWith({
|
|
stores: [expect.any(Keyv)],
|
|
ttl: CACHE_TTL_MS,
|
|
});
|
|
expect(logger.warn).toHaveBeenCalledWith("REDIS_URL not found, falling back to in-memory cache.");
|
|
expect(getCache()).toBe(mockCacheInstance);
|
|
});
|
|
|
|
test("should use memory store, log warning, and return it via getCache if REDIS_URL is an empty string", async () => {
|
|
process.env.REDIS_URL = ""; // Test with empty string
|
|
const { getCache } = await import("./service"); // Dynamically import
|
|
|
|
// If REDIS_URL is "", it's falsy, so it should fall back to memory store
|
|
expect(KeyvRedis).not.toHaveBeenCalled();
|
|
expect(Keyv).toHaveBeenCalledWith({
|
|
ttl: CACHE_TTL_MS, // Expect memory store configuration
|
|
});
|
|
expect(createCache).toHaveBeenCalledWith({
|
|
stores: [expect.any(Keyv)],
|
|
ttl: CACHE_TTL_MS,
|
|
});
|
|
expect(logger.warn).toHaveBeenCalledWith("REDIS_URL not found, falling back to in-memory cache.");
|
|
expect(getCache()).toBe(mockCacheInstance);
|
|
});
|
|
});
|
|
});
|