Files
deeplx/tests/lib/services/microsoftTranslator.test.ts
T
xixu-me e30b019cd2 Refactor Microsoft Translator integration and tests
Refactored the Microsoft Translator service to use a parameter object for translation requests, improved language code normalization, and enhanced error handling. Updated integration and unit tests to match the new API and moved Microsoft Translator unit tests to a new location under tests/lib/services. Removed the old test file and added more comprehensive test coverage for translation scenarios and error cases.
2025-08-09 18:18:36 +08:00

240 lines
6.3 KiB
TypeScript

/**
* Unit tests for Microsoft Translator service
*/
import { beforeEach, describe, expect, it } from "@jest/globals";
import { translateWithMicrosoft } from "../../../src/lib/services/microsoftTranslator";
// Mock global fetch
const mockFetch = jest.fn();
global.fetch = mockFetch;
describe("Microsoft Translator Service", () => {
beforeEach(() => {
jest.clearAllMocks();
});
it("should successfully translate text", async () => {
// Mock successful auth token response
mockFetch
.mockResolvedValueOnce({
ok: true,
text: () => Promise.resolve("mock-auth-token"),
})
.mockResolvedValueOnce({
ok: true,
json: () =>
Promise.resolve([
{
translations: [
{
text: "你好世界",
to: "zh-Hans",
},
],
detectedLanguage: {
language: "en",
score: 1.0,
},
},
]),
});
const result = await translateWithMicrosoft({
text: "Hello world",
source_lang: "en",
target_lang: "zh",
});
expect(result.code).toBe(200);
expect(result.data).toBe("你好世界");
expect(result.source_lang).toBe("EN");
expect(result.target_lang).toBe("ZH-HANS");
// Verify correct API calls
expect(mockFetch).toHaveBeenCalledTimes(2);
expect(mockFetch).toHaveBeenNthCalledWith(
1,
"https://edge.microsoft.com/translate/auth",
expect.objectContaining({
method: "GET",
headers: expect.objectContaining({
"User-Agent": expect.stringContaining("Chrome"),
}),
})
);
expect(mockFetch).toHaveBeenNthCalledWith(
2,
expect.stringContaining("api-edge.cognitive.microsofttranslator.com"),
expect.objectContaining({
method: "POST",
headers: expect.objectContaining({
authorization: "Bearer mock-auth-token",
"content-type": "application/json",
}),
body: JSON.stringify([{ Text: "Hello world" }]),
})
);
});
it("should handle auto language detection", async () => {
// Mock successful auth token response
mockFetch
.mockResolvedValueOnce({
ok: true,
text: () => Promise.resolve("mock-auth-token"),
})
.mockResolvedValueOnce({
ok: true,
json: () =>
Promise.resolve([
{
translations: [
{
text: "Hello world",
to: "en",
},
],
detectedLanguage: {
language: "zh-Hans",
score: 0.95,
},
},
]),
});
const result = await translateWithMicrosoft({
text: "你好世界",
source_lang: "auto",
target_lang: "en",
});
expect(result.code).toBe(200);
expect(result.data).toBe("Hello world");
expect(result.source_lang).toBe("ZH-HANS");
expect(result.target_lang).toBe("EN");
});
it("should handle auth token failure", async () => {
// Mock failed auth token response
mockFetch.mockResolvedValueOnce({
ok: false,
status: 403,
statusText: "Forbidden",
});
const result = await translateWithMicrosoft({
text: "Hello world",
source_lang: "en",
target_lang: "zh",
});
expect(result.code).toBeGreaterThanOrEqual(400);
expect(result.data).toBeNull();
expect(mockFetch).toHaveBeenCalledTimes(1);
});
it("should handle translation API failure", async () => {
// Mock successful auth but failed translation
mockFetch
.mockResolvedValueOnce({
ok: true,
text: () => Promise.resolve("mock-auth-token"),
})
.mockResolvedValueOnce({
ok: false,
status: 500,
statusText: "Internal Server Error",
});
const result = await translateWithMicrosoft({
text: "Hello world",
source_lang: "en",
target_lang: "zh",
});
expect(result.code).toBeGreaterThanOrEqual(400);
expect(result.data).toBeNull();
expect(mockFetch).toHaveBeenCalledTimes(2);
});
it("should handle empty auth token", async () => {
// Mock empty auth token response
mockFetch.mockResolvedValueOnce({
ok: true,
text: () => Promise.resolve(""),
});
const result = await translateWithMicrosoft({
text: "Hello world",
source_lang: "en",
target_lang: "zh",
});
expect(result.code).toBeGreaterThanOrEqual(400);
expect(result.data).toBeNull();
expect(mockFetch).toHaveBeenCalledTimes(1);
});
it("should handle invalid translation response", async () => {
// Mock successful auth but invalid translation response
mockFetch
.mockResolvedValueOnce({
ok: true,
text: () => Promise.resolve("mock-auth-token"),
})
.mockResolvedValueOnce({
ok: true,
json: () => Promise.resolve([{}]), // Empty translation object
});
const result = await translateWithMicrosoft({
text: "Hello world",
source_lang: "en",
target_lang: "zh",
});
expect(result.code).toBeGreaterThanOrEqual(400);
expect(result.data).toBeNull();
});
it("should normalize language codes correctly", async () => {
// Mock successful response
mockFetch
.mockResolvedValueOnce({
ok: true,
text: () => Promise.resolve("mock-auth-token"),
})
.mockResolvedValueOnce({
ok: true,
json: () =>
Promise.resolve([
{
translations: [
{
text: "你好世界",
to: "zh-Hans",
},
],
detectedLanguage: {
language: "en",
score: 1.0,
},
},
]),
});
await translateWithMicrosoft({
text: "Hello world",
source_lang: "EN", // Should be normalized to 'en'
target_lang: "ZH-CN", // Should be normalized to 'zh-Hans'
});
// Check that the URL contains correctly normalized language codes
const secondCall = mockFetch.mock.calls[1];
const url = secondCall[0];
expect(url).toContain("from=en");
expect(url).toContain("to=zh-hans");
});
});