Files
deeplx/tests/integration/translation.test.ts
T
xixu-me 1076a5817f Remove Microsoft Translator integration and update docs
Eliminated Microsoft Translator support from the codebase, including its service implementation, API endpoint, and related tests. Updated both English and Chinese README files to reflect the removal and to clarify usage of DeepL and Google endpoints, providing improved examples and API documentation.
2025-08-09 18:41:49 +08:00

284 lines
7.1 KiB
TypeScript

/**
* Integration tests for translation functionality
*/
describe("Translation Integration Tests", () => {
let mockEnv: Env;
beforeEach(() => {
mockEnv = createMockEnv();
});
afterEach(() => {
jest.clearAllMocks();
});
describe("End-to-end translation flow", () => {
it("should complete full translation workflow", async () => {
// Mock successful API response
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: () =>
Promise.resolve({
result: {
texts: [{ text: "你好世界" }],
lang: "ZH",
},
id: 12345,
}),
});
const { query } = await import("../../src/lib/query");
const result = await query(
{
text: "Hello world",
source_lang: "en",
target_lang: "zh",
},
{ env: mockEnv }
);
expect(result.code).toBe(200);
expect(result.data).toBe("你好世界");
expect(result.source_lang).toBe("ZH");
expect(result.target_lang).toBe("ZH");
});
it("should handle rate limiting in translation flow", async () => {
// Mock rate limit exceeded
(mockEnv.RATE_LIMIT_KV.get as jest.Mock).mockResolvedValue(
JSON.stringify({
tokens: 0,
lastRefill: Date.now(),
})
);
const { query } = await import("../../src/lib/query");
const result = await query(
{
text: "Hello world",
source_lang: "en",
target_lang: "zh",
},
{ env: mockEnv, clientIP: "192.168.1.1" }
);
expect(result.code).toBe(429);
});
it("should use cache when available", async () => {
const cachedEntry = {
data: "你好世界",
timestamp: Date.now(),
source_lang: "EN",
target_lang: "ZH",
id: 12345,
};
(mockEnv.CACHE_KV.get as jest.Mock).mockResolvedValue(
JSON.stringify(cachedEntry)
);
const { getCachedTranslation, generateCacheKey } = await import(
"../../src/lib/cache"
);
const cacheKey = generateCacheKey("Hello world", "EN", "ZH");
const result = await getCachedTranslation(cacheKey, mockEnv);
expect(result).toEqual(cachedEntry);
});
it("should handle proxy selection and failover", async () => {
// Mock first proxy failure, second proxy success
global.fetch = jest
.fn()
.mockRejectedValueOnce(new Error("Network error"))
.mockResolvedValueOnce({
ok: true,
json: () =>
Promise.resolve({
result: {
texts: [{ text: "你好世界" }],
lang: "ZH",
},
id: 12345,
}),
});
const { query } = await import("../../src/lib/query");
const result = await query(
{
text: "Hello world",
source_lang: "en",
target_lang: "zh",
},
{ env: mockEnv }
);
expect(result.code).toBe(200);
expect(result.data).toBe("你好世界");
});
});
describe("Error handling integration", () => {
it("should handle API errors gracefully", async () => {
// Mock API error response
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: () =>
Promise.resolve({
error: {
code: 1156049,
message: "Invalid request format",
},
}),
});
const { query } = await import("../../src/lib/query");
const result = await query(
{
text: "Hello world",
source_lang: "en",
target_lang: "zh",
},
{ env: mockEnv }
);
expect(result.code).toBeGreaterThanOrEqual(400);
expect(result.data).toBeNull();
});
it("should handle network failures with retry", async () => {
// Mock network failure then success
global.fetch = jest
.fn()
.mockRejectedValueOnce(new Error("Network error"))
.mockRejectedValueOnce(new Error("Network error"))
.mockResolvedValueOnce({
ok: true,
json: () =>
Promise.resolve({
result: {
texts: [{ text: "你好世界" }],
lang: "ZH",
},
id: 12345,
}),
});
const { query } = await import("../../src/lib/query");
const result = await query(
{
text: "Hello world",
source_lang: "en",
target_lang: "zh",
},
{ env: mockEnv }
);
expect(result.code).toBe(200);
expect(result.data).toBe("你好世界");
});
});
describe("Performance and reliability", () => {
it("should handle concurrent requests", async () => {
global.fetch = jest.fn().mockResolvedValue({
ok: true,
json: () =>
Promise.resolve({
result: {
texts: [{ text: "你好世界" }],
lang: "ZH",
},
id: 12345,
}),
});
const { query } = await import("../../src/lib/query");
const promises = Array.from({ length: 10 }, (_, i) =>
query(
{
text: `Hello world ${i}`,
source_lang: "en",
target_lang: "zh",
},
{ env: mockEnv }
)
);
const results = await Promise.all(promises);
results.forEach((result) => {
expect(result.code).toBe(200);
expect(result.data).toBe("你好世界");
});
});
it("should handle timeout scenarios", async () => {
// Mock timeout
global.fetch = jest
.fn()
.mockImplementation(
() =>
new Promise((_, reject) =>
setTimeout(() => reject(new Error("Request timeout")), 100)
)
);
const { query } = await import("../../src/lib/query");
const result = await query(
{
text: "Hello world",
source_lang: "en",
target_lang: "zh",
},
{ env: mockEnv }
);
expect(result.code).toBeGreaterThanOrEqual(400);
});
});
describe("Security integration", () => {
it("should validate and sanitize input", async () => {
const { validateTranslationRequest } = await import(
"../../src/lib/validation"
);
const maliciousInput = {
text: '<script>alert("xss")</script>Hello world',
source_lang: "en",
target_lang: "zh",
};
const result = validateTranslationRequest(maliciousInput);
expect(result.isValid).toBe(true);
expect(result.sanitizedInput?.text).toBe(
'<script>alert("xss")</script>Hello world'
);
});
it("should handle rate limiting across multiple IPs", async () => {
const { checkRateLimit } = await import("../../src/lib/rateLimit");
// Test multiple IPs
const ips = ["192.168.1.1", "192.168.1.2", "192.168.1.3"];
for (const ip of ips) {
const result = await checkRateLimit(ip, mockEnv);
expect(result.allowed).toBe(true);
}
});
});
});