OSDN Git Service

using var を使用する
[opentween/open-tween.git] / OpenTween.Tests / Api / MicrosoftTranslatorApiTest.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2016 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
4 //
5 // This file is part of OpenTween.
6 //
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)
10 // any later version.
11 //
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
15 // for more details.
16 //
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.
21
22 using System;
23 using System.Linq;
24 using System.Net;
25 using System.Net.Http;
26 using System.Runtime.Serialization.Json;
27 using System.Threading.Tasks;
28 using System.Web;
29 using System.Xml;
30 using System.Xml.Linq;
31 using System.Xml.XPath;
32 using Moq;
33 using Xunit;
34
35 namespace OpenTween.Api
36 {
37     public class MicrosoftTranslatorApiTest
38     {
39         [Fact]
40         public async Task TranslateAsync_Test()
41         {
42             using var mockHandler = new HttpMessageHandlerMock();
43             using var http = new HttpClient(mockHandler);
44
45             var mock = new Mock<MicrosoftTranslatorApi>(http);
46             mock.Setup(x => x.GetAccessTokenAsync())
47                 .ReturnsAsync(("1234abcd", TimeSpan.FromSeconds(1000)));
48
49             var translateApi = mock.Object;
50
51             mockHandler.Enqueue(async x =>
52             {
53                 Assert.Equal(HttpMethod.Post, x.Method);
54                 Assert.Equal(MicrosoftTranslatorApi.TranslateEndpoint.AbsoluteUri,
55                     x.RequestUri.GetLeftPart(UriPartial.Path));
56
57                 var query = HttpUtility.ParseQueryString(x.RequestUri.Query);
58
59                 Assert.Equal("3.0", query["api-version"]);
60                 Assert.Equal("ja", query["to"]);
61                 Assert.Equal("en", query["from"]);
62
63                 var requestBody = await x.Content.ReadAsByteArrayAsync()
64                     .ConfigureAwait(false);
65
66                 using (var jsonReader = JsonReaderWriterFactory.CreateJsonReader(requestBody, XmlDictionaryReaderQuotas.Max))
67                 {
68                     var xElm = XElement.Load(jsonReader);
69
70                     var textElm = xElm.XPathSelectElement("/item/Text");
71                     Assert.Equal("hogehoge", textElm.Value);
72                 }
73
74                 return new HttpResponseMessage(HttpStatusCode.OK)
75                 {
76                     Content = new StringContent(@"[
77     {
78         ""translations"": [
79             {
80                 ""text"": ""ほげほげ"",
81                 ""to"": ""ja""
82             }
83         ]
84     }
85 ]"),
86                 };
87             });
88
89             var result = await translateApi.TranslateAsync("hogehoge", langTo: "ja", langFrom: "en")
90                 .ConfigureAwait(false);
91             Assert.Equal("ほげほげ", result);
92
93             mock.Verify(x => x.GetAccessTokenAsync(), Times.Once());
94             Assert.Equal(0, mockHandler.QueueCount);
95         }
96
97         [Fact]
98         public async Task UpdateAccessTokenIfExpired_FirstCallTest()
99         {
100             var mock = new Mock<MicrosoftTranslatorApi>();
101             mock.Setup(x => x.GetAccessTokenAsync())
102                 .ReturnsAsync(("1234abcd", TimeSpan.FromSeconds(1000)));
103
104             var translateApi = mock.Object;
105
106             await translateApi.UpdateAccessTokenIfExpired()
107                 .ConfigureAwait(false);
108
109             Assert.Equal("1234abcd", translateApi.AccessToken);
110
111             // 期待値との差が 3 秒以内であるか
112             var expectedExpiresAt = DateTimeUtc.Now + TimeSpan.FromSeconds(1000 - 30);
113             Assert.True((translateApi.RefreshAccessTokenAt - expectedExpiresAt).Duration() < TimeSpan.FromSeconds(3));
114         }
115
116         [Fact]
117         public async Task UpdateAccessTokenIfExpired_NotExpiredTest()
118         {
119             var mock = new Mock<MicrosoftTranslatorApi>();
120
121             var translateApi = mock.Object;
122             translateApi.AccessToken = "1234abcd";
123             translateApi.RefreshAccessTokenAt = DateTimeUtc.Now + TimeSpan.FromMinutes(3);
124
125             await translateApi.UpdateAccessTokenIfExpired()
126                 .ConfigureAwait(false);
127
128             // RefreshAccessTokenAt の時刻を過ぎるまでは GetAccessTokenAsync は呼ばれない
129             mock.Verify(x => x.GetAccessTokenAsync(), Times.Never());
130         }
131
132         [Fact]
133         public async Task UpdateAccessTokenIfExpired_ExpiredTest()
134         {
135             var mock = new Mock<MicrosoftTranslatorApi>();
136             mock.Setup(x => x.GetAccessTokenAsync())
137                 .ReturnsAsync(("5678efgh", TimeSpan.FromSeconds(1000)));
138
139             var translateApi = mock.Object;
140             translateApi.AccessToken = "1234abcd";
141             translateApi.RefreshAccessTokenAt = DateTimeUtc.Now - TimeSpan.FromMinutes(3);
142
143             await translateApi.UpdateAccessTokenIfExpired()
144                 .ConfigureAwait(false);
145
146             Assert.Equal("5678efgh", translateApi.AccessToken);
147
148             // 期待値との差が 3 秒以内であるか
149             var expectedExpiresAt = DateTimeUtc.Now + TimeSpan.FromSeconds(1000 - 30);
150             Assert.True((translateApi.RefreshAccessTokenAt - expectedExpiresAt).Duration() < TimeSpan.FromSeconds(3));
151         }
152
153         [Fact]
154         public async Task GetAccessTokenAsync_Test()
155         {
156             using var mockHandler = new HttpMessageHandlerMock();
157             using var http = new HttpClient(mockHandler);
158             var translateApi = new MicrosoftTranslatorApi(http);
159
160             mockHandler.Enqueue(x =>
161             {
162                 Assert.Equal(HttpMethod.Post, x.Method);
163                 Assert.Equal(MicrosoftTranslatorApi.IssueTokenEndpoint, x.RequestUri);
164
165                 var keyHeader = x.Headers.First(y => y.Key == "Ocp-Apim-Subscription-Key");
166                 Assert.Equal(ApplicationSettings.TranslatorSubscriptionKey, keyHeader.Value.Single());
167
168                 return new HttpResponseMessage(HttpStatusCode.OK)
169                 {
170                     Content = new StringContent(@"ACCESS_TOKEN"),
171                 };
172             });
173
174             var result = await translateApi.GetAccessTokenAsync()
175                 .ConfigureAwait(false);
176
177             var expectedToken = (@"ACCESS_TOKEN", TimeSpan.FromMinutes(10));
178             Assert.Equal(expectedToken, result);
179
180             Assert.Equal(0, mockHandler.QueueCount);
181         }
182     }
183 }