mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Fix DeepL Response parsing, mock DeepL tests so they can always run without API keys
This commit is contained in:
parent
403d0ac5c2
commit
d791a9b350
3 changed files with 70 additions and 23 deletions
|
|
@ -1,21 +1,20 @@
|
|||
import { DittoConf } from '@ditto/conf';
|
||||
import { detectLanguage } from '@ditto/lang';
|
||||
import { assert, assertEquals } from '@std/assert';
|
||||
|
||||
import { DeepLTranslator } from './DeepLTranslator.ts';
|
||||
|
||||
const {
|
||||
deeplBaseUrl: baseUrl,
|
||||
deeplApiKey: apiKey,
|
||||
translationProvider,
|
||||
} = new DittoConf(Deno.env);
|
||||
|
||||
const deepl = 'deepl';
|
||||
|
||||
Deno.test('DeepL translation with source language omitted', {
|
||||
ignore: !(translationProvider === deepl && apiKey),
|
||||
}, async () => {
|
||||
const translator = new DeepLTranslator({ fetch: fetch, baseUrl, apiKey: apiKey! });
|
||||
Deno.test('DeepL translation with source language omitted', async () => {
|
||||
const translator = mockDeepL({
|
||||
translations: [
|
||||
{ detected_source_language: 'PT', text: 'Good morning friends' },
|
||||
{ detected_source_language: 'PT', text: 'My name is Patrick' },
|
||||
{
|
||||
detected_source_language: 'PT',
|
||||
text:
|
||||
'I will live in America, I promise. But first, I should mention that lande is interpreting this text as Italian, how strange.',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const data = await translator.translate(
|
||||
[
|
||||
|
|
@ -33,10 +32,18 @@ Deno.test('DeepL translation with source language omitted', {
|
|||
assertEquals(detectLanguage(data.results[2], 0), 'en');
|
||||
});
|
||||
|
||||
Deno.test('DeepL translation with source language set', {
|
||||
ignore: !(translationProvider === deepl && apiKey),
|
||||
}, async () => {
|
||||
const translator = new DeepLTranslator({ fetch: fetch, baseUrl, apiKey: apiKey as string });
|
||||
Deno.test('DeepL translation with source language set', async () => {
|
||||
const translator = mockDeepL({
|
||||
translations: [
|
||||
{ detected_source_language: 'PT', text: 'Good morning friends' },
|
||||
{ detected_source_language: 'PT', text: 'My name is Patrick' },
|
||||
{
|
||||
detected_source_language: 'PT',
|
||||
text:
|
||||
'I will live in America, I promise. But first, I should mention that lande is interpreting this text as Italian, how strange.',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const data = await translator.translate(
|
||||
[
|
||||
|
|
@ -54,10 +61,16 @@ Deno.test('DeepL translation with source language set', {
|
|||
assertEquals(detectLanguage(data.results[2], 0), 'en');
|
||||
});
|
||||
|
||||
Deno.test("DeepL translation doesn't alter Nostr URIs", {
|
||||
ignore: !(translationProvider === deepl && apiKey),
|
||||
}, async () => {
|
||||
const translator = new DeepLTranslator({ fetch: fetch, baseUrl, apiKey: apiKey as string });
|
||||
Deno.test("DeepL translation doesn't alter Nostr URIs", async () => {
|
||||
const translator = mockDeepL({
|
||||
translations: [
|
||||
{
|
||||
detected_source_language: 'EN',
|
||||
text:
|
||||
'Graças ao trabalho de nostr:nprofile1qy2hwumn8ghj7erfw36x7tnsw43z7un9d3shjqpqgujeqakgt7fyp6zjggxhyy7ft623qtcaay5lkc8n8gkry4cvnrzqep59se e nostr:nprofile1qy2hwumn8ghj7erfw36x7tnsw43z7un9d3shjqpqe6tnvlr46lv3lwdu80r07kanhk6jcxy5r07w9umgv9kuhu9dl5hsz44l8s , agora é possível filtrar o feed global por idioma no #Ditto!',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const patrick =
|
||||
'nostr:nprofile1qy2hwumn8ghj7erfw36x7tnsw43z7un9d3shjqpqgujeqakgt7fyp6zjggxhyy7ft623qtcaay5lkc8n8gkry4cvnrzqep59se';
|
||||
|
|
@ -72,3 +85,17 @@ Deno.test("DeepL translation doesn't alter Nostr URIs", {
|
|||
assert(output.includes(patrick));
|
||||
assert(output.includes(danidfra));
|
||||
});
|
||||
|
||||
interface DeepLResponse {
|
||||
translations: {
|
||||
detected_source_language: string;
|
||||
text: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
function mockDeepL(json: DeepLResponse): DeepLTranslator {
|
||||
return new DeepLTranslator({
|
||||
apiKey: 'deepl',
|
||||
fetch: () => Promise.resolve(new Response(JSON.stringify(json))),
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,13 @@ export class DeepLTranslator implements DittoTranslator {
|
|||
const json = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(json['message']);
|
||||
const result = DeepLTranslator.errorSchema().safeParse(json);
|
||||
|
||||
if (result.success) {
|
||||
throw new Error(result.data.message);
|
||||
} else {
|
||||
throw new Error(`Unexpected DeepL error: ${response.statusText} (${response.status})`);
|
||||
}
|
||||
}
|
||||
|
||||
return DeepLTranslator.schema().parse(json);
|
||||
|
|
@ -84,10 +90,17 @@ export class DeepLTranslator implements DittoTranslator {
|
|||
return z.object({
|
||||
translations: z.array(
|
||||
z.object({
|
||||
detected_source_language: languageSchema,
|
||||
detected_source_language: z.string().transform((val) => val.toLowerCase()).pipe(languageSchema),
|
||||
text: z.string(),
|
||||
}),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
/** DeepL error response schema. */
|
||||
private static errorSchema() {
|
||||
return z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7
packages/translators/schema.test.ts
Normal file
7
packages/translators/schema.test.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { assertEquals } from '@std/assert';
|
||||
|
||||
import { languageSchema } from './schema.ts';
|
||||
|
||||
Deno.test('languageSchema', () => {
|
||||
assertEquals(languageSchema.safeParse('en').success, true);
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue