155 lines
4.1 KiB
TypeScript
155 lines
4.1 KiB
TypeScript
/**
|
|
* Tests for cache module - translation caching functionality
|
|
*/
|
|
|
|
import {
|
|
clearMemoryCache,
|
|
generateCacheKey,
|
|
getCachedTranslation,
|
|
setCachedTranslation,
|
|
} from "../../src/lib/cache";
|
|
|
|
describe("Cache Module", () => {
|
|
let mockEnv: Env;
|
|
|
|
beforeEach(() => {
|
|
mockEnv = createMockEnv();
|
|
clearMemoryCache();
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
describe("generateCacheKey", () => {
|
|
it("should generate consistent cache keys", () => {
|
|
const key1 = generateCacheKey("Hello world", "EN", "ZH");
|
|
const key2 = generateCacheKey("Hello world", "EN", "ZH");
|
|
|
|
expect(key1).toBe(key2);
|
|
expect(key1).toMatch(/^cache_/);
|
|
});
|
|
|
|
it("should generate different keys for different inputs", () => {
|
|
const key1 = generateCacheKey("Hello world", "EN", "ZH");
|
|
const key2 = generateCacheKey("Hello world", "EN", "ES");
|
|
const key3 = generateCacheKey("Goodbye world", "EN", "ZH");
|
|
|
|
expect(key1).not.toBe(key2);
|
|
expect(key1).not.toBe(key3);
|
|
expect(key2).not.toBe(key3);
|
|
});
|
|
|
|
it("should handle special characters in text", () => {
|
|
const key = generateCacheKey("Hello, 世界! @#$%", "EN", "ZH");
|
|
expect(key).toMatch(/^cache_/);
|
|
});
|
|
});
|
|
|
|
describe("setCachedTranslation", () => {
|
|
it("should store translation in KV", async () => {
|
|
const cacheEntry = {
|
|
data: "你好世界",
|
|
timestamp: Date.now(),
|
|
source_lang: "EN",
|
|
target_lang: "ZH",
|
|
id: 12345,
|
|
};
|
|
|
|
await setCachedTranslation("test-key", cacheEntry, mockEnv);
|
|
|
|
expect(mockEnv.CACHE_KV.put).toHaveBeenCalledWith(
|
|
"test-key",
|
|
JSON.stringify(cacheEntry),
|
|
expect.objectContaining({
|
|
expirationTtl: expect.any(Number),
|
|
})
|
|
);
|
|
});
|
|
|
|
it("should handle KV storage errors gracefully", async () => {
|
|
(mockEnv.CACHE_KV.put as jest.Mock).mockRejectedValueOnce(
|
|
new Error("KV error")
|
|
);
|
|
|
|
const cacheEntry = {
|
|
data: "你好世界",
|
|
timestamp: Date.now(),
|
|
source_lang: "EN",
|
|
target_lang: "ZH",
|
|
};
|
|
|
|
// Should not throw
|
|
await expect(
|
|
setCachedTranslation("test-key", cacheEntry, mockEnv)
|
|
).resolves.not.toThrow();
|
|
});
|
|
});
|
|
|
|
describe("getCachedTranslation", () => {
|
|
it("should retrieve cached translation from KV", async () => {
|
|
const cacheEntry = {
|
|
data: "你好世界",
|
|
timestamp: Date.now(),
|
|
source_lang: "EN",
|
|
target_lang: "ZH",
|
|
id: 12345,
|
|
};
|
|
|
|
(mockEnv.CACHE_KV.get as jest.Mock).mockResolvedValueOnce(cacheEntry);
|
|
|
|
const result = await getCachedTranslation("test-key", mockEnv);
|
|
|
|
expect(result).toEqual(cacheEntry);
|
|
expect(mockEnv.CACHE_KV.get).toHaveBeenCalledWith("test-key", "json");
|
|
});
|
|
|
|
it("should return null for cache miss", async () => {
|
|
(mockEnv.CACHE_KV.get as jest.Mock).mockResolvedValueOnce(null);
|
|
|
|
const result = await getCachedTranslation("test-key", mockEnv);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it("should handle expired cache entries", async () => {
|
|
const expiredEntry = {
|
|
data: "你好世界",
|
|
timestamp: Date.now() - 25 * 60 * 60 * 1000, // 25 hours ago
|
|
source_lang: "EN",
|
|
target_lang: "ZH",
|
|
};
|
|
|
|
(mockEnv.CACHE_KV.get as jest.Mock).mockResolvedValueOnce(expiredEntry);
|
|
|
|
const result = await getCachedTranslation("test-key", mockEnv);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it("should handle invalid JSON in cache", async () => {
|
|
(mockEnv.CACHE_KV.get as jest.Mock).mockResolvedValueOnce(null);
|
|
|
|
const result = await getCachedTranslation("test-key", mockEnv);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it("should handle KV retrieval errors gracefully", async () => {
|
|
(mockEnv.CACHE_KV.get as jest.Mock).mockRejectedValueOnce(
|
|
new Error("KV error")
|
|
);
|
|
|
|
const result = await getCachedTranslation("test-key", mockEnv);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("clearMemoryCache", () => {
|
|
it("should clear memory cache without errors", () => {
|
|
expect(() => clearMemoryCache()).not.toThrow();
|
|
});
|
|
});
|
|
});
|