1 // OpenTween - Client of Twitter
2 // Copyright (c) 2014 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.
23 using System.Collections.Generic;
24 using System.Globalization;
27 using System.Net.Http;
28 using System.Reflection;
29 using System.Runtime.InteropServices;
31 using System.Threading;
32 using System.Threading.Tasks;
35 using OpenTween.Models;
37 using Xunit.Extensions;
39 namespace OpenTween.Thumbnail.Services
41 public class FoursquareCheckinTest
44 public void UrlPattern_Test()
46 // 通常のチェックイン URL (www.swarmapp.com/c/***)
47 var match = FoursquareCheckin.UrlPatternRegex.Match("https://www.swarmapp.com/c/xxxxxxxx");
48 Assert.True(match.Success);
49 Assert.Equal("xxxxxxxx", match.Groups["checkin_id"].Value);
53 public void LegacyUrlPattern_Test()
55 // 古い形式の URL (foursquare.com/***/checkin/***?s=***)
56 var match = FoursquareCheckin.LegacyUrlPatternRegex.Match("https://foursquare.com/hogehoge/checkin/xxxxxxxx?s=aaaaaaa");
57 Assert.True(match.Success);
58 Assert.Equal("xxxxxxxx", match.Groups["checkin_id"].Value);
59 Assert.Equal("aaaaaaa", match.Groups["signature"].Value);
61 // 古い形式の URL (www.swarmapp.com/***/checkin/***?s=***)
62 match = FoursquareCheckin.LegacyUrlPatternRegex.Match("https://www.swarmapp.com/hogehoge/checkin/xxxxxxxx?s=aaaaaaa");
63 Assert.True(match.Success);
64 Assert.Equal("xxxxxxxx", match.Groups["checkin_id"].Value);
65 Assert.Equal("aaaaaaa", match.Groups["signature"].Value);
69 public async Task GetThumbnailInfoAsync_NewUrlTest()
71 var handler = new HttpMessageHandlerMock();
72 using (var http = new HttpClient(handler))
74 var service = new FoursquareCheckin(http);
78 Assert.Equal(HttpMethod.Get, x.Method);
79 Assert.Equal("https://api.foursquare.com/v2/checkins/resolve",
80 x.RequestUri.GetLeftPart(UriPartial.Path));
82 var query = HttpUtility.ParseQueryString(x.RequestUri.Query);
84 Assert.Equal(ApplicationSettings.FoursquareClientId, query["client_id"]);
85 Assert.Equal(ApplicationSettings.FoursquareClientSecret, query["client_secret"]);
86 Assert.NotNull(query["v"]);
87 Assert.Equal("xxxxxxxx", query["shortId"]);
89 // リクエストに対するテストなのでレスポンスは適当に返す
90 return new HttpResponseMessage(HttpStatusCode.NotFound);
93 var post = new PostClass
98 await service.GetThumbnailInfoAsync(
99 "https://www.swarmapp.com/c/xxxxxxxx",
100 post, CancellationToken.None);
102 Assert.Equal(0, handler.QueueCount);
107 public async Task GetThumbnailInfoAsync_LegacyUrlTest()
109 var handler = new HttpMessageHandlerMock();
110 using (var http = new HttpClient(handler))
112 var service = new FoursquareCheckin(http);
116 Assert.Equal(HttpMethod.Get, x.Method);
117 Assert.Equal("https://api.foursquare.com/v2/checkins/xxxxxxxx",
118 x.RequestUri.GetLeftPart(UriPartial.Path));
120 var query = HttpUtility.ParseQueryString(x.RequestUri.Query);
122 Assert.Equal(ApplicationSettings.FoursquareClientId, query["client_id"]);
123 Assert.Equal(ApplicationSettings.FoursquareClientSecret, query["client_secret"]);
124 Assert.NotNull(query["v"]);
125 Assert.Null(query["signature"]);
127 // リクエストに対するテストなのでレスポンスは適当に返す
128 return new HttpResponseMessage(HttpStatusCode.NotFound);
131 var post = new PostClass
136 await service.GetThumbnailInfoAsync(
137 "https://foursquare.com/hogehoge/checkin/xxxxxxxx",
138 post, CancellationToken.None);
140 Assert.Equal(0, handler.QueueCount);
145 public async Task GetThumbnailInfoAsync_LegacyUrlWithSignatureTest()
147 var handler = new HttpMessageHandlerMock();
148 using (var http = new HttpClient(handler))
150 var service = new FoursquareCheckin(http);
154 Assert.Equal(HttpMethod.Get, x.Method);
155 Assert.Equal("https://api.foursquare.com/v2/checkins/xxxxxxxx",
156 x.RequestUri.GetLeftPart(UriPartial.Path));
158 var query = HttpUtility.ParseQueryString(x.RequestUri.Query);
160 Assert.Equal(ApplicationSettings.FoursquareClientId, query["client_id"]);
161 Assert.Equal(ApplicationSettings.FoursquareClientSecret, query["client_secret"]);
162 Assert.NotNull(query["v"]);
163 Assert.Equal("aaaaaaa", query["signature"]);
165 // リクエストに対するテストなのでレスポンスは適当に返す
166 return new HttpResponseMessage(HttpStatusCode.NotFound);
169 var post = new PostClass
174 await service.GetThumbnailInfoAsync(
175 "https://foursquare.com/hogehoge/checkin/xxxxxxxx?s=aaaaaaa",
176 post, CancellationToken.None);
178 Assert.Equal(0, handler.QueueCount);
183 public async Task GetThumbnailInfoAsync_GeoLocatedTweetTest()
185 var handler = new HttpMessageHandlerMock();
186 using (var http = new HttpClient(handler))
188 var service = new FoursquareCheckin(http);
194 return new HttpResponseMessage(HttpStatusCode.NotFound);
197 // 既にジオタグが付いているツイートに対しては何もしない
198 var post = new PostClass
200 PostGeo = new PostClass.StatusGeo(134.04693603515625, 34.35067978344854),
203 await service.GetThumbnailInfoAsync(
204 "https://www.swarmapp.com/c/xxxxxxxx",
205 post, CancellationToken.None);
207 Assert.Equal(1, handler.QueueCount);
212 public void ParseInLocation_Test()
215 ""meta"": { ""code"": 200 },
218 ""id"": ""xxxxxxxxx"",
219 ""type"": ""checkin"",
221 ""id"": ""4b73dedcf964a5206bbe2de3"",
222 ""name"": ""高松駅 (Takamatsu Sta.)"",
224 ""lat"": 34.35067978344854,
225 ""lng"": 134.04693603515625
231 var jsonBytes = Encoding.UTF8.GetBytes(json);
232 var location = FoursquareCheckin.ParseIntoLocation(jsonBytes);
234 Assert.NotNull(location);
235 Assert.Equal(34.35067978344854, location!.Latitude);
236 Assert.Equal(134.04693603515625, location.Longitude);
240 public void ParseInLocation_CultureTest()
243 ""meta"": { ""code"": 200 },
246 ""id"": ""xxxxxxxxx"",
247 ""type"": ""checkin"",
249 ""id"": ""4b73dedcf964a5206bbe2de3"",
250 ""name"": ""高松駅 (Takamatsu Sta.)"",
252 ""lat"": 34.35067978344854,
253 ""lng"": 134.04693603515625
259 var origCulture = Thread.CurrentThread.CurrentCulture;
260 Thread.CurrentThread.CurrentCulture = new CultureInfo("ru-RU");
262 var jsonBytes = Encoding.UTF8.GetBytes(json);
263 var location = FoursquareCheckin.ParseIntoLocation(jsonBytes);
265 Thread.CurrentThread.CurrentCulture = origCulture;
267 Assert.NotNull(location);
268 Assert.Equal(34.35067978344854, location!.Latitude);
269 Assert.Equal(134.04693603515625, location.Longitude);
273 public void ParseInLocation_PlanetTest()
276 ""meta"": { ""code"": 200 },
279 ""id"": ""xxxxxxxxx"",
280 ""type"": ""checkin"",
282 ""id"": ""5069d8bdc640385aa7711fe4"",
283 ""name"": ""Gale Crater"",
285 ""planet"": ""mars"",
293 var jsonBytes = Encoding.UTF8.GetBytes(json);
294 var location = FoursquareCheckin.ParseIntoLocation(jsonBytes);
296 // 地球以外の位置にあるベニューに対しては null を返す
297 Assert.Null(location);
301 public void ParseInLocation_VenueNullTest()
304 ""meta"": { ""code"": 200 },
307 ""id"": ""xxxxxxxxx"",
308 ""type"": ""checkin"",
313 var jsonBytes = Encoding.UTF8.GetBytes(json);
314 var location = FoursquareCheckin.ParseIntoLocation(jsonBytes);
316 // ベニュー情報が得られなかった場合は null を返す
317 Assert.Null(location);