1 // OpenTween - Client of Twitter
2 // Copyright (c) 2013 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;
25 using System.Net.Http;
28 using OpenTween.Api.DataModel;
30 using Xunit.Extensions;
32 namespace OpenTween.Api
34 public class TwitterApiStatusTest
37 public void ResetTest()
39 var apiStatus = new TwitterApiStatus();
41 apiStatus.AccessLimit["/statuses/home_timeline"] = new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0));
42 apiStatus.MediaUploadLimit = new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0));
43 apiStatus.AccessLevel = TwitterApiAccessLevel.ReadWriteAndDirectMessage;
47 Assert.Null(apiStatus.AccessLimit["/statuses/home_timeline"]);
48 Assert.Null(apiStatus.MediaUploadLimit);
49 Assert.Equal(TwitterApiAccessLevel.Anonymous, apiStatus.AccessLevel);
52 public static IEnumerable<object[]> ParseRateLimit_TestCase
56 yield return new object[] {
57 new Dictionary<string, string> {
58 ["X-RateLimit-Limit"] = "150",
59 ["X-RateLimit-Remaining"] = "100",
60 ["X-RateLimit-Reset"] = "1356998400",
62 new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)),
64 yield return new object[] {
65 new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
66 ["x-ratelimit-limit"] = "150",
67 ["x-ratelimit-remaining"] = "100",
68 ["x-ratelimit-reset"] = "1356998400",
70 new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)),
72 yield return new object[] {
73 new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
74 ["X-RateLimit-Limit"] = "150",
75 ["X-RateLimit-Remaining"] = "100",
76 ["X-RateLimit-Reset"] = "hogehoge",
80 yield return new object[] {
81 new Dictionary<string, string> {
82 ["X-RateLimit-Limit"] = "150",
83 ["X-RateLimit-Remaining"] = "100",
91 [MemberData(nameof(ParseRateLimit_TestCase))]
92 public void ParseRateLimitTest(IDictionary<string, string> header, ApiLimit expected)
94 var limit = TwitterApiStatus.ParseRateLimit(header, "X-RateLimit-");
95 Assert.Equal(expected, limit);
98 public static IEnumerable<object[]> ParseMediaRateLimit_TestCase
102 yield return new object[] {
103 new Dictionary<string, string> {
104 ["X-MediaRateLimit-Limit"] = "30",
105 ["X-MediaRateLimit-Remaining"] = "20",
106 ["X-MediaRateLimit-Reset"] = "1234567890",
108 new ApiLimit(30, 20, new DateTimeUtc(2009, 2, 13, 23, 31, 30)),
110 yield return new object[] {
111 new Dictionary<string, string> {
112 ["X-MediaRateLimit-Limit"] = "30",
113 ["X-MediaRateLimit-Remaining"] = "20",
114 ["X-MediaRateLimit-Reset"] = "hogehoge",
118 yield return new object[] {
119 new Dictionary<string, string> {
120 ["X-MediaRateLimit-Limit"] = "30",
121 ["X-MediaRateLimit-Remaining"] = "20",
129 [MemberData(nameof(ParseMediaRateLimit_TestCase))]
130 public void ParseMediaRateLimitTest(IDictionary<string, string> header, ApiLimit expected)
132 var limit = TwitterApiStatus.ParseRateLimit(header, "X-MediaRateLimit-");
133 Assert.Equal(expected, limit);
136 public static IEnumerable<object[]> ParseAccessLevel_TestCase
140 yield return new object[] {
141 new Dictionary<string, string> { {"X-Access-Level", "read"} },
142 TwitterApiAccessLevel.Read,
144 yield return new object[] {
145 new Dictionary<string, string> { {"X-Access-Level", "read-write"} },
146 TwitterApiAccessLevel.ReadWrite,
148 yield return new object[] {
149 new Dictionary<string, string> { {"X-Access-Level", "read-write-directmessages"} },
150 TwitterApiAccessLevel.ReadWriteAndDirectMessage,
152 yield return new object[] {
153 new Dictionary<string, string> { {"X-Access-Level", ""} }, // 何故かたまに出てくるやつ
156 yield return new object[] {
157 new Dictionary<string, string> { },
164 [MemberData(nameof(ParseAccessLevel_TestCase))]
165 public void ParseAccessLevelTest(IDictionary<string, string> header, TwitterApiAccessLevel? expected)
167 var accessLevel = TwitterApiStatus.ParseAccessLevel(header, "X-Access-Level");
168 Assert.Equal(expected, accessLevel);
172 public void UpdateFromHeader_DictionaryTest()
174 var status = new TwitterApiStatus();
176 var header = new Dictionary<string, string>
178 ["X-Rate-Limit-Limit"] = "150",
179 ["X-Rate-Limit-Remaining"] = "100",
180 ["X-Rate-Limit-Reset"] = "1356998400",
181 ["X-MediaRateLimit-Limit"] = "30",
182 ["X-MediaRateLimit-Remaining"] = "20",
183 ["X-MediaRateLimit-Reset"] = "1357084800",
184 ["X-Access-Level"] = "read-write-directmessages",
187 Assert.Raises<TwitterApiStatus.AccessLimitUpdatedEventArgs>(
188 x => status.AccessLimitUpdated += x,
189 x => status.AccessLimitUpdated -= x,
190 () => status.UpdateFromHeader(header, "/statuses/home_timeline")
193 var rateLimit = status.AccessLimit["/statuses/home_timeline"];
194 Assert.Equal(150, rateLimit.AccessLimitCount);
195 Assert.Equal(100, rateLimit.AccessLimitRemain);
196 Assert.Equal(new DateTimeUtc(2013, 1, 1, 0, 0, 0), rateLimit.AccessLimitResetDate);
198 var mediaLimit = status.MediaUploadLimit;
199 Assert.Equal(30, mediaLimit.AccessLimitCount);
200 Assert.Equal(20, mediaLimit.AccessLimitRemain);
201 Assert.Equal(new DateTimeUtc(2013, 1, 2, 0, 0, 0), mediaLimit.AccessLimitResetDate);
203 Assert.Equal(TwitterApiAccessLevel.ReadWriteAndDirectMessage, status.AccessLevel);
207 public void UpdateFromHeader_HttpClientTest()
209 var status = new TwitterApiStatus();
211 var response = new HttpResponseMessage
215 { "x-rate-limit-limit", "150" },
216 { "x-rate-limit-remaining", "100" },
217 { "x-rate-limit-reset", "1356998400" },
218 { "x-mediaratelimit-limit", "30" },
219 { "x-mediaratelimit-remaining", "20" },
220 { "x-mediaratelimit-reset", "1357084800" },
221 { "x-access-level", "read-write-directmessages" },
225 Assert.Raises<TwitterApiStatus.AccessLimitUpdatedEventArgs>(
226 x => status.AccessLimitUpdated += x,
227 x => status.AccessLimitUpdated -= x,
228 () => status.UpdateFromHeader(response.Headers, "/statuses/home_timeline")
231 var rateLimit = status.AccessLimit["/statuses/home_timeline"];
232 Assert.Equal(150, rateLimit.AccessLimitCount);
233 Assert.Equal(100, rateLimit.AccessLimitRemain);
234 Assert.Equal(new DateTimeUtc(2013, 1, 1, 0, 0, 0), rateLimit.AccessLimitResetDate);
236 var mediaLimit = status.MediaUploadLimit;
237 Assert.Equal(30, mediaLimit.AccessLimitCount);
238 Assert.Equal(20, mediaLimit.AccessLimitRemain);
239 Assert.Equal(new DateTimeUtc(2013, 1, 2, 0, 0, 0), mediaLimit.AccessLimitResetDate);
241 Assert.Equal(TwitterApiAccessLevel.ReadWriteAndDirectMessage, status.AccessLevel);
245 public void UpdateFromJsonTest()
247 var status = new TwitterApiStatus();
249 var json = "{\"resources\":{\"statuses\":{\"/statuses/home_timeline\":{\"limit\":150,\"remaining\":100,\"reset\":1356998400}}}}";
251 Assert.Raises<TwitterApiStatus.AccessLimitUpdatedEventArgs>(
252 x => status.AccessLimitUpdated += x,
253 x => status.AccessLimitUpdated -= x,
254 () => status.UpdateFromJson(TwitterRateLimits.ParseJson(json))
257 var rateLimit = status.AccessLimit["/statuses/home_timeline"];
258 Assert.Equal(150, rateLimit.AccessLimitCount);
259 Assert.Equal(100, rateLimit.AccessLimitRemain);
260 Assert.Equal(new DateTimeUtc(2013, 1, 1, 0, 0, 0), rateLimit.AccessLimitResetDate);
264 public void AccessLimitUpdatedTest()
266 var apiStatus = new TwitterApiStatus();
268 Assert.Raises<TwitterApiStatus.AccessLimitUpdatedEventArgs>(
269 x => apiStatus.AccessLimitUpdated += x,
270 x => apiStatus.AccessLimitUpdated -= x,
271 () => apiStatus.AccessLimit["/statuses/home_timeline"] = new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0))
274 Assert.Raises<TwitterApiStatus.AccessLimitUpdatedEventArgs>(
275 x => apiStatus.AccessLimitUpdated += x,
276 x => apiStatus.AccessLimitUpdated -= x,
277 () => apiStatus.Reset()