using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Http;
using System.Text;
using System.Xml;
using OpenTween.Api.DataModel;
}
[Fact]
- public void UpdateFromHeaderTest()
+ public void UpdateFromHeader_DictionaryTest()
{
var status = new TwitterApiStatus();
Assert.True(eventCalled);
}
+ [Fact]
+ public void UpdateFromHeader_HttpClientTest()
+ {
+ var status = new TwitterApiStatus();
+
+ var eventCalled = false;
+ status.AccessLimitUpdated += (s, e) => eventCalled = true;
+
+ var response = new HttpResponseMessage
+ {
+ Headers =
+ {
+ { "X-Rate-Limit-Limit", "150" },
+ { "X-Rate-Limit-Remaining", "100" },
+ { "X-Rate-Limit-Reset", "1356998400" },
+ { "X-MediaRateLimit-Limit", "30" },
+ { "X-MediaRateLimit-Remaining", "20" },
+ { "X-MediaRateLimit-Reset", "1357084800" },
+ { "X-Access-Level", "read-write-directmessages" },
+ },
+ };
+
+ status.UpdateFromHeader(response.Headers, "/statuses/home_timeline");
+
+ var rateLimit = status.AccessLimit["/statuses/home_timeline"];
+ Assert.Equal(150, rateLimit.AccessLimitCount);
+ Assert.Equal(100, rateLimit.AccessLimitRemain);
+ Assert.Equal(new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime(), rateLimit.AccessLimitResetDate);
+
+ var mediaLimit = status.MediaUploadLimit;
+ Assert.Equal(30, mediaLimit.AccessLimitCount);
+ Assert.Equal(20, mediaLimit.AccessLimitRemain);
+ Assert.Equal(new DateTime(2013, 1, 2, 0, 0, 0, DateTimeKind.Utc).ToLocalTime(), mediaLimit.AccessLimitResetDate);
+
+ Assert.Equal(TwitterApiAccessLevel.ReadWriteAndDirectMessage, status.AccessLevel);
+
+ Assert.True(eventCalled);
+ }
+
[Fact(Skip = "Mono環境でエラーが発生する")]
public void UpdateFromJsonTest()
{
mock.Setup(x =>
x.GetAsync<TwitterStatus>(
new Uri("statuses/show.json", UriKind.Relative),
- new Dictionary<string, string> { { "id", "100" }, { "include_entities", "true" } })
+ new Dictionary<string, string> { { "id", "100" }, { "include_entities", "true" } },
+ "/statuses/show/:id")
)
.ReturnsAsync(new TwitterStatus { Id = 100L });
mock.Setup(x =>
x.GetAsync<TwitterUser>(
new Uri("users/show.json", UriKind.Relative),
- new Dictionary<string, string> { { "screen_name", "twitterapi" }, { "include_entities", "true" } })
+ new Dictionary<string, string> { { "screen_name", "twitterapi" }, { "include_entities", "true" } },
+ "/users/show/:id")
)
.ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
mock.Setup(x =>
x.GetAsync<TwitterFriendship>(
new Uri("friendships/show.json", UriKind.Relative),
- new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } })
+ new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } },
+ "/friendships/show")
)
.ReturnsAsync(new TwitterFriendship());
}
[Fact]
+ public async Task GetAsync_UpdateRateLimitTest()
+ {
+ using (var mockHandler = new HttpMessageHandlerMock())
+ using (var http = new HttpClient(mockHandler))
+ using (var apiConnection = new TwitterApiConnection("", ""))
+ {
+ apiConnection.http = http;
+
+ mockHandler.Enqueue(x =>
+ {
+ Assert.Equal(HttpMethod.Get, x.Method);
+ Assert.Equal("https://api.twitter.com/1.1/hoge/tetete.json",
+ x.RequestUri.GetLeftPart(UriPartial.Path));
+
+ return new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Headers =
+ {
+ { "X-Rate-Limit-Limit", "150" },
+ { "X-Rate-Limit-Remaining", "100" },
+ { "X-Rate-Limit-Reset", "1356998400" },
+ { "X-Access-Level", "read-write-directmessages" },
+ },
+ Content = new StringContent("\"hogehoge\""),
+ };
+ });
+
+ var apiStatus = new TwitterApiStatus();
+ MyCommon.TwitterApiInfo = apiStatus;
+
+ var endpoint = new Uri("hoge/tetete.json", UriKind.Relative);
+
+ await apiConnection.GetAsync<string>(endpoint, null, endpointName: "/hoge/tetete")
+ .ConfigureAwait(false);
+
+ Assert.Equal(apiStatus.AccessLevel, TwitterApiAccessLevel.ReadWriteAndDirectMessage);
+ Assert.Equal(apiStatus.AccessLimit["/hoge/tetete"], new ApiLimit(150, 100, new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime()));
+
+ Assert.Equal(0, mockHandler.QueueCount);
+ }
+ }
+
+ [Fact]
public async Task GetAsync_ErrorStatusTest()
{
using (var mockHandler = new HttpMessageHandlerMock())
["include_entities"] = "true",
};
- return this.apiConnection.GetAsync<TwitterStatus>(endpoint, param);
+ return this.apiConnection.GetAsync<TwitterStatus>(endpoint, param, "/statuses/show/:id");
}
public Task<LazyJson<TwitterStatus>> StatusesDestroy(long statusId)
["include_entities"] = "true",
};
- return this.apiConnection.GetAsync<TwitterUser>(endpoint, param);
+ return this.apiConnection.GetAsync<TwitterUser>(endpoint, param, "/users/show/:id");
}
public Task<LazyJson<TwitterUser>> UsersReportSpam(string screenName)
["target_screen_name"] = targetScreenName,
};
- return this.apiConnection.GetAsync<TwitterFriendship>(endpoint, param);
+ return this.apiConnection.GetAsync<TwitterFriendship>(endpoint, param, "/friendships/show");
}
public Task<LazyJson<TwitterFriendship>> FriendshipsCreate(string screenName)
using System.Xml.Linq;
using System.Xml.XPath;
using OpenTween.Api.DataModel;
+using System.Net.Http.Headers;
namespace OpenTween.Api
{
}
return null;
- }
+ }
+
+ public void UpdateFromHeader(HttpResponseHeaders header, string endpointName)
+ {
+ this.UpdateFromHeader(header.ToDictionary(x => x.Key, x => string.Join(",", x.Value)), endpointName);
+ }
public void UpdateFromHeader(IDictionary<string, string> header, string endpointName)
{
public interface IApiConnection : IDisposable
{
Task<T> GetAsync<T>(Uri uri, IDictionary<string, string> param);
+ Task<T> GetAsync<T>(Uri uri, IDictionary<string, string> param, string endpointName);
Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string> param);
Networking.WebProxyChanged += this.Networking_WebProxyChanged;
}
- public async Task<T> GetAsync<T>(Uri uri, IDictionary<string, string> param)
+ public Task<T> GetAsync<T>(Uri uri, IDictionary<string, string> param)
+ => this.GetAsync<T>(uri, param, null);
+
+ public async Task<T> GetAsync<T>(Uri uri, IDictionary<string, string> param, string endpointName)
{
var requestUri = new Uri(this.RestApiBase, uri);
await this.CheckStatusCode(response)
.ConfigureAwait(false);
+ if (endpointName != null)
+ MyCommon.TwitterApiInfo.UpdateFromHeader(response.Headers, endpointName);
+
using (var content = response.Content)
{
var responseText = await content.ReadAsStringAsync()