OSDN Git Service

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