OSDN Git Service

ITwitterCredentialとアクセス手段ごとの具象クラスを追加
[opentween/open-tween.git] / OpenTween.Tests / Api / TwitterApiTest.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2016 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
4 //
5 // This file is part of OpenTween.
6 //
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
10 // any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 // for more details.
16 //
17 // You should have received a copy of the GNU General Public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
21
22 using System;
23 using System.Collections.Generic;
24 using System.IO;
25 using System.Linq;
26 using System.Net.Http;
27 using System.Reflection;
28 using System.Runtime.InteropServices;
29 using System.Text;
30 using System.Threading.Tasks;
31 using Moq;
32 using OpenTween.Api.DataModel;
33 using OpenTween.Connection;
34 using Xunit;
35
36 namespace OpenTween.Api
37 {
38     public class TwitterApiTest
39     {
40         public TwitterApiTest()
41             => this.MyCommonSetup();
42
43         private void MyCommonSetup()
44         {
45             var mockAssembly = new Mock<_Assembly>();
46             mockAssembly.Setup(m => m.GetName()).Returns(new AssemblyName("OpenTween"));
47
48             MyCommon.EntryAssembly = mockAssembly.Object;
49         }
50
51         [Fact]
52         public void Initialize_Test()
53         {
54             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
55             Assert.Null(twitterApi.ApiConnection);
56
57             twitterApi.Initialize("*** AccessToken ***", "*** AccessSecret ***", userId: 100L, screenName: "hogehoge");
58
59             Assert.IsType<TwitterApiConnection>(twitterApi.ApiConnection);
60
61             var apiConnection = (TwitterApiConnection)twitterApi.ApiConnection!;
62             var credential = Assert.IsType<TwitterCredentialOAuth1>(apiConnection.Credential);
63             Assert.Equal("*** AccessToken ***", credential.Token);
64             Assert.Equal("*** AccessSecret ***", credential.TokenSecret);
65
66             Assert.Equal(100L, twitterApi.CurrentUserId);
67             Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
68
69             // 複数回 Initialize を実行した場合は新たに TwitterApiConnection が生成される
70             twitterApi.Initialize("*** AccessToken2 ***", "*** AccessSecret2 ***", userId: 200L, screenName: "foobar");
71
72             var oldApiConnection = apiConnection;
73             Assert.True(oldApiConnection.IsDisposed);
74
75             Assert.IsType<TwitterApiConnection>(twitterApi.ApiConnection);
76
77             apiConnection = (TwitterApiConnection)twitterApi.ApiConnection!;
78             credential = Assert.IsType<TwitterCredentialOAuth1>(apiConnection.Credential);
79             Assert.Equal("*** AccessToken2 ***", credential.Token);
80             Assert.Equal("*** AccessSecret2 ***", credential.TokenSecret);
81
82             Assert.Equal(200L, twitterApi.CurrentUserId);
83             Assert.Equal("foobar", twitterApi.CurrentScreenName);
84         }
85
86         [Fact]
87         public async Task StatusesHomeTimeline_Test()
88         {
89             var mock = new Mock<IApiConnectionLegacy>();
90             mock.Setup(x =>
91                 x.GetAsync<TwitterStatus[]>(
92                     new Uri("statuses/home_timeline.json", UriKind.Relative),
93                     new Dictionary<string, string>
94                     {
95                             { "include_entities", "true" },
96                             { "include_ext_alt_text", "true" },
97                             { "tweet_mode", "extended" },
98                             { "count", "200" },
99                             { "max_id", "900" },
100                             { "since_id", "100" },
101                     },
102                     "/statuses/home_timeline")
103             )
104             .ReturnsAsync(Array.Empty<TwitterStatus>());
105
106             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
107             twitterApi.ApiConnection = mock.Object;
108
109             await twitterApi.StatusesHomeTimeline(200, maxId: new("900"), sinceId: new("100"));
110
111             mock.VerifyAll();
112         }
113
114         [Fact]
115         public async Task StatusesMentionsTimeline_Test()
116         {
117             var mock = new Mock<IApiConnectionLegacy>();
118             mock.Setup(x =>
119                 x.GetAsync<TwitterStatus[]>(
120                     new Uri("statuses/mentions_timeline.json", UriKind.Relative),
121                     new Dictionary<string, string>
122                     {
123                             { "include_entities", "true" },
124                             { "include_ext_alt_text", "true" },
125                             { "tweet_mode", "extended" },
126                             { "count", "200" },
127                             { "max_id", "900" },
128                             { "since_id", "100" },
129                     },
130                     "/statuses/mentions_timeline")
131             )
132             .ReturnsAsync(Array.Empty<TwitterStatus>());
133
134             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
135             twitterApi.ApiConnection = mock.Object;
136
137             await twitterApi.StatusesMentionsTimeline(200, maxId: new("900"), sinceId: new("100"));
138
139             mock.VerifyAll();
140         }
141
142         [Fact]
143         public async Task StatusesUserTimeline_Test()
144         {
145             var mock = new Mock<IApiConnectionLegacy>();
146             mock.Setup(x =>
147                 x.GetAsync<TwitterStatus[]>(
148                     new Uri("statuses/user_timeline.json", UriKind.Relative),
149                     new Dictionary<string, string>
150                     {
151                             { "screen_name", "twitterapi" },
152                             { "include_rts", "true" },
153                             { "include_entities", "true" },
154                             { "include_ext_alt_text", "true" },
155                             { "tweet_mode", "extended" },
156                             { "count", "200" },
157                             { "max_id", "900" },
158                             { "since_id", "100" },
159                     },
160                     "/statuses/user_timeline")
161             )
162             .ReturnsAsync(Array.Empty<TwitterStatus>());
163
164             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
165             twitterApi.ApiConnection = mock.Object;
166
167             await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: new("900"), sinceId: new("100"));
168
169             mock.VerifyAll();
170         }
171
172         [Fact]
173         public async Task StatusesShow_Test()
174         {
175             var mock = new Mock<IApiConnectionLegacy>();
176             mock.Setup(x =>
177                 x.GetAsync<TwitterStatus>(
178                     new Uri("statuses/show.json", UriKind.Relative),
179                     new Dictionary<string, string>
180                     {
181                             { "id", "100" },
182                             { "include_entities", "true" },
183                             { "include_ext_alt_text", "true" },
184                             { "tweet_mode", "extended" },
185                     },
186                     "/statuses/show/:id")
187             )
188             .ReturnsAsync(new TwitterStatus { Id = 100L });
189
190             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
191             twitterApi.ApiConnection = mock.Object;
192
193             await twitterApi.StatusesShow(statusId: new("100"));
194
195             mock.VerifyAll();
196         }
197
198         [Fact]
199         public async Task StatusesLookup_Test()
200         {
201             var mock = new Mock<IApiConnectionLegacy>();
202             mock.Setup(x =>
203                 x.GetAsync<TwitterStatus[]>(
204                     new Uri("statuses/lookup.json", UriKind.Relative),
205                     new Dictionary<string, string>
206                     {
207                         { "id", "100,200" },
208                         { "include_entities", "true" },
209                         { "include_ext_alt_text", "true" },
210                         { "tweet_mode", "extended" },
211                     },
212                     "/statuses/lookup"
213                 )
214             )
215             .ReturnsAsync(Array.Empty<TwitterStatus>());
216
217             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
218             twitterApi.ApiConnection = mock.Object;
219
220             await twitterApi.StatusesLookup(statusIds: new[] { "100", "200" });
221
222             mock.VerifyAll();
223         }
224
225         [Fact]
226         public async Task StatusesUpdate_Test()
227         {
228             var mock = new Mock<IApiConnectionLegacy>();
229             mock.Setup(x =>
230                 x.PostLazyAsync<TwitterStatus>(
231                     new Uri("statuses/update.json", UriKind.Relative),
232                     new Dictionary<string, string>
233                     {
234                             { "status", "hogehoge" },
235                             { "include_entities", "true" },
236                             { "include_ext_alt_text", "true" },
237                             { "tweet_mode", "extended" },
238                             { "in_reply_to_status_id", "100" },
239                             { "media_ids", "10,20" },
240                             { "auto_populate_reply_metadata", "true" },
241                             { "exclude_reply_user_ids", "100,200" },
242                             { "attachment_url", "https://twitter.com/twitterapi/status/22634515958" },
243                     })
244             )
245             .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
246
247             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
248             twitterApi.ApiConnection = mock.Object;
249
250             await twitterApi.StatusesUpdate(
251                     "hogehoge",
252                     replyToId: new("100"),
253                     mediaIds: new[] { 10L, 20L },
254                     autoPopulateReplyMetadata: true,
255                     excludeReplyUserIds: new[] { 100L, 200L },
256                     attachmentUrl: "https://twitter.com/twitterapi/status/22634515958"
257                 )
258                 .IgnoreResponse();
259
260             mock.VerifyAll();
261         }
262
263         [Fact]
264         public async Task StatusesUpdate_ExcludeReplyUserIdsEmptyTest()
265         {
266             var mock = new Mock<IApiConnectionLegacy>();
267             mock.Setup(x =>
268                 x.PostLazyAsync<TwitterStatus>(
269                     new Uri("statuses/update.json", UriKind.Relative),
270                     new Dictionary<string, string>
271                     {
272                         { "status", "hogehoge" },
273                         { "include_entities", "true" },
274                         { "include_ext_alt_text", "true" },
275                         { "tweet_mode", "extended" },
276                         // exclude_reply_user_ids は空の場合には送信されない
277                     })
278             )
279             .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
280
281             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
282             twitterApi.ApiConnection = mock.Object;
283
284             await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: Array.Empty<long>())
285                 .IgnoreResponse();
286
287             mock.VerifyAll();
288         }
289
290         [Fact]
291         public async Task StatusesDestroy_Test()
292         {
293             var mock = new Mock<IApiConnectionLegacy>();
294             mock.Setup(x =>
295                 x.PostLazyAsync<TwitterStatus>(
296                     new Uri("statuses/destroy.json", UriKind.Relative),
297                     new Dictionary<string, string> { { "id", "100" } })
298             )
299             .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
300
301             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
302             twitterApi.ApiConnection = mock.Object;
303
304             await twitterApi.StatusesDestroy(statusId: new("100"))
305                 .IgnoreResponse();
306
307             mock.VerifyAll();
308         }
309
310         [Fact]
311         public async Task StatusesRetweet_Test()
312         {
313             var mock = new Mock<IApiConnectionLegacy>();
314             mock.Setup(x =>
315                 x.PostLazyAsync<TwitterStatus>(
316                     new Uri("statuses/retweet.json", UriKind.Relative),
317                     new Dictionary<string, string>
318                     {
319                             { "id", "100" },
320                             { "include_entities", "true" },
321                             { "include_ext_alt_text", "true" },
322                             { "tweet_mode", "extended" },
323                     })
324             )
325             .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
326
327             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
328             twitterApi.ApiConnection = mock.Object;
329
330             await twitterApi.StatusesRetweet(new("100"))
331                 .IgnoreResponse();
332
333             mock.VerifyAll();
334         }
335
336         [Fact]
337         public async Task SearchTweets_Test()
338         {
339             var mock = new Mock<IApiConnectionLegacy>();
340             mock.Setup(x =>
341                 x.GetAsync<TwitterSearchResult>(
342                     new Uri("search/tweets.json", UriKind.Relative),
343                     new Dictionary<string, string>
344                     {
345                             { "q", "from:twitterapi" },
346                             { "result_type", "recent" },
347                             { "include_entities", "true" },
348                             { "include_ext_alt_text", "true" },
349                             { "tweet_mode", "extended" },
350                             { "lang", "en" },
351                             { "count", "200" },
352                             { "max_id", "900" },
353                             { "since_id", "100" },
354                     },
355                     "/search/tweets")
356             )
357             .ReturnsAsync(new TwitterSearchResult());
358
359             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
360             twitterApi.ApiConnection = mock.Object;
361
362             await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: new("900"), sinceId: new("100"));
363
364             mock.VerifyAll();
365         }
366
367         [Fact]
368         public async Task ListsOwnerships_Test()
369         {
370             var mock = new Mock<IApiConnectionLegacy>();
371             mock.Setup(x =>
372                 x.GetAsync<TwitterLists>(
373                     new Uri("lists/ownerships.json", UriKind.Relative),
374                     new Dictionary<string, string>
375                     {
376                             { "screen_name", "twitterapi" },
377                             { "cursor", "-1" },
378                             { "count", "100" },
379                     },
380                     "/lists/ownerships")
381             )
382             .ReturnsAsync(new TwitterLists());
383
384             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
385             twitterApi.ApiConnection = mock.Object;
386
387             await twitterApi.ListsOwnerships("twitterapi", cursor: -1L, count: 100);
388
389             mock.VerifyAll();
390         }
391
392         [Fact]
393         public async Task ListsSubscriptions_Test()
394         {
395             var mock = new Mock<IApiConnectionLegacy>();
396             mock.Setup(x =>
397                 x.GetAsync<TwitterLists>(
398                     new Uri("lists/subscriptions.json", UriKind.Relative),
399                     new Dictionary<string, string>
400                     {
401                             { "screen_name", "twitterapi" },
402                             { "cursor", "-1" },
403                             { "count", "100" },
404                     },
405                     "/lists/subscriptions")
406             )
407             .ReturnsAsync(new TwitterLists());
408
409             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
410             twitterApi.ApiConnection = mock.Object;
411
412             await twitterApi.ListsSubscriptions("twitterapi", cursor: -1L, count: 100);
413
414             mock.VerifyAll();
415         }
416
417         [Fact]
418         public async Task ListsMemberships_Test()
419         {
420             var mock = new Mock<IApiConnectionLegacy>();
421             mock.Setup(x =>
422                 x.GetAsync<TwitterLists>(
423                     new Uri("lists/memberships.json", UriKind.Relative),
424                     new Dictionary<string, string>
425                     {
426                             { "screen_name", "twitterapi" },
427                             { "cursor", "-1" },
428                             { "count", "100" },
429                             { "filter_to_owned_lists", "true" },
430                     },
431                     "/lists/memberships")
432             )
433             .ReturnsAsync(new TwitterLists());
434
435             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
436             twitterApi.ApiConnection = mock.Object;
437
438             await twitterApi.ListsMemberships("twitterapi", cursor: -1L, count: 100, filterToOwnedLists: true);
439
440             mock.VerifyAll();
441         }
442
443         [Fact]
444         public async Task ListsCreate_Test()
445         {
446             var mock = new Mock<IApiConnectionLegacy>();
447             mock.Setup(x =>
448                 x.PostLazyAsync<TwitterList>(
449                     new Uri("lists/create.json", UriKind.Relative),
450                     new Dictionary<string, string>
451                     {
452                             { "name", "hogehoge" },
453                             { "description", "aaaa" },
454                             { "mode", "private" },
455                     })
456             )
457             .ReturnsAsync(LazyJson.Create(new TwitterList()));
458
459             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
460             twitterApi.ApiConnection = mock.Object;
461
462             await twitterApi.ListsCreate("hogehoge", description: "aaaa", @private: true)
463                 .IgnoreResponse();
464
465             mock.VerifyAll();
466         }
467
468         [Fact]
469         public async Task ListsUpdate_Test()
470         {
471             var mock = new Mock<IApiConnectionLegacy>();
472             mock.Setup(x =>
473                 x.PostLazyAsync<TwitterList>(
474                     new Uri("lists/update.json", UriKind.Relative),
475                     new Dictionary<string, string>
476                     {
477                             { "list_id", "12345" },
478                             { "name", "hogehoge" },
479                             { "description", "aaaa" },
480                             { "mode", "private" },
481                     })
482             )
483             .ReturnsAsync(LazyJson.Create(new TwitterList()));
484
485             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
486             twitterApi.ApiConnection = mock.Object;
487
488             await twitterApi.ListsUpdate(12345L, name: "hogehoge", description: "aaaa", @private: true)
489                 .IgnoreResponse();
490
491             mock.VerifyAll();
492         }
493
494         [Fact]
495         public async Task ListsDestroy_Test()
496         {
497             var mock = new Mock<IApiConnectionLegacy>();
498             mock.Setup(x =>
499                 x.PostLazyAsync<TwitterList>(
500                     new Uri("lists/destroy.json", UriKind.Relative),
501                     new Dictionary<string, string>
502                     {
503                             { "list_id", "12345" },
504                     })
505             )
506             .ReturnsAsync(LazyJson.Create(new TwitterList()));
507
508             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
509             twitterApi.ApiConnection = mock.Object;
510
511             await twitterApi.ListsDestroy(12345L)
512                 .IgnoreResponse();
513
514             mock.VerifyAll();
515         }
516
517         [Fact]
518         public async Task ListsStatuses_Test()
519         {
520             var mock = new Mock<IApiConnectionLegacy>();
521             mock.Setup(x =>
522                 x.GetAsync<TwitterStatus[]>(
523                     new Uri("lists/statuses.json", UriKind.Relative),
524                     new Dictionary<string, string>
525                     {
526                             { "list_id", "12345" },
527                             { "include_entities", "true" },
528                             { "include_ext_alt_text", "true" },
529                             { "tweet_mode", "extended" },
530                             { "count", "200" },
531                             { "max_id", "900" },
532                             { "since_id", "100" },
533                             { "include_rts", "true" },
534                     },
535                     "/lists/statuses")
536             )
537             .ReturnsAsync(Array.Empty<TwitterStatus>());
538
539             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
540             twitterApi.ApiConnection = mock.Object;
541
542             await twitterApi.ListsStatuses(12345L, count: 200, maxId: new("900"), sinceId: new("100"), includeRTs: true);
543
544             mock.VerifyAll();
545         }
546
547         [Fact]
548         public async Task ListsMembers_Test()
549         {
550             var mock = new Mock<IApiConnectionLegacy>();
551             mock.Setup(x =>
552                 x.GetAsync<TwitterUsers>(
553                     new Uri("lists/members.json", UriKind.Relative),
554                     new Dictionary<string, string>
555                     {
556                             { "list_id", "12345" },
557                             { "include_entities", "true" },
558                             { "include_ext_alt_text", "true" },
559                             { "tweet_mode", "extended" },
560                             { "cursor", "-1" },
561                     },
562                     "/lists/members")
563             )
564             .ReturnsAsync(new TwitterUsers());
565
566             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
567             twitterApi.ApiConnection = mock.Object;
568
569             await twitterApi.ListsMembers(12345L, cursor: -1);
570
571             mock.VerifyAll();
572         }
573
574         [Fact]
575         public async Task ListsMembersShow_Test()
576         {
577             var mock = new Mock<IApiConnectionLegacy>();
578             mock.Setup(x =>
579                 x.GetAsync<TwitterUser>(
580                     new Uri("lists/members/show.json", UriKind.Relative),
581                     new Dictionary<string, string>
582                     {
583                             { "list_id", "12345" },
584                             { "screen_name", "twitterapi" },
585                             { "include_entities", "true" },
586                             { "include_ext_alt_text", "true" },
587                             { "tweet_mode", "extended" },
588                     },
589                     "/lists/members/show")
590             )
591             .ReturnsAsync(new TwitterUser());
592
593             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
594             twitterApi.ApiConnection = mock.Object;
595
596             await twitterApi.ListsMembersShow(12345L, "twitterapi");
597
598             mock.VerifyAll();
599         }
600
601         [Fact]
602         public async Task ListsMembersCreate_Test()
603         {
604             var mock = new Mock<IApiConnectionLegacy>();
605             mock.Setup(x =>
606                 x.PostLazyAsync<TwitterUser>(
607                     new Uri("lists/members/create.json", UriKind.Relative),
608                     new Dictionary<string, string>
609                     {
610                             { "list_id", "12345" },
611                             { "screen_name", "twitterapi" },
612                             { "include_entities", "true" },
613                             { "include_ext_alt_text", "true" },
614                             { "tweet_mode", "extended" },
615                     })
616             )
617             .ReturnsAsync(LazyJson.Create(new TwitterUser()));
618
619             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
620             twitterApi.ApiConnection = mock.Object;
621
622             await twitterApi.ListsMembersCreate(12345L, "twitterapi")
623                 .IgnoreResponse();
624
625             mock.VerifyAll();
626         }
627
628         [Fact]
629         public async Task ListsMembersDestroy_Test()
630         {
631             var mock = new Mock<IApiConnectionLegacy>();
632             mock.Setup(x =>
633                 x.PostLazyAsync<TwitterUser>(
634                     new Uri("lists/members/destroy.json", UriKind.Relative),
635                     new Dictionary<string, string>
636                     {
637                             { "list_id", "12345" },
638                             { "screen_name", "twitterapi" },
639                             { "include_entities", "true" },
640                             { "include_ext_alt_text", "true" },
641                             { "tweet_mode", "extended" },
642                     })
643             )
644             .ReturnsAsync(LazyJson.Create(new TwitterUser()));
645
646             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
647             twitterApi.ApiConnection = mock.Object;
648
649             await twitterApi.ListsMembersDestroy(12345L, "twitterapi")
650                 .IgnoreResponse();
651
652             mock.VerifyAll();
653         }
654
655         [Fact]
656         public async Task DirectMessagesEventsList_Test()
657         {
658             var mock = new Mock<IApiConnectionLegacy>();
659             mock.Setup(x =>
660                 x.GetAsync<TwitterMessageEventList>(
661                     new Uri("direct_messages/events/list.json", UriKind.Relative),
662                     new Dictionary<string, string>
663                     {
664                             { "count", "50" },
665                             { "cursor", "12345abcdefg" },
666                     },
667                     "/direct_messages/events/list")
668             )
669             .ReturnsAsync(new TwitterMessageEventList());
670
671             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
672             twitterApi.ApiConnection = mock.Object;
673
674             await twitterApi.DirectMessagesEventsList(count: 50, cursor: "12345abcdefg");
675
676             mock.VerifyAll();
677         }
678
679         [Fact]
680         public async Task DirectMessagesEventsNew_Test()
681         {
682             var mock = new Mock<IApiConnectionLegacy>();
683             var responseText = """
684                 {
685                   "event": {
686                     "type": "message_create",
687                     "message_create": {
688                       "target": {
689                         "recipient_id": "12345"
690                       },
691                       "message_data": {
692                         "text": "hogehoge",
693                         "attachment": {
694                           "type": "media",
695                           "media": {
696                             "id": "67890"
697                           }
698                         }
699                       }
700                     }
701                   }
702                 }
703                 """;
704             mock.Setup(x =>
705                 x.PostJsonAsync<TwitterMessageEventSingle>(
706                     new Uri("direct_messages/events/new.json", UriKind.Relative),
707                     responseText)
708             )
709             .ReturnsAsync(LazyJson.Create(new TwitterMessageEventSingle()));
710
711             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
712             twitterApi.ApiConnection = mock.Object;
713
714             await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge", mediaId: 67890L);
715
716             mock.VerifyAll();
717         }
718
719         [Fact]
720         public async Task DirectMessagesEventsDestroy_Test()
721         {
722             var mock = new Mock<IApiConnectionLegacy>();
723             mock.Setup(x =>
724                 x.DeleteAsync(
725                     new Uri("direct_messages/events/destroy.json?id=100", UriKind.Relative))
726             )
727             .Returns(Task.CompletedTask);
728
729             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
730             twitterApi.ApiConnection = mock.Object;
731
732             await twitterApi.DirectMessagesEventsDestroy(eventId: new("100"));
733
734             mock.VerifyAll();
735         }
736
737         [Fact]
738         public async Task UsersShow_Test()
739         {
740             var mock = new Mock<IApiConnectionLegacy>();
741             mock.Setup(x =>
742                 x.GetAsync<TwitterUser>(
743                     new Uri("users/show.json", UriKind.Relative),
744                     new Dictionary<string, string>
745                     {
746                             { "screen_name", "twitterapi" },
747                             { "include_entities", "true" },
748                             { "include_ext_alt_text", "true" },
749                             { "tweet_mode", "extended" },
750                     },
751                     "/users/show/:id")
752             )
753             .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
754
755             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
756             twitterApi.ApiConnection = mock.Object;
757
758             await twitterApi.UsersShow(screenName: "twitterapi");
759
760             mock.VerifyAll();
761         }
762
763         [Fact]
764         public async Task UsersLookup_Test()
765         {
766             var mock = new Mock<IApiConnectionLegacy>();
767             mock.Setup(x =>
768                 x.GetAsync<TwitterUser[]>(
769                     new Uri("users/lookup.json", UriKind.Relative),
770                     new Dictionary<string, string>
771                     {
772                             { "user_id", "11111,22222" },
773                             { "include_entities", "true" },
774                             { "include_ext_alt_text", "true" },
775                             { "tweet_mode", "extended" },
776                     },
777                     "/users/lookup")
778             )
779             .ReturnsAsync(Array.Empty<TwitterUser>());
780
781             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
782             twitterApi.ApiConnection = mock.Object;
783
784             await twitterApi.UsersLookup(userIds: new[] { "11111", "22222" });
785
786             mock.VerifyAll();
787         }
788
789         [Fact]
790         public async Task UsersReportSpam_Test()
791         {
792             var mock = new Mock<IApiConnectionLegacy>();
793             mock.Setup(x =>
794                 x.PostLazyAsync<TwitterUser>(
795                     new Uri("users/report_spam.json", UriKind.Relative),
796                     new Dictionary<string, string>
797                     {
798                             { "screen_name", "twitterapi" },
799                             { "tweet_mode", "extended" },
800                     })
801             )
802             .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
803
804             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
805             twitterApi.ApiConnection = mock.Object;
806
807             await twitterApi.UsersReportSpam(screenName: "twitterapi")
808                 .IgnoreResponse();
809
810             mock.VerifyAll();
811         }
812
813         [Fact]
814         public async Task FavoritesList_Test()
815         {
816             var mock = new Mock<IApiConnectionLegacy>();
817             mock.Setup(x =>
818                 x.GetAsync<TwitterStatus[]>(
819                     new Uri("favorites/list.json", UriKind.Relative),
820                     new Dictionary<string, string>
821                     {
822                             { "include_entities", "true" },
823                             { "include_ext_alt_text", "true" },
824                             { "tweet_mode", "extended" },
825                             { "count", "200" },
826                             { "max_id", "900" },
827                             { "since_id", "100" },
828                     },
829                     "/favorites/list")
830             )
831             .ReturnsAsync(Array.Empty<TwitterStatus>());
832
833             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
834             twitterApi.ApiConnection = mock.Object;
835
836             await twitterApi.FavoritesList(200, maxId: 900L, sinceId: 100L);
837
838             mock.VerifyAll();
839         }
840
841         [Fact]
842         public async Task FavoritesCreate_Test()
843         {
844             var mock = new Mock<IApiConnectionLegacy>();
845             mock.Setup(x =>
846                 x.PostLazyAsync<TwitterStatus>(
847                     new Uri("favorites/create.json", UriKind.Relative),
848                     new Dictionary<string, string>
849                     {
850                             { "id", "100" },
851                             { "tweet_mode", "extended" },
852                     })
853             )
854             .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
855
856             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
857             twitterApi.ApiConnection = mock.Object;
858
859             await twitterApi.FavoritesCreate(statusId: new("100"))
860                 .IgnoreResponse();
861
862             mock.VerifyAll();
863         }
864
865         [Fact]
866         public async Task FavoritesDestroy_Test()
867         {
868             var mock = new Mock<IApiConnectionLegacy>();
869             mock.Setup(x =>
870                 x.PostLazyAsync<TwitterStatus>(
871                     new Uri("favorites/destroy.json", UriKind.Relative),
872                     new Dictionary<string, string>
873                     {
874                             { "id", "100" },
875                             { "tweet_mode", "extended" },
876                     })
877             )
878             .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
879
880             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
881             twitterApi.ApiConnection = mock.Object;
882
883             await twitterApi.FavoritesDestroy(statusId: new("100"))
884                 .IgnoreResponse();
885
886             mock.VerifyAll();
887         }
888
889         [Fact]
890         public async Task FriendshipsShow_Test()
891         {
892             var mock = new Mock<IApiConnectionLegacy>();
893             mock.Setup(x =>
894                 x.GetAsync<TwitterFriendship>(
895                     new Uri("friendships/show.json", UriKind.Relative),
896                     new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } },
897                     "/friendships/show")
898             )
899             .ReturnsAsync(new TwitterFriendship());
900
901             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
902             twitterApi.ApiConnection = mock.Object;
903
904             await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi");
905
906             mock.VerifyAll();
907         }
908
909         [Fact]
910         public async Task FriendshipsCreate_Test()
911         {
912             var mock = new Mock<IApiConnectionLegacy>();
913             mock.Setup(x =>
914                 x.PostLazyAsync<TwitterFriendship>(
915                     new Uri("friendships/create.json", UriKind.Relative),
916                     new Dictionary<string, string> { { "screen_name", "twitterapi" } })
917             )
918             .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
919
920             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
921             twitterApi.ApiConnection = mock.Object;
922
923             await twitterApi.FriendshipsCreate(screenName: "twitterapi")
924                 .IgnoreResponse();
925
926             mock.VerifyAll();
927         }
928
929         [Fact]
930         public async Task FriendshipsDestroy_Test()
931         {
932             var mock = new Mock<IApiConnectionLegacy>();
933             mock.Setup(x =>
934                 x.PostLazyAsync<TwitterFriendship>(
935                     new Uri("friendships/destroy.json", UriKind.Relative),
936                     new Dictionary<string, string> { { "screen_name", "twitterapi" } })
937             )
938             .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
939
940             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
941             twitterApi.ApiConnection = mock.Object;
942
943             await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
944                 .IgnoreResponse();
945
946             mock.VerifyAll();
947         }
948
949         [Fact]
950         public async Task NoRetweetIds_Test()
951         {
952             var mock = new Mock<IApiConnectionLegacy>();
953             mock.Setup(x =>
954                 x.GetAsync<long[]>(
955                     new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
956                     null,
957                     "/friendships/no_retweets/ids")
958             )
959             .ReturnsAsync(Array.Empty<long>());
960
961             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
962             twitterApi.ApiConnection = mock.Object;
963
964             await twitterApi.NoRetweetIds();
965
966             mock.VerifyAll();
967         }
968
969         [Fact]
970         public async Task FollowersIds_Test()
971         {
972             var mock = new Mock<IApiConnectionLegacy>();
973             mock.Setup(x =>
974                 x.GetAsync<TwitterIds>(
975                     new Uri("followers/ids.json", UriKind.Relative),
976                     new Dictionary<string, string> { { "cursor", "-1" } },
977                     "/followers/ids")
978             )
979             .ReturnsAsync(new TwitterIds());
980
981             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
982             twitterApi.ApiConnection = mock.Object;
983
984             await twitterApi.FollowersIds(cursor: -1L);
985
986             mock.VerifyAll();
987         }
988
989         [Fact]
990         public async Task MutesUsersIds_Test()
991         {
992             var mock = new Mock<IApiConnectionLegacy>();
993             mock.Setup(x =>
994                 x.GetAsync<TwitterIds>(
995                     new Uri("mutes/users/ids.json", UriKind.Relative),
996                     new Dictionary<string, string> { { "cursor", "-1" } },
997                     "/mutes/users/ids")
998             )
999             .ReturnsAsync(new TwitterIds());
1000
1001             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1002             twitterApi.ApiConnection = mock.Object;
1003
1004             await twitterApi.MutesUsersIds(cursor: -1L);
1005
1006             mock.VerifyAll();
1007         }
1008
1009         [Fact]
1010         public async Task BlocksIds_Test()
1011         {
1012             var mock = new Mock<IApiConnectionLegacy>();
1013             mock.Setup(x =>
1014                 x.GetAsync<TwitterIds>(
1015                     new Uri("blocks/ids.json", UriKind.Relative),
1016                     new Dictionary<string, string> { { "cursor", "-1" } },
1017                     "/blocks/ids")
1018             )
1019             .ReturnsAsync(new TwitterIds());
1020
1021             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1022             twitterApi.ApiConnection = mock.Object;
1023
1024             await twitterApi.BlocksIds(cursor: -1L);
1025
1026             mock.VerifyAll();
1027         }
1028
1029         [Fact]
1030         public async Task BlocksCreate_Test()
1031         {
1032             var mock = new Mock<IApiConnectionLegacy>();
1033             mock.Setup(x =>
1034                 x.PostLazyAsync<TwitterUser>(
1035                     new Uri("blocks/create.json", UriKind.Relative),
1036                     new Dictionary<string, string>
1037                     {
1038                             { "screen_name", "twitterapi" },
1039                             { "tweet_mode", "extended" },
1040                     })
1041             )
1042             .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1043
1044             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1045             twitterApi.ApiConnection = mock.Object;
1046
1047             await twitterApi.BlocksCreate(screenName: "twitterapi")
1048                 .IgnoreResponse();
1049
1050             mock.VerifyAll();
1051         }
1052
1053         [Fact]
1054         public async Task BlocksDestroy_Test()
1055         {
1056             var mock = new Mock<IApiConnectionLegacy>();
1057             mock.Setup(x =>
1058                 x.PostLazyAsync<TwitterUser>(
1059                     new Uri("blocks/destroy.json", UriKind.Relative),
1060                     new Dictionary<string, string>
1061                     {
1062                             { "screen_name", "twitterapi" },
1063                             { "tweet_mode", "extended" },
1064                     })
1065             )
1066             .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1067
1068             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1069             twitterApi.ApiConnection = mock.Object;
1070
1071             await twitterApi.BlocksDestroy(screenName: "twitterapi")
1072                 .IgnoreResponse();
1073
1074             mock.VerifyAll();
1075         }
1076
1077         [Fact]
1078         public async Task AccountVerifyCredentials_Test()
1079         {
1080             var mock = new Mock<IApiConnectionLegacy>();
1081             mock.Setup(x =>
1082                 x.GetAsync<TwitterUser>(
1083                     new Uri("account/verify_credentials.json", UriKind.Relative),
1084                     new Dictionary<string, string>
1085                     {
1086                             { "include_entities", "true" },
1087                             { "include_ext_alt_text", "true" },
1088                             { "tweet_mode", "extended" },
1089                     },
1090                     "/account/verify_credentials")
1091             )
1092             .ReturnsAsync(new TwitterUser
1093             {
1094                 Id = 100L,
1095                 ScreenName = "opentween",
1096             });
1097
1098             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1099             twitterApi.ApiConnection = mock.Object;
1100
1101             await twitterApi.AccountVerifyCredentials();
1102
1103             Assert.Equal(100L, twitterApi.CurrentUserId);
1104             Assert.Equal("opentween", twitterApi.CurrentScreenName);
1105
1106             mock.VerifyAll();
1107         }
1108
1109         [Fact]
1110         public async Task AccountUpdateProfile_Test()
1111         {
1112             var mock = new Mock<IApiConnectionLegacy>();
1113             mock.Setup(x =>
1114                 x.PostLazyAsync<TwitterUser>(
1115                     new Uri("account/update_profile.json", UriKind.Relative),
1116                     new Dictionary<string, string>
1117                     {
1118                             { "include_entities", "true" },
1119                             { "include_ext_alt_text", "true" },
1120                             { "tweet_mode", "extended" },
1121                             { "name", "Name" },
1122                             { "url", "http://example.com/" },
1123                             { "location", "Location" },
1124                             { "description", "&lt;script&gt;alert(1)&lt;/script&gt;" },
1125                     })
1126             )
1127             .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1128
1129             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1130             twitterApi.ApiConnection = mock.Object;
1131
1132             await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
1133                 .IgnoreResponse();
1134
1135             mock.VerifyAll();
1136         }
1137
1138         [Fact]
1139         public async Task AccountUpdateProfileImage_Test()
1140         {
1141             using var image = TestUtils.CreateDummyImage();
1142             using var media = new MemoryImageMediaItem(image);
1143             var mock = new Mock<IApiConnectionLegacy>();
1144             mock.Setup(x =>
1145                 x.PostLazyAsync<TwitterUser>(
1146                     new Uri("account/update_profile_image.json", UriKind.Relative),
1147                     new Dictionary<string, string>
1148                     {
1149                             { "include_entities", "true" },
1150                             { "include_ext_alt_text", "true" },
1151                             { "tweet_mode", "extended" },
1152                     },
1153                     new Dictionary<string, IMediaItem> { { "image", media } })
1154             )
1155             .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1156
1157             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1158             twitterApi.ApiConnection = mock.Object;
1159
1160             await twitterApi.AccountUpdateProfileImage(media)
1161                 .IgnoreResponse();
1162
1163             mock.VerifyAll();
1164         }
1165
1166         [Fact]
1167         public async Task ApplicationRateLimitStatus_Test()
1168         {
1169             var mock = new Mock<IApiConnectionLegacy>();
1170             mock.Setup(x =>
1171                 x.GetAsync<TwitterRateLimits>(
1172                     new Uri("application/rate_limit_status.json", UriKind.Relative),
1173                     null,
1174                     "/application/rate_limit_status")
1175             )
1176             .ReturnsAsync(new TwitterRateLimits());
1177
1178             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1179             twitterApi.ApiConnection = mock.Object;
1180
1181             await twitterApi.ApplicationRateLimitStatus();
1182
1183             mock.VerifyAll();
1184         }
1185
1186         [Fact]
1187         public async Task Configuration_Test()
1188         {
1189             var mock = new Mock<IApiConnectionLegacy>();
1190             mock.Setup(x =>
1191                 x.GetAsync<TwitterConfiguration>(
1192                     new Uri("help/configuration.json", UriKind.Relative),
1193                     null,
1194                     "/help/configuration")
1195             )
1196             .ReturnsAsync(new TwitterConfiguration());
1197
1198             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1199             twitterApi.ApiConnection = mock.Object;
1200
1201             await twitterApi.Configuration();
1202
1203             mock.VerifyAll();
1204         }
1205
1206         [Fact]
1207         public async Task MediaUploadInit_Test()
1208         {
1209             var mock = new Mock<IApiConnectionLegacy>();
1210             mock.Setup(x =>
1211                 x.PostLazyAsync<TwitterUploadMediaInit>(
1212                     new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1213                     new Dictionary<string, string>
1214                     {
1215                             { "command", "INIT" },
1216                             { "total_bytes", "123456" },
1217                             { "media_type", "image/png" },
1218                             { "media_category", "dm_image" },
1219                     })
1220             )
1221             .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaInit()));
1222
1223             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1224             twitterApi.ApiConnection = mock.Object;
1225
1226             await twitterApi.MediaUploadInit(totalBytes: 123456L, mediaType: "image/png", mediaCategory: "dm_image")
1227                 .IgnoreResponse();
1228
1229             mock.VerifyAll();
1230         }
1231
1232         [Fact]
1233         public async Task MediaUploadAppend_Test()
1234         {
1235             using var image = TestUtils.CreateDummyImage();
1236             using var media = new MemoryImageMediaItem(image);
1237             var mock = new Mock<IApiConnectionLegacy>();
1238             mock.Setup(x =>
1239                 x.PostAsync(
1240                     new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1241                     new Dictionary<string, string>
1242                     {
1243                             { "command", "APPEND" },
1244                             { "media_id", "11111" },
1245                             { "segment_index", "1" },
1246                     },
1247                     new Dictionary<string, IMediaItem> { { "media", media } })
1248             )
1249             .Returns(Task.CompletedTask);
1250
1251             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1252             twitterApi.ApiConnection = mock.Object;
1253
1254             await twitterApi.MediaUploadAppend(mediaId: 11111L, segmentIndex: 1, media: media);
1255
1256             mock.VerifyAll();
1257         }
1258
1259         [Fact]
1260         public async Task MediaUploadFinalize_Test()
1261         {
1262             var mock = new Mock<IApiConnectionLegacy>();
1263             mock.Setup(x =>
1264                 x.PostLazyAsync<TwitterUploadMediaResult>(
1265                     new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1266                     new Dictionary<string, string>
1267                     {
1268                             { "command", "FINALIZE" },
1269                             { "media_id", "11111" },
1270                     })
1271             )
1272             .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
1273
1274             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1275             twitterApi.ApiConnection = mock.Object;
1276
1277             await twitterApi.MediaUploadFinalize(mediaId: 11111L)
1278                 .IgnoreResponse();
1279
1280             mock.VerifyAll();
1281         }
1282
1283         [Fact]
1284         public async Task MediaUploadStatus_Test()
1285         {
1286             var mock = new Mock<IApiConnectionLegacy>();
1287             mock.Setup(x =>
1288                 x.GetAsync<TwitterUploadMediaResult>(
1289                     new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1290                     new Dictionary<string, string>
1291                     {
1292                             { "command", "STATUS" },
1293                             { "media_id", "11111" },
1294                     },
1295                     null)
1296             )
1297             .ReturnsAsync(new TwitterUploadMediaResult());
1298
1299             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1300             twitterApi.ApiConnection = mock.Object;
1301
1302             await twitterApi.MediaUploadStatus(mediaId: 11111L);
1303
1304             mock.VerifyAll();
1305         }
1306
1307         [Fact]
1308         public async Task MediaMetadataCreate_Test()
1309         {
1310             var mock = new Mock<IApiConnectionLegacy>();
1311             mock.Setup(x =>
1312                 x.PostJsonAsync(
1313                     new Uri("https://upload.twitter.com/1.1/media/metadata/create.json", UriKind.Absolute),
1314                     """{"media_id": "12345", "alt_text": {"text": "hogehoge"}}""")
1315             )
1316             .ReturnsAsync("");
1317
1318             using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1319             twitterApi.ApiConnection = mock.Object;
1320
1321             await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge");
1322
1323             mock.VerifyAll();
1324         }
1325     }
1326 }