defmodule Pleroma.Akkoma.Translators.LibreTranslateTest do use Pleroma.DataCase, async: true alias Pleroma.Akkoma.Translators.LibreTranslate describe "translating with libre translate" do setup do clear_config([:libre_translate, :url], "http://libre.translate/translate") end test "should list supported languages" do clear_config([:deepl, :tier], :free) Tesla.Mock.mock(fn %{method: :get, url: "http://libre.translate/languages"} = _ -> %Tesla.Env{ status: 200, body: Jason.encode!([ %{ "code" => "en", "name" => "English" }, %{ "code" => "ar", "name" => "Arabic" } ]) } end) assert {:ok, [%{code: "en", name: "English"}, %{code: "ar", name: "Arabic"}], [%{code: "en", name: "English"}, %{code: "ar", name: "Arabic"}]} = LibreTranslate.languages() end test "should work without an API key" do Tesla.Mock.mock(fn %{method: :post, url: "http://libre.translate/translate"} = env -> assert {:ok, %{"api_key" => nil, "source" => "auto"}} = Jason.decode(env.body) %Tesla.Env{ status: 200, body: Jason.encode!(%{ detectedLanguage: %{ confidence: 83, language: "ja" }, translatedText: "I will crush you" }) } end) assert {:ok, "ja", "I will crush you"} = LibreTranslate.translate("ギュギュ握りつぶしちゃうぞ", nil, "en") end test "should work with an API key" do clear_config([:libre_translate, :api_key], "libre_translate_api_key") Tesla.Mock.mock(fn %{method: :post, url: "http://libre.translate/translate"} = env -> assert {:ok, %{"api_key" => "libre_translate_api_key"}} = Jason.decode(env.body) %Tesla.Env{ status: 200, body: Jason.encode!(%{ detectedLanguage: %{ confidence: 83, language: "ja" }, translatedText: "I will crush you" }) } end) assert {:ok, "ja", "I will crush you"} = LibreTranslate.translate("ギュギュ握りつぶしちゃうぞ", nil, "en") end test "should gracefully handle API key errors" do clear_config([:libre_translate, :api_key], "") Tesla.Mock.mock(fn %{method: :post, url: "http://libre.translate/translate"} -> %Tesla.Env{ status: 403, body: Jason.encode!(%{ error: "Please contact the server operator to obtain an API key" }) } end) assert {:error, "libre_translate: request failed (code 403)"} = LibreTranslate.translate("ギュギュ握りつぶしちゃうぞ", nil, "en") end test "should set a source language if requested" do Tesla.Mock.mock(fn %{method: :post, url: "http://libre.translate/translate"} = env -> assert {:ok, %{"api_key" => nil, "source" => "ja"}} = Jason.decode(env.body) %Tesla.Env{ status: 200, body: Jason.encode!(%{ translatedText: "I will crush you" }) } end) assert {:ok, "ja", "I will crush you"} = LibreTranslate.translate("ギュギュ握りつぶしちゃうぞ", "ja", "en") end test "should gracefully handle an unsupported language" do clear_config([:libre_translate, :api_key], "") Tesla.Mock.mock(fn %{method: :post, url: "http://libre.translate/translate"} -> %Tesla.Env{ status: 400, body: Jason.encode!(%{ error: "zoop is not supported" }) } end) assert {:error, "libre_translate: request failed (code 400)"} = LibreTranslate.translate("ギュギュ握りつぶしちゃうぞ", nil, "zoop") end test "should work when no detected language is received" do Tesla.Mock.mock(fn %{method: :post, url: "http://libre.translate/translate"} -> %Tesla.Env{ status: 200, body: Jason.encode!(%{ translatedText: "I will crush you" }) } end) assert {:ok, "", "I will crush you"} = LibreTranslate.translate("ギュギュ握りつぶしちゃうぞ", nil, "en") end end end