// OpenTween - Client of Twitter
// Copyright (c) 2012 the40san <http://sourceforge.jp/users/the40san/>
+// (c) 2014 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
// All rights reserved.
//
// This file is part of OpenTween.
// Boston, MA 02110-1301, USA.
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
+using System.Net;
+using System.Net.Http;
using System.Text;
+using System.Threading.Tasks;
+using System.Web;
using Xunit;
using Xunit.Extensions;
{
/// <summary>
/// Bingクラスのテストクラス
- /// Translate(string _from, string _to, string _text, out string buf)のテスト未実装です
/// </summary>
public class BingTest
{
- List<string> LanguageTable;
- Bing bing;
-
- public BingTest()
+ [Fact]
+ public async Task TranslateAsync_Test()
{
- bing = new Bing();
- //リフレクション使ってインスタンスから取得するようにしたい
- #region 言語テーブル定義
- LanguageTable = new List<string>() {
- "af",
- "sq",
- "ar-sa",
- "ar-iq",
- "ar-eg",
- "ar-ly",
- "ar-dz",
- "ar-ma",
- "ar-tn",
- "ar-om",
- "ar-ye",
- "ar-sy",
- "ar-jo",
- "ar-lb",
- "ar-kw",
- "ar-ae",
- "ar-bh",
- "ar-qa",
- "eu",
- "bg",
- "be",
- "ca",
- "zh-tw",
- "zh-cn",
- "zh-hk",
- "zh-sg",
- "hr",
- "cs",
- "da",
- "nl",
- "nl-be",
- "en",
- "en-us",
- "en-gb",
- "en-au",
- "en-ca",
- "en-nz",
- "en-ie",
- "en-za",
- "en-jm",
- "en",
- "en-bz",
- "en-tt",
- "et",
- "fo",
- "fa",
- "fi",
- "fr",
- "fr-be",
- "fr-ca",
- "fr-ch",
- "fr-lu",
- "gd",
- "ga",
- "de",
- "de-ch",
- "de-at",
- "de-lu",
- "de-li",
- "el",
- "he",
- "hi",
- "hu",
- "is",
- "id",
- "it",
- "it-ch",
- "ja",
- "ko",
- "ko",
- "lv",
- "lt",
- "mk",
- "ms",
- "mt",
- "no",
- "no",
- "pl",
- "pt-br",
- "pt",
- "rm",
- "ro",
- "ro-mo",
- "ru",
- "ru-mo",
- "sz",
- "sr",
- "sr",
- "sk",
- "sl",
- "sb",
- "es",
- "es-mx",
- "es-gt",
- "es-cr",
- "es-pa",
- "es-do",
- "es-ve",
- "es-co",
- "es-pe",
- "es-ar",
- "es-ec",
- "es-cl",
- "es-uy",
- "es-py",
- "es-bo",
- "es-sv",
- "es-hn",
- "es-ni",
- "es-pr",
- "sx",
- "sv",
- "sv-fi",
- "th",
- "ts",
- "tn",
- "tr",
- "uk",
- "ur",
- "ve",
- "vi",
- "xh",
- "ji",
- "zu"
- };
- #endregion
+ var handler = new HttpMessageHandlerMock();
+ var bing = new Bing(new HttpClient(handler));
- }
+ handler.Enqueue(x =>
+ {
+ Assert.Equal(HttpMethod.Get, x.Method);
+ Assert.Equal("https://api.datamarket.azure.com/Data.ashx/Bing/MicrosoftTranslator/v1/Translate",
+ x.RequestUri.GetLeftPart(UriPartial.Path));
+
+ var query = HttpUtility.ParseQueryString(x.RequestUri.Query);
+
+ Assert.Equal("'hogehoge'", query["Text"]);
+ Assert.Equal("'ja'", query["To"]);
+ Assert.Equal("Raw", query["$format"]);
- //public bool TranslateTest(string _from, string _to, string _text, out string buf)
- //{
+ return new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent("<string>ほげほげ</string>"),
+ };
+ });
- //}
+ var translatedText = await bing.TranslateAsync("hogehoge", langFrom: null, langTo: "ja");
+ Assert.Equal("ほげほげ", translatedText);
+
+ Assert.Equal(0, handler.QueueCount);
+ }
[Fact]
- public void GetLanguageEnumFromIndexTest()
+ public async Task TranslateAsync_HttpErrorTest()
{
- Assert.Equal(LanguageTable[0], bing.GetLanguageEnumFromIndex(0));
- Assert.Equal(LanguageTable[1], bing.GetLanguageEnumFromIndex(1));
- Assert.Equal(LanguageTable[LanguageTable.Count - 1], bing.GetLanguageEnumFromIndex(LanguageTable.Count - 1));
+ var handler = new HttpMessageHandlerMock();
+ var bing = new Bing(new HttpClient(handler));
+
+ handler.Enqueue(x =>
+ {
+ return new HttpResponseMessage(HttpStatusCode.ServiceUnavailable);
+ });
+
+ await TestUtils.ThrowsAsync<HttpRequestException>(async () =>
+ await bing.TranslateAsync("hogehoge", langFrom: null, langTo: "ja"));
+
+ Assert.Equal(0, handler.QueueCount);
}
- [Fact]
- public void GetIndexFromLanguageEnumTest()
+ [Theory]
+ [InlineData("af", 0)]
+ [InlineData("sq", 1)]
+ [InlineData("ja", 67)]
+ public void GetLanguageEnumFromIndex_Test(string expected, int index)
+ {
+ Assert.Equal(expected, Bing.GetLanguageEnumFromIndex(index));
+ }
+
+ [Theory]
+ [InlineData(0, "af")]
+ [InlineData(1, "sq")]
+ [InlineData(67, "ja")]
+ public void GetIndexFromLanguageEnum_Test(int expected, string lang)
{
- Assert.Equal(0, bing.GetIndexFromLanguageEnum(LanguageTable[0]));
- Assert.Equal(1, bing.GetIndexFromLanguageEnum(LanguageTable[1]));
- Assert.Equal(LanguageTable.Count - 1, bing.GetIndexFromLanguageEnum(LanguageTable[LanguageTable.Count - 1]));
+ Assert.Equal(expected, Bing.GetIndexFromLanguageEnum(lang));
}
+ [Fact]
+ public void CreateBasicAuthHeaderValue_Test()
+ {
+ var value = Bing.CreateBasicAuthHeaderValue("user", "pass");
+ Assert.Equal("Basic", value.Scheme);
+ Assert.Equal("user:pass", Encoding.UTF8.GetString(Convert.FromBase64String(value.Parameter)));
+ }
}
}
GetEventNotifyFlag(ref _MyEventNotifyFlag, ref _isMyEventNotifyFlag);
ForceEventNotify = this.NotifyPanel.CheckForceEventNotify.Checked;
FavEventUnread = this.NotifyPanel.CheckFavEventUnread.Checked;
- TranslateLanguage = (new Bing()).GetLanguageEnumFromIndex(this.CooperatePanel.ComboBoxTranslateLanguage.SelectedIndex);
+ TranslateLanguage = Bing.GetLanguageEnumFromIndex(this.CooperatePanel.ComboBoxTranslateLanguage.SelectedIndex);
EventSoundFile = (string)this.NotifyPanel.ComboBoxEventNotifySound.SelectedItem;
AutoShortUrlFirst = (MyCommon.UrlConverter)this.ShortUrlPanel.ComboBoxAutoShortUrlFirst.SelectedIndex;
TabIconDisp = this.PreviewPanel.chkTabIconDisp.Checked;
ApplyEventNotifyFlag(EventNotifyEnabled, EventNotifyFlag, IsMyEventNotifyFlag);
this.NotifyPanel.CheckForceEventNotify.Checked = ForceEventNotify;
this.NotifyPanel.CheckFavEventUnread.Checked = FavEventUnread;
- this.CooperatePanel.ComboBoxTranslateLanguage.SelectedIndex = (new Bing()).GetIndexFromLanguageEnum(TranslateLanguage);
+ this.CooperatePanel.ComboBoxTranslateLanguage.SelectedIndex = Bing.GetIndexFromLanguageEnum(TranslateLanguage);
SoundFileListup();
this.ShortUrlPanel.ComboBoxAutoShortUrlFirst.SelectedIndex = (int)AutoShortUrlFirst;
this.PreviewPanel.chkTabIconDisp.Checked = TabIconDisp;
set
{
_MyTranslateLanguage = value;
- this.CooperatePanel.ComboBoxTranslateLanguage.SelectedIndex = (new Bing()).GetIndexFromLanguageEnum(value);
+ this.CooperatePanel.ComboBoxTranslateLanguage.SelectedIndex = Bing.GetIndexFromLanguageEnum(value);
}
}
using System;
using System.Collections.Generic;
-using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
using System.Text;
-using System.Net;
-using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Web;
+using System.Xml.Linq;
namespace OpenTween
{
public class Bing
{
- #region 言語テーブル定義
- private static readonly List<string> LanguageTable = new List<string>() {
+ private static readonly List<string> LanguageTable = new List<string>
+ {
"af",
"sq",
"ar-sa",
"vi",
"xh",
"ji",
- "zu"
+ "zu",
};
- #endregion
- #region Translation
- private const string TranslateUri = "https://api.datamarket.azure.com/Data.ashx/Bing/MicrosoftTranslator/v1/Translate";
+ private static readonly string TranslateUri =
+ "https://api.datamarket.azure.com/Data.ashx/Bing/MicrosoftTranslator/v1/Translate";
+
+ private readonly HttpClient http;
+
+ public Bing(HttpClient http)
+ {
+ this.http = http;
+ }
- public bool Translate(string _from, string _to, string _text, out string buf)
+ /// <summary>
+ /// Microsoft Translator API を使用した翻訳を非同期に行います
+ /// </summary>
+ /// <exception cref="HttpRequestException"/>
+ public async Task<string> TranslateAsync(string text, string langFrom, string langTo)
{
- var apiurl = TranslateUri +
- "?Text=" + Uri.EscapeDataString("'" + _text + "'") +
- "&To=" + Uri.EscapeDataString("'" + _to + "'") +
- "&$format=Raw";
+ var param = HttpUtility.ParseQueryString(string.Empty);
+ param["Text"] = "'" + text + "'";
+ param["To"] = "'" + langTo + "'";
+ param["$format"] = "Raw";
+
+ if (langFrom != null)
+ param["From"] = "'" + langFrom + "'";
- using (var client = new OTWebClient())
+ var request = new HttpRequestMessage(HttpMethod.Get, TranslateUri + "?" + param);
+ request.Headers.Authorization = CreateBasicAuthHeaderValue(ApplicationSettings.AzureMarketplaceKey, ApplicationSettings.AzureMarketplaceKey);
+
+ using (var response = await this.http.SendAsync(request).ConfigureAwait(false))
{
- client.Credentials = new NetworkCredential(ApplicationSettings.AzureMarketplaceKey, ApplicationSettings.AzureMarketplaceKey);
- client.Encoding = Encoding.UTF8;
+ response.EnsureSuccessStatusCode();
+
+ var xmlStr = await response.Content.ReadAsStringAsync()
+ .ConfigureAwait(false);
- try
- {
- var content = client.DownloadString(apiurl);
+ var xdoc = XDocument.Parse(xmlStr);
- buf = Regex.Replace(content, @"^<string[^>]*>(.*)</string>$", "$1");
- return true;
- }
- catch (WebException)
- {
- buf = null;
- return false;
- }
+ return xdoc.Root.Value;
}
}
- public string GetLanguageEnumFromIndex(int index)
+ public static string GetLanguageEnumFromIndex(int index)
{
return LanguageTable[index];
}
- public int GetIndexFromLanguageEnum(string lang)
+ public static int GetIndexFromLanguageEnum(string lang)
{
return LanguageTable.IndexOf(lang);
}
- #endregion
+
+ internal static AuthenticationHeaderValue CreateBasicAuthHeaderValue(string user, string pass)
+ {
+ var paramBytes = Encoding.UTF8.GetBytes(user + ":" + pass);
+ return new AuthenticationHeaderValue("Basic", Convert.ToBase64String(paramBytes));
+ }
}
}
OpenUriAsync(MyCommon.TwitterUrl + tw.Username);
}
- private void doTranslation(string str)
+ private async Task doTranslation(string str)
{
- Bing _bing = new Bing();
- string buf = "";
- if (string.IsNullOrEmpty(str)) return;
- string srclng = "";
- string dstlng = SettingDialog.TranslateLanguage;
- string msg = "";
- if (srclng != dstlng && _bing.Translate("", dstlng, str, out buf))
+ if (string.IsNullOrEmpty(str))
+ return;
+
+ var bing = new Bing(this.http);
+ try
{
- PostBrowser.DocumentText = createDetailHtml(buf);
+ var translatedText = await bing.TranslateAsync(str,
+ langFrom: null,
+ langTo: this.SettingDialog.TranslateLanguage);
+
+ this.PostBrowser.DocumentText = translatedText;
}
- else
+ catch (HttpRequestException e)
{
- if (msg.StartsWith("Err:"))
- StatusLabel.Text = msg;
+ this.StatusLabel.Text = "Err:" + e.Message;
}
}
- private void TranslationToolStripMenuItem_Click(object sender, EventArgs e)
+ private async void TranslationToolStripMenuItem_Click(object sender, EventArgs e)
{
- if (!this.ExistCurrentPost) return;
- doTranslation(_curPost.TextFromApi);
+ if (!this.ExistCurrentPost)
+ return;
+
+ await this.doTranslation(this._curPost.TextFromApi);
}
- private void SelectionTranslationToolStripMenuItem_Click(object sender, EventArgs e)
+ private async void SelectionTranslationToolStripMenuItem_Click(object sender, EventArgs e)
{
- doTranslation(WebBrowser_GetSelectionText(ref PostBrowser));
+ var text = this.WebBrowser_GetSelectionText(ref this.PostBrowser);
+ await this.doTranslation(text);
}
private bool ExistCurrentPost