1 // OpenTween - Client of Twitter
2 // Copyright (c) 2016 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
5 // This file is part of OpenTween.
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 // You should have received a copy of the GNU General Public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
25 using System.Net.Http;
26 using System.Runtime.Serialization.Json;
27 using System.Threading.Tasks;
30 using System.Xml.Linq;
31 using System.Xml.XPath;
35 namespace OpenTween.Api
37 public class MicrosoftTranslatorApiTest
40 public async Task TranslateAsync_Test()
42 using var mockHandler = new HttpMessageHandlerMock();
43 using var http = new HttpClient(mockHandler);
45 var mock = new Mock<MicrosoftTranslatorApi>(http);
46 mock.Setup(x => x.GetAccessTokenAsync())
47 .ReturnsAsync(("1234abcd", TimeSpan.FromSeconds(1000)));
49 var translateApi = mock.Object;
51 mockHandler.Enqueue(async x =>
53 Assert.Equal(HttpMethod.Post, x.Method);
54 Assert.Equal(MicrosoftTranslatorApi.TranslateEndpoint.AbsoluteUri,
55 x.RequestUri.GetLeftPart(UriPartial.Path));
57 var query = HttpUtility.ParseQueryString(x.RequestUri.Query);
59 Assert.Equal("3.0", query["api-version"]);
60 Assert.Equal("ja", query["to"]);
61 Assert.Equal("en", query["from"]);
63 var requestBody = await x.Content.ReadAsByteArrayAsync()
64 .ConfigureAwait(false);
66 using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(requestBody, XmlDictionaryReaderQuotas.Max))
68 var xElm = XElement.Load(jsonReader);
70 var textElm = xElm.XPathSelectElement("/item/Text");
71 Assert.Equal("hogehoge", textElm.Value);
74 return new HttpResponseMessage(HttpStatusCode.OK)
76 Content = new StringContent(@"[
89 var result = await translateApi.TranslateAsync("hogehoge", langTo: "ja", langFrom: "en")
90 .ConfigureAwait(false);
91 Assert.Equal("ほげほげ", result);
93 mock.Verify(x => x.GetAccessTokenAsync(), Times.Once());
94 Assert.Equal(0, mockHandler.QueueCount);
98 public async Task UpdateAccessTokenIfExpired_FirstCallTest()
100 var mock = new Mock<MicrosoftTranslatorApi>();
101 mock.Setup(x => x.GetAccessTokenAsync())
102 .ReturnsAsync(("1234abcd", TimeSpan.FromSeconds(1000)));
104 var translateApi = mock.Object;
106 await translateApi.UpdateAccessTokenIfExpired()
107 .ConfigureAwait(false);
109 Assert.Equal("1234abcd", translateApi.AccessToken);
112 var expectedExpiresAt = DateTimeUtc.Now + TimeSpan.FromSeconds(1000 - 30);
113 Assert.True((translateApi.RefreshAccessTokenAt - expectedExpiresAt).Duration() < TimeSpan.FromSeconds(3));
117 public async Task UpdateAccessTokenIfExpired_NotExpiredTest()
119 var mock = new Mock<MicrosoftTranslatorApi>();
121 var translateApi = mock.Object;
122 translateApi.AccessToken = "1234abcd";
123 translateApi.RefreshAccessTokenAt = DateTimeUtc.Now + TimeSpan.FromMinutes(3);
125 await translateApi.UpdateAccessTokenIfExpired()
126 .ConfigureAwait(false);
128 // RefreshAccessTokenAt の時刻を過ぎるまでは GetAccessTokenAsync は呼ばれない
129 mock.Verify(x => x.GetAccessTokenAsync(), Times.Never());
133 public async Task UpdateAccessTokenIfExpired_ExpiredTest()
135 var mock = new Mock<MicrosoftTranslatorApi>();
136 mock.Setup(x => x.GetAccessTokenAsync())
137 .ReturnsAsync(("5678efgh", TimeSpan.FromSeconds(1000)));
139 var translateApi = mock.Object;
140 translateApi.AccessToken = "1234abcd";
141 translateApi.RefreshAccessTokenAt = DateTimeUtc.Now - TimeSpan.FromMinutes(3);
143 await translateApi.UpdateAccessTokenIfExpired()
144 .ConfigureAwait(false);
146 Assert.Equal("5678efgh", translateApi.AccessToken);
149 var expectedExpiresAt = DateTimeUtc.Now + TimeSpan.FromSeconds(1000 - 30);
150 Assert.True((translateApi.RefreshAccessTokenAt - expectedExpiresAt).Duration() < TimeSpan.FromSeconds(3));
154 public async Task GetAccessTokenAsync_Test()
156 using var mockHandler = new HttpMessageHandlerMock();
157 using var http = new HttpClient(mockHandler);
158 var translateApi = new MicrosoftTranslatorApi(http);
160 mockHandler.Enqueue(x =>
162 Assert.Equal(HttpMethod.Post, x.Method);
163 Assert.Equal(MicrosoftTranslatorApi.IssueTokenEndpoint, x.RequestUri);
165 var keyHeader = x.Headers.First(y => y.Key == "Ocp-Apim-Subscription-Key");
166 Assert.Equal(ApplicationSettings.TranslatorSubscriptionKey, keyHeader.Value.Single());
168 return new HttpResponseMessage(HttpStatusCode.OK)
170 Content = new StringContent(@"ACCESS_TOKEN"),
174 var result = await translateApi.GetAccessTokenAsync()
175 .ConfigureAwait(false);
177 var expectedToken = (@"ACCESS_TOKEN", TimeSpan.FromMinutes(10));
178 Assert.Equal(expectedToken, result);
180 Assert.Equal(0, mockHandler.QueueCount);