OSDN Git Service

IApiConnectionLegacy.GetAsyncを使用している箇所をGetRequestに移行
authorKimura Youichi <kim.upsilon@bucyou.net>
Tue, 12 Dec 2023 17:38:24 +0000 (02:38 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Tue, 12 Dec 2023 17:51:29 +0000 (02:51 +0900)
OpenTween.Tests/Api/TwitterApiTest.cs
OpenTween.Tests/Api/TwitterV2/GetTimelineRequestTest.cs
OpenTween/Api/TwitterApi.cs
OpenTween/Api/TwitterV2/GetTimelineRequest.cs

index 9266c60..f19ca84 100644 (file)
@@ -81,6 +81,10 @@ namespace OpenTween.Api
 
         private Mock<IApiConnectionLegacy> CreateApiConnectionMock<T>(Action<T> verifyRequest)
             where T : IHttpRequest
+            => this.CreateApiConnectionMock(verifyRequest, "");
+
+        private Mock<IApiConnectionLegacy> CreateApiConnectionMock<T>(Action<T> verifyRequest, string responseText)
+            where T : IHttpRequest
         {
             Func<T, bool> verifyRequestWrapper = r =>
             {
@@ -89,7 +93,10 @@ namespace OpenTween.Api
                 return true;
             };
 
-            var responseMessage = new HttpResponseMessage(HttpStatusCode.OK);
+            var responseMessage = new HttpResponseMessage(HttpStatusCode.OK)
+            {
+                Content = new StringContent(responseText),
+            };
             var mock = new Mock<IApiConnectionLegacy>();
             mock.Setup(x =>
                 x.SendAsync(
@@ -104,22 +111,24 @@ namespace OpenTween.Api
         [Fact]
         public async Task StatusesHomeTimeline_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterStatus[]>(
-                    new Uri("statuses/home_timeline.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("statuses/home_timeline.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                            { "count", "200" },
-                            { "max_id", "900" },
-                            { "since_id", "100" },
-                    },
-                    "/statuses/home_timeline")
-            )
-            .ReturnsAsync(Array.Empty<TwitterStatus>());
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                        ["count"] = "200",
+                        ["max_id"] = "900",
+                        ["since_id"] = "100",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/statuses/home_timeline", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(Array.Empty<TwitterStatus>())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -132,22 +141,24 @@ namespace OpenTween.Api
         [Fact]
         public async Task StatusesMentionsTimeline_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterStatus[]>(
-                    new Uri("statuses/mentions_timeline.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("statuses/mentions_timeline.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                            { "count", "200" },
-                            { "max_id", "900" },
-                            { "since_id", "100" },
-                    },
-                    "/statuses/mentions_timeline")
-            )
-            .ReturnsAsync(Array.Empty<TwitterStatus>());
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                        ["count"] = "200",
+                        ["max_id"] = "900",
+                        ["since_id"] = "100",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/statuses/mentions_timeline", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(Array.Empty<TwitterStatus>())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -160,24 +171,26 @@ namespace OpenTween.Api
         [Fact]
         public async Task StatusesUserTimeline_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterStatus[]>(
-                    new Uri("statuses/user_timeline.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("statuses/user_timeline.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "screen_name", "twitterapi" },
-                            { "include_rts", "true" },
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                            { "count", "200" },
-                            { "max_id", "900" },
-                            { "since_id", "100" },
-                    },
-                    "/statuses/user_timeline")
-            )
-            .ReturnsAsync(Array.Empty<TwitterStatus>());
+                        ["screen_name"] = "twitterapi",
+                        ["include_rts"] = "true",
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                        ["count"] = "200",
+                        ["max_id"] = "900",
+                        ["since_id"] = "100",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/statuses/user_timeline", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(Array.Empty<TwitterStatus>())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -190,20 +203,22 @@ namespace OpenTween.Api
         [Fact]
         public async Task StatusesShow_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterStatus>(
-                    new Uri("statuses/show.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("statuses/show.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "id", "100" },
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                    },
-                    "/statuses/show/:id")
-            )
-            .ReturnsAsync(new TwitterStatus { Id = 100L });
+                        ["id"] = "100",
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/statuses/show/:id", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterStatus())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -216,21 +231,22 @@ namespace OpenTween.Api
         [Fact]
         public async Task StatusesLookup_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterStatus[]>(
-                    new Uri("statuses/lookup.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("statuses/lookup.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                        { "id", "100,200" },
-                        { "include_entities", "true" },
-                        { "include_ext_alt_text", "true" },
-                        { "tweet_mode", "extended" },
-                    },
-                    "/statuses/lookup"
-                )
-            )
-            .ReturnsAsync(Array.Empty<TwitterStatus>());
+                        ["id"] = "100,200",
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/statuses/lookup", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(Array.Empty<TwitterStatus>())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -353,25 +369,27 @@ namespace OpenTween.Api
         [Fact]
         public async Task SearchTweets_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterSearchResult>(
-                    new Uri("search/tweets.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("search/tweets.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "q", "from:twitterapi" },
-                            { "result_type", "recent" },
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                            { "lang", "en" },
-                            { "count", "200" },
-                            { "max_id", "900" },
-                            { "since_id", "100" },
-                    },
-                    "/search/tweets")
-            )
-            .ReturnsAsync(new TwitterSearchResult());
+                        ["q"] = "from:twitterapi",
+                        ["result_type"] = "recent",
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                        ["lang"] = "en",
+                        ["count"] = "200",
+                        ["max_id"] = "900",
+                        ["since_id"] = "100",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/search/tweets", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterSearchResult())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -384,19 +402,21 @@ namespace OpenTween.Api
         [Fact]
         public async Task ListsOwnerships_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterLists>(
-                    new Uri("lists/ownerships.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("lists/ownerships.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "screen_name", "twitterapi" },
-                            { "cursor", "-1" },
-                            { "count", "100" },
-                    },
-                    "/lists/ownerships")
-            )
-            .ReturnsAsync(new TwitterLists());
+                        ["screen_name"] = "twitterapi",
+                        ["cursor"] = "-1",
+                        ["count"] = "100",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/lists/ownerships", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterLists())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -409,19 +429,21 @@ namespace OpenTween.Api
         [Fact]
         public async Task ListsSubscriptions_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterLists>(
-                    new Uri("lists/subscriptions.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("lists/subscriptions.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "screen_name", "twitterapi" },
-                            { "cursor", "-1" },
-                            { "count", "100" },
-                    },
-                    "/lists/subscriptions")
-            )
-            .ReturnsAsync(new TwitterLists());
+                        ["screen_name"] = "twitterapi",
+                        ["cursor"] = "-1",
+                        ["count"] = "100",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/lists/subscriptions", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterLists())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -434,20 +456,22 @@ namespace OpenTween.Api
         [Fact]
         public async Task ListsMemberships_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterLists>(
-                    new Uri("lists/memberships.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("lists/memberships.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "screen_name", "twitterapi" },
-                            { "cursor", "-1" },
-                            { "count", "100" },
-                            { "filter_to_owned_lists", "true" },
-                    },
-                    "/lists/memberships")
-            )
-            .ReturnsAsync(new TwitterLists());
+                        ["screen_name"] = "twitterapi",
+                        ["cursor"] = "-1",
+                        ["count"] = "100",
+                        ["filter_to_owned_lists"] = "true",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/lists/memberships", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterLists())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -531,24 +555,26 @@ namespace OpenTween.Api
         [Fact]
         public async Task ListsStatuses_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterStatus[]>(
-                    new Uri("lists/statuses.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("lists/statuses.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "list_id", "12345" },
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                            { "count", "200" },
-                            { "max_id", "900" },
-                            { "since_id", "100" },
-                            { "include_rts", "true" },
-                    },
-                    "/lists/statuses")
-            )
-            .ReturnsAsync(Array.Empty<TwitterStatus>());
+                        ["list_id"] = "12345",
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                        ["count"] = "200",
+                        ["max_id"] = "900",
+                        ["since_id"] = "100",
+                        ["include_rts"] = "true",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/lists/statuses", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(Array.Empty<TwitterStatus>())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -561,21 +587,23 @@ namespace OpenTween.Api
         [Fact]
         public async Task ListsMembers_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterUsers>(
-                    new Uri("lists/members.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("lists/members.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "list_id", "12345" },
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                            { "cursor", "-1" },
-                    },
-                    "/lists/members")
-            )
-            .ReturnsAsync(new TwitterUsers());
+                        ["list_id"] = "12345",
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                        ["cursor"] = "-1",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/lists/members", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(Array.Empty<TwitterUser>())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -588,21 +616,23 @@ namespace OpenTween.Api
         [Fact]
         public async Task ListsMembersShow_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterUser>(
-                    new Uri("lists/members/show.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("lists/members/show.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "list_id", "12345" },
-                            { "screen_name", "twitterapi" },
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                    },
-                    "/lists/members/show")
-            )
-            .ReturnsAsync(new TwitterUser());
+                        ["list_id"] = "12345",
+                        ["screen_name"] = "twitterapi",
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/lists/members/show", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterUser())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -667,18 +697,20 @@ namespace OpenTween.Api
         [Fact]
         public async Task DirectMessagesEventsList_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterMessageEventList>(
-                    new Uri("direct_messages/events/list.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("direct_messages/events/list.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "count", "50" },
-                            { "cursor", "12345abcdefg" },
-                    },
-                    "/direct_messages/events/list")
-            )
-            .ReturnsAsync(new TwitterMessageEventList());
+                        ["count"] = "50",
+                        ["cursor"] = "12345abcdefg",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/direct_messages/events/list", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterMessageEventList())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -751,20 +783,22 @@ namespace OpenTween.Api
         [Fact]
         public async Task UsersShow_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterUser>(
-                    new Uri("users/show.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("users/show.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "screen_name", "twitterapi" },
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                    },
-                    "/users/show/:id")
-            )
-            .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
+                        ["screen_name"] = "twitterapi",
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/users/show/:id", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterUser())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -777,20 +811,22 @@ namespace OpenTween.Api
         [Fact]
         public async Task UsersLookup_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterUser[]>(
-                    new Uri("users/lookup.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("users/lookup.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "user_id", "11111,22222" },
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                    },
-                    "/users/lookup")
-            )
-            .ReturnsAsync(Array.Empty<TwitterUser>());
+                        ["user_id"] = "11111,22222",
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/users/lookup", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(Array.Empty<TwitterUser>())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -826,22 +862,24 @@ namespace OpenTween.Api
         [Fact]
         public async Task FavoritesList_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterStatus[]>(
-                    new Uri("favorites/list.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("favorites/list.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                            { "count", "200" },
-                            { "max_id", "900" },
-                            { "since_id", "100" },
-                    },
-                    "/favorites/list")
-            )
-            .ReturnsAsync(Array.Empty<TwitterStatus>());
+                        ["include_entities"] = "true",
+                        ["include_ext_alt_text"] = "true",
+                        ["tweet_mode"] = "extended",
+                        ["count"] = "200",
+                        ["max_id"] = "900",
+                        ["since_id"] = "100",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/favorites/list", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterStatus())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -900,14 +938,20 @@ namespace OpenTween.Api
         [Fact]
         public async Task FriendshipsShow_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            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" } },
-                    "/friendships/show")
-            )
-            .ReturnsAsync(new TwitterFriendship());
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("friendships/show.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
+                    {
+                        ["source_screen_name"] = "twitter",
+                        ["target_screen_name"] = "twitterapi",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/friendships/show", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterFriendship())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -964,14 +1008,15 @@ namespace OpenTween.Api
         [Fact]
         public async Task NoRetweetIds_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<long[]>(
-                    new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
-                    null,
-                    "/friendships/no_retweets/ids")
-            )
-            .ReturnsAsync(Array.Empty<long>());
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("friendships/no_retweets/ids.json", UriKind.Relative), r.RequestUri);
+                    Assert.Null(r.Query);
+                    Assert.Equal("/friendships/no_retweets/ids", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(Array.Empty<long>())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -984,14 +1029,19 @@ namespace OpenTween.Api
         [Fact]
         public async Task FollowersIds_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterIds>(
-                    new Uri("followers/ids.json", UriKind.Relative),
-                    new Dictionary<string, string> { { "cursor", "-1" } },
-                    "/followers/ids")
-            )
-            .ReturnsAsync(new TwitterIds());
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("followers/ids.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
+                    {
+                        ["cursor"] = "-1",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/followers/ids", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterIds())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -1004,14 +1054,19 @@ namespace OpenTween.Api
         [Fact]
         public async Task MutesUsersIds_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterIds>(
-                    new Uri("mutes/users/ids.json", UriKind.Relative),
-                    new Dictionary<string, string> { { "cursor", "-1" } },
-                    "/mutes/users/ids")
-            )
-            .ReturnsAsync(new TwitterIds());
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("mutes/users/ids.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
+                    {
+                        ["cursor"] = "-1",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/mutes/users/ids", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterIds())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -1024,14 +1079,19 @@ namespace OpenTween.Api
         [Fact]
         public async Task BlocksIds_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterIds>(
-                    new Uri("blocks/ids.json", UriKind.Relative),
-                    new Dictionary<string, string> { { "cursor", "-1" } },
-                    "/blocks/ids")
-            )
-            .ReturnsAsync(new TwitterIds());
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("blocks/ids.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
+                    {
+                        ["cursor"] = "-1",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/blocks/ids", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterIds())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -1090,23 +1150,25 @@ namespace OpenTween.Api
         [Fact]
         public async Task AccountVerifyCredentials_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterUser>(
-                    new Uri("account/verify_credentials.json", UriKind.Relative),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("account/verify_credentials.json", UriKind.Relative), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "include_entities", "true" },
-                            { "include_ext_alt_text", "true" },
-                            { "tweet_mode", "extended" },
-                    },
-                    "/account/verify_credentials")
-            )
-            .ReturnsAsync(new TwitterUser
-            {
-                Id = 100L,
-                ScreenName = "opentween",
-            });
+                        { "include_entities", "true" },
+                        { "include_ext_alt_text", "true" },
+                        { "tweet_mode", "extended" },
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                    Assert.Equal("/account/verify_credentials", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterUser
+                {
+                    Id = 100L,
+                    ScreenName = "opentween",
+                })
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -1182,14 +1244,15 @@ namespace OpenTween.Api
         [Fact]
         public async Task ApplicationRateLimitStatus_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterRateLimits>(
-                    new Uri("application/rate_limit_status.json", UriKind.Relative),
-                    null,
-                    "/application/rate_limit_status")
-            )
-            .ReturnsAsync(new TwitterRateLimits());
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("application/rate_limit_status.json", UriKind.Relative), r.RequestUri);
+                    Assert.Null(r.Query);
+                    Assert.Equal("/application/rate_limit_status", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterRateLimits())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -1202,14 +1265,15 @@ namespace OpenTween.Api
         [Fact]
         public async Task Configuration_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterConfiguration>(
-                    new Uri("help/configuration.json", UriKind.Relative),
-                    null,
-                    "/help/configuration")
-            )
-            .ReturnsAsync(new TwitterConfiguration());
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("help/configuration.json", UriKind.Relative), r.RequestUri);
+                    Assert.Null(r.Query);
+                    Assert.Equal("/help/configuration", r.EndpointName);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterConfiguration())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
@@ -1301,18 +1365,19 @@ namespace OpenTween.Api
         [Fact]
         public async Task MediaUploadStatus_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
-            mock.Setup(x =>
-                x.GetAsync<TwitterUploadMediaResult>(
-                    new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
-                    new Dictionary<string, string>
+            var mock = this.CreateApiConnectionMock<GetRequest>(
+                r =>
+                {
+                    Assert.Equal(new("https://upload.twitter.com/1.1/media/upload.json"), r.RequestUri);
+                    var expectedQuery = new Dictionary<string, string>
                     {
-                            { "command", "STATUS" },
-                            { "media_id", "11111" },
-                    },
-                    null)
-            )
-            .ReturnsAsync(new TwitterUploadMediaResult());
+                        ["command"] = "STATUS",
+                        ["media_id"] = "11111",
+                    };
+                    Assert.Equal(expectedQuery, r.Query);
+                },
+                JsonUtils.SerializeJsonByDataContract(new TwitterUploadMediaResult())
+            );
 
             using var twitterApi = new TwitterApi();
             twitterApi.ApiConnection = mock.Object;
index a2b00fd..62e0fed 100644 (file)
@@ -21,6 +21,8 @@
 
 using System;
 using System.Collections.Generic;
+using System.Net;
+using System.Net.Http;
 using System.Threading.Tasks;
 using Moq;
 using OpenTween.Api.DataModel;
@@ -32,23 +34,36 @@ namespace OpenTween.Api.TwitterV2
     public class GetTimelineRequestTest
     {
         [Fact]
-        public async Task StatusesMentionsTimeline_Test()
+        public async Task Send_Test()
         {
-            var mock = new Mock<IApiConnectionLegacy>();
+            Func<GetRequest, bool> verifyRequest = r =>
+            {
+                Assert.Equal(new("/2/users/100/timelines/reverse_chronological", UriKind.Relative), r.RequestUri);
+                var expectedQuery = new Dictionary<string, string>
+                {
+                    { "tweet.fields", "id" },
+                    { "max_results", "200" },
+                    { "until_id", "900" },
+                    { "since_id", "100" },
+                };
+                Assert.Equal(expectedQuery, r.Query);
+                Assert.Equal("/2/users/:id/timelines/reverse_chronological", r.EndpointName);
+                return true;
+            };
+
+            using var responseMessage = new HttpResponseMessage(HttpStatusCode.OK)
+            {
+                Content = new StringContent(
+                    JsonUtils.SerializeJsonByDataContract(new TwitterV2TweetIds())
+                ),
+            };
+            var mock = new Mock<IApiConnection>();
             mock.Setup(x =>
-                x.GetAsync<TwitterV2TweetIds>(
-                    new Uri("/2/users/100/timelines/reverse_chronological", UriKind.Relative),
-                    new Dictionary<string, string>
-                    {
-                        { "tweet.fields", "id" },
-                        { "max_results", "200" },
-                        { "until_id", "900" },
-                        { "since_id", "100" },
-                    },
-                    "/2/users/:id/timelines/reverse_chronological"
+                x.SendAsync(
+                    It.Is<GetRequest>(r => verifyRequest(r))
                 )
             )
-            .ReturnsAsync(new TwitterV2TweetIds());
+            .ReturnsAsync(new ApiResponse(responseMessage));
 
             var request = new GetTimelineRequest(userId: 100L)
             {
index d572032..7386e08 100644 (file)
@@ -62,9 +62,8 @@ namespace OpenTween.Api
             this.CurrentScreenName = screenName;
         }
 
-        public Task<TwitterStatus[]> StatusesHomeTimeline(int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
+        public async Task<TwitterStatus[]> StatusesHomeTimeline(int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
         {
-            var endpoint = new Uri("statuses/home_timeline.json", UriKind.Relative);
             var param = new Dictionary<string, string>
             {
                 ["include_entities"] = "true",
@@ -79,12 +78,22 @@ namespace OpenTween.Api
             if (sinceId != null)
                 param["since_id"] = sinceId.Id;
 
-            return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/home_timeline");
+            var request = new GetRequest
+            {
+                RequestUri = new("statuses/home_timeline.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/statuses/home_timeline",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterStatus[]>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterStatus[]> StatusesMentionsTimeline(int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
+        public async Task<TwitterStatus[]> StatusesMentionsTimeline(int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
         {
-            var endpoint = new Uri("statuses/mentions_timeline.json", UriKind.Relative);
             var param = new Dictionary<string, string>
             {
                 ["include_entities"] = "true",
@@ -99,12 +108,22 @@ namespace OpenTween.Api
             if (sinceId != null)
                 param["since_id"] = sinceId.Id;
 
-            return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/mentions_timeline");
+            var request = new GetRequest
+            {
+                RequestUri = new("statuses/mentions_timeline.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/statuses/mentions_timeline",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterStatus[]>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterStatus[]> StatusesUserTimeline(string screenName, int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
+        public async Task<TwitterStatus[]> StatusesUserTimeline(string screenName, int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
         {
-            var endpoint = new Uri("statuses/user_timeline.json", UriKind.Relative);
             var param = new Dictionary<string, string>
             {
                 ["screen_name"] = screenName,
@@ -121,35 +140,62 @@ namespace OpenTween.Api
             if (sinceId != null)
                 param["since_id"] = sinceId.Id;
 
-            return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/user_timeline");
+            var request = new GetRequest
+            {
+                RequestUri = new("statuses/user_timeline.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/statuses/user_timeline",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterStatus[]>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterStatus> StatusesShow(TwitterStatusId statusId)
+        public async Task<TwitterStatus> StatusesShow(TwitterStatusId statusId)
         {
-            var endpoint = new Uri("statuses/show.json", UriKind.Relative);
-            var param = new Dictionary<string, string>
+            var request = new GetRequest
             {
-                ["id"] = statusId.Id,
-                ["include_entities"] = "true",
-                ["include_ext_alt_text"] = "true",
-                ["tweet_mode"] = "extended",
+                RequestUri = new("statuses/show.json", UriKind.Relative),
+                Query = new Dictionary<string, string>
+                {
+                    ["id"] = statusId.Id,
+                    ["include_entities"] = "true",
+                    ["include_ext_alt_text"] = "true",
+                    ["tweet_mode"] = "extended",
+                },
+                EndpointName = "/statuses/show/:id",
             };
 
-            return this.Connection.GetAsync<TwitterStatus>(endpoint, param, "/statuses/show/:id");
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterStatus>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterStatus[]> StatusesLookup(IReadOnlyList<string> statusIds)
+        public async Task<TwitterStatus[]> StatusesLookup(IReadOnlyList<string> statusIds)
         {
-            var endpoint = new Uri("statuses/lookup.json", UriKind.Relative);
-            var param = new Dictionary<string, string>
+            var request = new GetRequest
             {
-                ["id"] = string.Join(",", statusIds),
-                ["include_entities"] = "true",
-                ["include_ext_alt_text"] = "true",
-                ["tweet_mode"] = "extended",
+                RequestUri = new("statuses/lookup.json", UriKind.Relative),
+                Query = new Dictionary<string, string>
+                {
+                    ["id"] = string.Join(",", statusIds),
+                    ["include_entities"] = "true",
+                    ["include_ext_alt_text"] = "true",
+                    ["tweet_mode"] = "extended",
+                },
+                EndpointName = "/statuses/lookup",
             };
 
-            return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/statuses/lookup");
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterStatus[]>()
+                .ConfigureAwait(false);
         }
 
         public async Task<LazyJson<TwitterStatus>> StatusesUpdate(
@@ -228,9 +274,8 @@ namespace OpenTween.Api
             return response.ReadAsLazyJson<TwitterStatus>();
         }
 
-        public Task<TwitterSearchResult> SearchTweets(string query, string? lang = null, int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
+        public async Task<TwitterSearchResult> SearchTweets(string query, string? lang = null, int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null)
         {
-            var endpoint = new Uri("search/tweets.json", UriKind.Relative);
             var param = new Dictionary<string, string>
             {
                 ["q"] = query,
@@ -249,12 +294,22 @@ namespace OpenTween.Api
             if (sinceId != null)
                 param["since_id"] = sinceId.Id;
 
-            return this.Connection.GetAsync<TwitterSearchResult>(endpoint, param, "/search/tweets");
+            var request = new GetRequest
+            {
+                RequestUri = new("search/tweets.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/search/tweets",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterSearchResult>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterLists> ListsOwnerships(string screenName, long? cursor = null, int? count = null)
+        public async Task<TwitterLists> ListsOwnerships(string screenName, long? cursor = null, int? count = null)
         {
-            var endpoint = new Uri("lists/ownerships.json", UriKind.Relative);
             var param = new Dictionary<string, string>
             {
                 ["screen_name"] = screenName,
@@ -265,12 +320,22 @@ namespace OpenTween.Api
             if (count != null)
                 param["count"] = count.ToString();
 
-            return this.Connection.GetAsync<TwitterLists>(endpoint, param, "/lists/ownerships");
+            var request = new GetRequest
+            {
+                RequestUri = new("lists/ownerships.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/lists/ownerships",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterLists>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterLists> ListsSubscriptions(string screenName, long? cursor = null, int? count = null)
+        public async Task<TwitterLists> ListsSubscriptions(string screenName, long? cursor = null, int? count = null)
         {
-            var endpoint = new Uri("lists/subscriptions.json", UriKind.Relative);
             var param = new Dictionary<string, string>
             {
                 ["screen_name"] = screenName,
@@ -281,12 +346,22 @@ namespace OpenTween.Api
             if (count != null)
                 param["count"] = count.ToString();
 
-            return this.Connection.GetAsync<TwitterLists>(endpoint, param, "/lists/subscriptions");
+            var request = new GetRequest
+            {
+                RequestUri = new("lists/subscriptions.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/lists/subscriptions",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterLists>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterLists> ListsMemberships(string screenName, long? cursor = null, int? count = null, bool? filterToOwnedLists = null)
+        public async Task<TwitterLists> ListsMemberships(string screenName, long? cursor = null, int? count = null, bool? filterToOwnedLists = null)
         {
-            var endpoint = new Uri("lists/memberships.json", UriKind.Relative);
             var param = new Dictionary<string, string>
             {
                 ["screen_name"] = screenName,
@@ -299,7 +374,18 @@ namespace OpenTween.Api
             if (filterToOwnedLists != null)
                 param["filter_to_owned_lists"] = filterToOwnedLists.Value ? "true" : "false";
 
-            return this.Connection.GetAsync<TwitterLists>(endpoint, param, "/lists/memberships");
+            var request = new GetRequest
+            {
+                RequestUri = new("lists/memberships.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/lists/memberships",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterLists>()
+                .ConfigureAwait(false);
         }
 
         public async Task<LazyJson<TwitterList>> ListsCreate(string name, string? description = null, bool? @private = null)
@@ -369,9 +455,8 @@ namespace OpenTween.Api
             return response.ReadAsLazyJson<TwitterList>();
         }
 
-        public Task<TwitterStatus[]> ListsStatuses(long listId, int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null, bool? includeRTs = null)
+        public async Task<TwitterStatus[]> ListsStatuses(long listId, int? count = null, TwitterStatusId? maxId = null, TwitterStatusId? sinceId = null, bool? includeRTs = null)
         {
-            var endpoint = new Uri("lists/statuses.json", UriKind.Relative);
             var param = new Dictionary<string, string>
             {
                 ["list_id"] = listId.ToString(),
@@ -389,12 +474,22 @@ namespace OpenTween.Api
             if (includeRTs != null)
                 param["include_rts"] = includeRTs.Value ? "true" : "false";
 
-            return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/lists/statuses");
+            var request = new GetRequest
+            {
+                RequestUri = new("lists/statuses.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/lists/statuses",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterStatus[]>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterUsers> ListsMembers(long listId, long? cursor = null)
+        public async Task<TwitterUsers> ListsMembers(long listId, long? cursor = null)
         {
-            var endpoint = new Uri("lists/members.json", UriKind.Relative);
             var param = new Dictionary<string, string>
             {
                 ["list_id"] = listId.ToString(),
@@ -406,22 +501,41 @@ namespace OpenTween.Api
             if (cursor != null)
                 param["cursor"] = cursor.ToString();
 
-            return this.Connection.GetAsync<TwitterUsers>(endpoint, param, "/lists/members");
+            var request = new GetRequest
+            {
+                RequestUri = new("lists/members.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/lists/members",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterUsers>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterUser> ListsMembersShow(long listId, string screenName)
+        public async Task<TwitterUser> ListsMembersShow(long listId, string screenName)
         {
-            var endpoint = new Uri("lists/members/show.json", UriKind.Relative);
-            var param = new Dictionary<string, string>
+            var request = new GetRequest
             {
-                ["list_id"] = listId.ToString(),
-                ["screen_name"] = screenName,
-                ["include_entities"] = "true",
-                ["include_ext_alt_text"] = "true",
-                ["tweet_mode"] = "extended",
+                RequestUri = new("lists/members/show.json", UriKind.Relative),
+                Query = new Dictionary<string, string>
+                {
+                    ["list_id"] = listId.ToString(),
+                    ["screen_name"] = screenName,
+                    ["include_entities"] = "true",
+                    ["include_ext_alt_text"] = "true",
+                    ["tweet_mode"] = "extended",
+                },
+                EndpointName = "/lists/members/show",
             };
 
-            return this.Connection.GetAsync<TwitterUser>(endpoint, param, "/lists/members/show");
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterUser>()
+                .ConfigureAwait(false);
         }
 
         public async Task<LazyJson<TwitterUser>> ListsMembersCreate(long listId, string screenName)
@@ -466,9 +580,8 @@ namespace OpenTween.Api
             return response.ReadAsLazyJson<TwitterUser>();
         }
 
-        public Task<TwitterMessageEventList> DirectMessagesEventsList(int? count = null, string? cursor = null)
+        public async Task<TwitterMessageEventList> DirectMessagesEventsList(int? count = null, string? cursor = null)
         {
-            var endpoint = new Uri("direct_messages/events/list.json", UriKind.Relative);
             var param = new Dictionary<string, string>();
 
             if (count != null)
@@ -476,7 +589,18 @@ namespace OpenTween.Api
             if (cursor != null)
                 param["cursor"] = cursor;
 
-            return this.Connection.GetAsync<TwitterMessageEventList>(endpoint, param, "/direct_messages/events/list");
+            var request = new GetRequest
+            {
+                RequestUri = new("direct_messages/events/list.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/direct_messages/events/list",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterMessageEventList>()
+                .ConfigureAwait(false);
         }
 
         public async Task<LazyJson<TwitterMessageEventSingle>> DirectMessagesEventsNew(long recipientId, string text, long? mediaId = null)
@@ -538,32 +662,48 @@ namespace OpenTween.Api
                 .ConfigureAwait(false);
         }
 
-        public Task<TwitterUser> UsersShow(string screenName)
+        public async Task<TwitterUser> UsersShow(string screenName)
         {
-            var endpoint = new Uri("users/show.json", UriKind.Relative);
-            var param = new Dictionary<string, string>
+            var request = new GetRequest
             {
-                ["screen_name"] = screenName,
-                ["include_entities"] = "true",
-                ["include_ext_alt_text"] = "true",
-                ["tweet_mode"] = "extended",
+                RequestUri = new("users/show.json", UriKind.Relative),
+                Query = new Dictionary<string, string>
+                {
+                    ["screen_name"] = screenName,
+                    ["include_entities"] = "true",
+                    ["include_ext_alt_text"] = "true",
+                    ["tweet_mode"] = "extended",
+                },
+                EndpointName = "/users/show/:id",
             };
 
-            return this.Connection.GetAsync<TwitterUser>(endpoint, param, "/users/show/:id");
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterUser>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterUser[]> UsersLookup(IReadOnlyList<string> userIds)
+        public async Task<TwitterUser[]> UsersLookup(IReadOnlyList<string> userIds)
         {
-            var endpoint = new Uri("users/lookup.json", UriKind.Relative);
-            var param = new Dictionary<string, string>
+            var request = new GetRequest
             {
-                ["user_id"] = string.Join(",", userIds),
-                ["include_entities"] = "true",
-                ["include_ext_alt_text"] = "true",
-                ["tweet_mode"] = "extended",
+                RequestUri = new("users/lookup.json", UriKind.Relative),
+                Query = new Dictionary<string, string>
+                {
+                    ["user_id"] = string.Join(",", userIds),
+                    ["include_entities"] = "true",
+                    ["include_ext_alt_text"] = "true",
+                    ["tweet_mode"] = "extended",
+                },
+                EndpointName = "/users/lookup",
             };
 
-            return this.Connection.GetAsync<TwitterUser[]>(endpoint, param, "/users/lookup");
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterUser[]>()
+                .ConfigureAwait(false);
         }
 
         public async Task<LazyJson<TwitterUser>> UsersReportSpam(string screenName)
@@ -584,9 +724,8 @@ namespace OpenTween.Api
             return response.ReadAsLazyJson<TwitterUser>();
         }
 
-        public Task<TwitterStatus[]> FavoritesList(int? count = null, long? maxId = null, long? sinceId = null)
+        public async Task<TwitterStatus[]> FavoritesList(int? count = null, long? maxId = null, long? sinceId = null)
         {
-            var endpoint = new Uri("favorites/list.json", UriKind.Relative);
             var param = new Dictionary<string, string>
             {
                 ["include_entities"] = "true",
@@ -601,7 +740,18 @@ namespace OpenTween.Api
             if (sinceId != null)
                 param["since_id"] = sinceId.ToString();
 
-            return this.Connection.GetAsync<TwitterStatus[]>(endpoint, param, "/favorites/list");
+            var request = new GetRequest
+            {
+                RequestUri = new("favorites/list.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/favorites/list",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterStatus[]>()
+                .ConfigureAwait(false);
         }
 
         public async Task<LazyJson<TwitterStatus>> FavoritesCreate(TwitterStatusId statusId)
@@ -640,16 +790,24 @@ namespace OpenTween.Api
             return response.ReadAsLazyJson<TwitterStatus>();
         }
 
-        public Task<TwitterFriendship> FriendshipsShow(string sourceScreenName, string targetScreenName)
+        public async Task<TwitterFriendship> FriendshipsShow(string sourceScreenName, string targetScreenName)
         {
-            var endpoint = new Uri("friendships/show.json", UriKind.Relative);
-            var param = new Dictionary<string, string>
+            var request = new GetRequest
             {
-                ["source_screen_name"] = sourceScreenName,
-                ["target_screen_name"] = targetScreenName,
+                RequestUri = new("friendships/show.json", UriKind.Relative),
+                Query = new Dictionary<string, string>
+                {
+                    ["source_screen_name"] = sourceScreenName,
+                    ["target_screen_name"] = targetScreenName,
+                },
+                EndpointName = "/friendships/show",
             };
 
-            return this.Connection.GetAsync<TwitterFriendship>(endpoint, param, "/friendships/show");
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterFriendship>()
+                .ConfigureAwait(false);
         }
 
         public async Task<LazyJson<TwitterFriendship>> FriendshipsCreate(string screenName)
@@ -686,44 +844,82 @@ namespace OpenTween.Api
             return response.ReadAsLazyJson<TwitterFriendship>();
         }
 
-        public Task<long[]> NoRetweetIds()
+        public async Task<long[]> NoRetweetIds()
         {
-            var endpoint = new Uri("friendships/no_retweets/ids.json", UriKind.Relative);
+            var request = new GetRequest
+            {
+                RequestUri = new("friendships/no_retweets/ids.json", UriKind.Relative),
+                EndpointName = "/friendships/no_retweets/ids",
+            };
 
-            return this.Connection.GetAsync<long[]>(endpoint, null, "/friendships/no_retweets/ids");
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<long[]>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterIds> FollowersIds(long? cursor = null)
+        public async Task<TwitterIds> FollowersIds(long? cursor = null)
         {
-            var endpoint = new Uri("followers/ids.json", UriKind.Relative);
             var param = new Dictionary<string, string>();
 
             if (cursor != null)
                 param["cursor"] = cursor.ToString();
 
-            return this.Connection.GetAsync<TwitterIds>(endpoint, param, "/followers/ids");
+            var request = new GetRequest
+            {
+                RequestUri = new("followers/ids.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/followers/ids",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterIds>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterIds> MutesUsersIds(long? cursor = null)
+        public async Task<TwitterIds> MutesUsersIds(long? cursor = null)
         {
-            var endpoint = new Uri("mutes/users/ids.json", UriKind.Relative);
             var param = new Dictionary<string, string>();
 
             if (cursor != null)
                 param["cursor"] = cursor.ToString();
 
-            return this.Connection.GetAsync<TwitterIds>(endpoint, param, "/mutes/users/ids");
+            var request = new GetRequest
+            {
+                RequestUri = new("mutes/users/ids.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/mutes/users/ids",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterIds>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterIds> BlocksIds(long? cursor = null)
+        public async Task<TwitterIds> BlocksIds(long? cursor = null)
         {
-            var endpoint = new Uri("blocks/ids.json", UriKind.Relative);
             var param = new Dictionary<string, string>();
 
             if (cursor != null)
                 param["cursor"] = cursor.ToString();
 
-            return this.Connection.GetAsync<TwitterIds>(endpoint, param, "/blocks/ids");
+            var request = new GetRequest
+            {
+                RequestUri = new("blocks/ids.json", UriKind.Relative),
+                Query = param,
+                EndpointName = "/blocks/ids",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterIds>()
+                .ConfigureAwait(false);
         }
 
         public async Task<LazyJson<TwitterUser>> BlocksCreate(string screenName)
@@ -764,15 +960,22 @@ namespace OpenTween.Api
 
         public async Task<TwitterUser> AccountVerifyCredentials()
         {
-            var endpoint = new Uri("account/verify_credentials.json", UriKind.Relative);
-            var param = new Dictionary<string, string>
+            var request = new GetRequest
             {
-                ["include_entities"] = "true",
-                ["include_ext_alt_text"] = "true",
-                ["tweet_mode"] = "extended",
+                RequestUri = new("account/verify_credentials.json", UriKind.Relative),
+                Query = new Dictionary<string, string>
+                {
+                    ["include_entities"] = "true",
+                    ["include_ext_alt_text"] = "true",
+                    ["tweet_mode"] = "extended",
+                },
+                EndpointName = "/account/verify_credentials",
             };
 
-            var user = await this.Connection.GetAsync<TwitterUser>(endpoint, param, "/account/verify_credentials")
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            var user = await response.ReadAsJson<TwitterUser>()
                 .ConfigureAwait(false);
 
             this.CurrentUserId = user.Id;
@@ -840,18 +1043,34 @@ namespace OpenTween.Api
             return response.ReadAsLazyJson<TwitterUser>();
         }
 
-        public Task<TwitterRateLimits> ApplicationRateLimitStatus()
+        public async Task<TwitterRateLimits> ApplicationRateLimitStatus()
         {
-            var endpoint = new Uri("application/rate_limit_status.json", UriKind.Relative);
+            var request = new GetRequest
+            {
+                RequestUri = new("application/rate_limit_status.json", UriKind.Relative),
+                EndpointName = "/application/rate_limit_status",
+            };
+
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
 
-            return this.Connection.GetAsync<TwitterRateLimits>(endpoint, null, "/application/rate_limit_status");
+            return await response.ReadAsJson<TwitterRateLimits>()
+                .ConfigureAwait(false);
         }
 
-        public Task<TwitterConfiguration> Configuration()
+        public async Task<TwitterConfiguration> Configuration()
         {
-            var endpoint = new Uri("help/configuration.json", UriKind.Relative);
+            var request = new GetRequest
+            {
+                RequestUri = new("help/configuration.json", UriKind.Relative),
+                EndpointName = "/help/configuration",
+            };
 
-            return this.Connection.GetAsync<TwitterConfiguration>(endpoint, null, "/help/configuration");
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterConfiguration>()
+                .ConfigureAwait(false);
         }
 
         public async Task<LazyJson<TwitterUploadMediaInit>> MediaUploadInit(long totalBytes, string mediaType, string? mediaCategory = null)
@@ -918,16 +1137,23 @@ namespace OpenTween.Api
             return response.ReadAsLazyJson<TwitterUploadMediaResult>();
         }
 
-        public Task<TwitterUploadMediaResult> MediaUploadStatus(long mediaId)
+        public async Task<TwitterUploadMediaResult> MediaUploadStatus(long mediaId)
         {
-            var endpoint = new Uri("https://upload.twitter.com/1.1/media/upload.json");
-            var param = new Dictionary<string, string>
+            var request = new GetRequest
             {
-                ["command"] = "STATUS",
-                ["media_id"] = mediaId.ToString(),
+                RequestUri = new("https://upload.twitter.com/1.1/media/upload.json"),
+                Query = new Dictionary<string, string>
+                {
+                    ["command"] = "STATUS",
+                    ["media_id"] = mediaId.ToString(),
+                },
             };
 
-            return this.Connection.GetAsync<TwitterUploadMediaResult>(endpoint, param, endpointName: null);
+            using var response = await this.Connection.SendAsync(request)
+                .ConfigureAwait(false);
+
+            return await response.ReadAsJson<TwitterUploadMediaResult>()
+                .ConfigureAwait(false);
         }
 
         public async Task MediaMetadataCreate(long mediaId, string altText)
index 677d167..24faa6b 100644 (file)
@@ -69,12 +69,20 @@ namespace OpenTween.Api.TwitterV2
             return param;
         }
 
-        public Task<TwitterV2TweetIds> Send(IApiConnectionLegacy apiConnection)
+        public async Task<TwitterV2TweetIds> Send(IApiConnection apiConnection)
         {
-            var uri = this.CreateEndpointUri();
-            var param = this.CreateParameters();
+            var request = new GetRequest
+            {
+                RequestUri = this.CreateEndpointUri(),
+                Query = this.CreateParameters(),
+                EndpointName = EndpointName,
+            };
+
+            using var response = await apiConnection.SendAsync(request)
+                .ConfigureAwait(false);
 
-            return apiConnection.GetAsync<TwitterV2TweetIds>(uri, param, EndpointName);
+            return await response.ReadAsJson<TwitterV2TweetIds>()
+                .ConfigureAwait(false);
         }
     }
 }