1 // OpenTween - Client of Twitter
2 // Copyright (c) 2016 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
5 // This file is part of OpenTween.
7 // This program is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by the Free
9 // Software Foundation; either version 3 of the License, or (at your option)
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 // You should have received a copy of the GNU General Public License along
18 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
19 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 // Boston, MA 02110-1301, USA.
23 using System.Collections.Generic;
26 using System.Net.Http;
27 using System.Reflection;
28 using System.Runtime.InteropServices;
30 using System.Threading.Tasks;
32 using OpenTween.Api.DataModel;
33 using OpenTween.Connection;
36 namespace OpenTween.Api
38 public class TwitterApiTest
40 public TwitterApiTest()
41 => this.MyCommonSetup();
43 private void MyCommonSetup()
45 var mockAssembly = new Mock<_Assembly>();
46 mockAssembly.Setup(m => m.GetName()).Returns(new AssemblyName("OpenTween"));
48 MyCommon.EntryAssembly = mockAssembly.Object;
52 public void Initialize_Test()
54 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
55 Assert.Null(twitterApi.ApiConnection);
57 twitterApi.Initialize("*** AccessToken ***", "*** AccessSecret ***", userId: 100L, screenName: "hogehoge");
59 Assert.IsType<TwitterApiConnection>(twitterApi.ApiConnection);
61 var apiConnection = (TwitterApiConnection)twitterApi.ApiConnection!;
62 Assert.Equal("*** AccessToken ***", apiConnection.AccessToken);
63 Assert.Equal("*** AccessSecret ***", apiConnection.AccessSecret);
65 Assert.Equal(100L, twitterApi.CurrentUserId);
66 Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
68 // 複数回 Initialize を実行した場合は新たに TwitterApiConnection が生成される
69 twitterApi.Initialize("*** AccessToken2 ***", "*** AccessSecret2 ***", userId: 200L, screenName: "foobar");
71 var oldApiConnection = apiConnection;
72 Assert.True(oldApiConnection.IsDisposed);
74 Assert.IsType<TwitterApiConnection>(twitterApi.ApiConnection);
76 apiConnection = (TwitterApiConnection)twitterApi.ApiConnection!;
77 Assert.Equal("*** AccessToken2 ***", apiConnection.AccessToken);
78 Assert.Equal("*** AccessSecret2 ***", apiConnection.AccessSecret);
80 Assert.Equal(200L, twitterApi.CurrentUserId);
81 Assert.Equal("foobar", twitterApi.CurrentScreenName);
85 public async Task StatusesHomeTimeline_Test()
87 var mock = new Mock<IApiConnection>();
89 x.GetAsync<TwitterStatus[]>(
90 new Uri("statuses/home_timeline.json", UriKind.Relative),
91 new Dictionary<string, string>
93 { "include_entities", "true" },
94 { "include_ext_alt_text", "true" },
95 { "tweet_mode", "extended" },
98 { "since_id", "100" },
100 "/statuses/home_timeline")
102 .ReturnsAsync(Array.Empty<TwitterStatus>());
104 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
105 twitterApi.ApiConnection = mock.Object;
107 await twitterApi.StatusesHomeTimeline(200, maxId: 900L, sinceId: 100L)
108 .ConfigureAwait(false);
114 public async Task StatusesMentionsTimeline_Test()
116 var mock = new Mock<IApiConnection>();
118 x.GetAsync<TwitterStatus[]>(
119 new Uri("statuses/mentions_timeline.json", UriKind.Relative),
120 new Dictionary<string, string>
122 { "include_entities", "true" },
123 { "include_ext_alt_text", "true" },
124 { "tweet_mode", "extended" },
127 { "since_id", "100" },
129 "/statuses/mentions_timeline")
131 .ReturnsAsync(Array.Empty<TwitterStatus>());
133 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
134 twitterApi.ApiConnection = mock.Object;
136 await twitterApi.StatusesMentionsTimeline(200, maxId: 900L, sinceId: 100L)
137 .ConfigureAwait(false);
143 public async Task StatusesUserTimeline_Test()
145 var mock = new Mock<IApiConnection>();
147 x.GetAsync<TwitterStatus[]>(
148 new Uri("statuses/user_timeline.json", UriKind.Relative),
149 new Dictionary<string, string>
151 { "screen_name", "twitterapi" },
152 { "include_rts", "true" },
153 { "include_entities", "true" },
154 { "include_ext_alt_text", "true" },
155 { "tweet_mode", "extended" },
158 { "since_id", "100" },
160 "/statuses/user_timeline")
162 .ReturnsAsync(Array.Empty<TwitterStatus>());
164 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
165 twitterApi.ApiConnection = mock.Object;
167 await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: 900L, sinceId: 100L)
168 .ConfigureAwait(false);
174 public async Task StatusesShow_Test()
176 var mock = new Mock<IApiConnection>();
178 x.GetAsync<TwitterStatus>(
179 new Uri("statuses/show.json", UriKind.Relative),
180 new Dictionary<string, string>
183 { "include_entities", "true" },
184 { "include_ext_alt_text", "true" },
185 { "tweet_mode", "extended" },
187 "/statuses/show/:id")
189 .ReturnsAsync(new TwitterStatus { Id = 100L });
191 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
192 twitterApi.ApiConnection = mock.Object;
194 await twitterApi.StatusesShow(statusId: new("100"))
195 .ConfigureAwait(false);
201 public async Task StatusesLookup_Test()
203 var mock = new Mock<IApiConnection>();
205 x.GetAsync<TwitterStatus[]>(
206 new Uri("statuses/lookup.json", UriKind.Relative),
207 new Dictionary<string, string>
210 { "include_entities", "true" },
211 { "include_ext_alt_text", "true" },
212 { "tweet_mode", "extended" },
217 .ReturnsAsync(Array.Empty<TwitterStatus>());
219 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
220 twitterApi.ApiConnection = mock.Object;
222 await twitterApi.StatusesLookup(statusIds: new[] { "100", "200" })
223 .ConfigureAwait(false);
229 public async Task StatusesUpdate_Test()
231 var mock = new Mock<IApiConnection>();
233 x.PostLazyAsync<TwitterStatus>(
234 new Uri("statuses/update.json", UriKind.Relative),
235 new Dictionary<string, string>
237 { "status", "hogehoge" },
238 { "include_entities", "true" },
239 { "include_ext_alt_text", "true" },
240 { "tweet_mode", "extended" },
241 { "in_reply_to_status_id", "100" },
242 { "media_ids", "10,20" },
243 { "auto_populate_reply_metadata", "true" },
244 { "exclude_reply_user_ids", "100,200" },
245 { "attachment_url", "https://twitter.com/twitterapi/status/22634515958" },
248 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
250 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
251 twitterApi.ApiConnection = mock.Object;
253 await twitterApi.StatusesUpdate(
255 replyToId: new("100"),
256 mediaIds: new[] { 10L, 20L },
257 autoPopulateReplyMetadata: true,
258 excludeReplyUserIds: new[] { 100L, 200L },
259 attachmentUrl: "https://twitter.com/twitterapi/status/22634515958"
262 .ConfigureAwait(false);
268 public async Task StatusesUpdate_ExcludeReplyUserIdsEmptyTest()
270 var mock = new Mock<IApiConnection>();
272 x.PostLazyAsync<TwitterStatus>(
273 new Uri("statuses/update.json", UriKind.Relative),
274 new Dictionary<string, string>
276 { "status", "hogehoge" },
277 { "include_entities", "true" },
278 { "include_ext_alt_text", "true" },
279 { "tweet_mode", "extended" },
280 // exclude_reply_user_ids は空の場合には送信されない
283 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
285 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
286 twitterApi.ApiConnection = mock.Object;
288 await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: Array.Empty<long>())
290 .ConfigureAwait(false);
296 public async Task StatusesDestroy_Test()
298 var mock = new Mock<IApiConnection>();
300 x.PostLazyAsync<TwitterStatus>(
301 new Uri("statuses/destroy.json", UriKind.Relative),
302 new Dictionary<string, string> { { "id", "100" } })
304 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
306 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
307 twitterApi.ApiConnection = mock.Object;
309 await twitterApi.StatusesDestroy(statusId: new("100"))
311 .ConfigureAwait(false);
317 public async Task StatusesRetweet_Test()
319 var mock = new Mock<IApiConnection>();
321 x.PostLazyAsync<TwitterStatus>(
322 new Uri("statuses/retweet.json", UriKind.Relative),
323 new Dictionary<string, string>
326 { "include_entities", "true" },
327 { "include_ext_alt_text", "true" },
328 { "tweet_mode", "extended" },
331 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
333 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
334 twitterApi.ApiConnection = mock.Object;
336 await twitterApi.StatusesRetweet(new("100"))
338 .ConfigureAwait(false);
344 public async Task SearchTweets_Test()
346 var mock = new Mock<IApiConnection>();
348 x.GetAsync<TwitterSearchResult>(
349 new Uri("search/tweets.json", UriKind.Relative),
350 new Dictionary<string, string>
352 { "q", "from:twitterapi" },
353 { "result_type", "recent" },
354 { "include_entities", "true" },
355 { "include_ext_alt_text", "true" },
356 { "tweet_mode", "extended" },
360 { "since_id", "100" },
364 .ReturnsAsync(new TwitterSearchResult());
366 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
367 twitterApi.ApiConnection = mock.Object;
369 await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: 900L, sinceId: 100L)
370 .ConfigureAwait(false);
376 public async Task ListsOwnerships_Test()
378 var mock = new Mock<IApiConnection>();
380 x.GetAsync<TwitterLists>(
381 new Uri("lists/ownerships.json", UriKind.Relative),
382 new Dictionary<string, string>
384 { "screen_name", "twitterapi" },
390 .ReturnsAsync(new TwitterLists());
392 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
393 twitterApi.ApiConnection = mock.Object;
395 await twitterApi.ListsOwnerships("twitterapi", cursor: -1L, count: 100)
396 .ConfigureAwait(false);
402 public async Task ListsSubscriptions_Test()
404 var mock = new Mock<IApiConnection>();
406 x.GetAsync<TwitterLists>(
407 new Uri("lists/subscriptions.json", UriKind.Relative),
408 new Dictionary<string, string>
410 { "screen_name", "twitterapi" },
414 "/lists/subscriptions")
416 .ReturnsAsync(new TwitterLists());
418 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
419 twitterApi.ApiConnection = mock.Object;
421 await twitterApi.ListsSubscriptions("twitterapi", cursor: -1L, count: 100)
422 .ConfigureAwait(false);
428 public async Task ListsMemberships_Test()
430 var mock = new Mock<IApiConnection>();
432 x.GetAsync<TwitterLists>(
433 new Uri("lists/memberships.json", UriKind.Relative),
434 new Dictionary<string, string>
436 { "screen_name", "twitterapi" },
439 { "filter_to_owned_lists", "true" },
441 "/lists/memberships")
443 .ReturnsAsync(new TwitterLists());
445 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
446 twitterApi.ApiConnection = mock.Object;
448 await twitterApi.ListsMemberships("twitterapi", cursor: -1L, count: 100, filterToOwnedLists: true)
449 .ConfigureAwait(false);
455 public async Task ListsCreate_Test()
457 var mock = new Mock<IApiConnection>();
459 x.PostLazyAsync<TwitterList>(
460 new Uri("lists/create.json", UriKind.Relative),
461 new Dictionary<string, string>
463 { "name", "hogehoge" },
464 { "description", "aaaa" },
465 { "mode", "private" },
468 .ReturnsAsync(LazyJson.Create(new TwitterList()));
470 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
471 twitterApi.ApiConnection = mock.Object;
473 await twitterApi.ListsCreate("hogehoge", description: "aaaa", @private: true)
475 .ConfigureAwait(false);
481 public async Task ListsUpdate_Test()
483 var mock = new Mock<IApiConnection>();
485 x.PostLazyAsync<TwitterList>(
486 new Uri("lists/update.json", UriKind.Relative),
487 new Dictionary<string, string>
489 { "list_id", "12345" },
490 { "name", "hogehoge" },
491 { "description", "aaaa" },
492 { "mode", "private" },
495 .ReturnsAsync(LazyJson.Create(new TwitterList()));
497 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
498 twitterApi.ApiConnection = mock.Object;
500 await twitterApi.ListsUpdate(12345L, name: "hogehoge", description: "aaaa", @private: true)
502 .ConfigureAwait(false);
508 public async Task ListsDestroy_Test()
510 var mock = new Mock<IApiConnection>();
512 x.PostLazyAsync<TwitterList>(
513 new Uri("lists/destroy.json", UriKind.Relative),
514 new Dictionary<string, string>
516 { "list_id", "12345" },
519 .ReturnsAsync(LazyJson.Create(new TwitterList()));
521 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
522 twitterApi.ApiConnection = mock.Object;
524 await twitterApi.ListsDestroy(12345L)
526 .ConfigureAwait(false);
532 public async Task ListsStatuses_Test()
534 var mock = new Mock<IApiConnection>();
536 x.GetAsync<TwitterStatus[]>(
537 new Uri("lists/statuses.json", UriKind.Relative),
538 new Dictionary<string, string>
540 { "list_id", "12345" },
541 { "include_entities", "true" },
542 { "include_ext_alt_text", "true" },
543 { "tweet_mode", "extended" },
546 { "since_id", "100" },
547 { "include_rts", "true" },
551 .ReturnsAsync(Array.Empty<TwitterStatus>());
553 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
554 twitterApi.ApiConnection = mock.Object;
556 await twitterApi.ListsStatuses(12345L, count: 200, maxId: 900L, sinceId: 100L, includeRTs: true)
557 .ConfigureAwait(false);
563 public async Task ListsMembers_Test()
565 var mock = new Mock<IApiConnection>();
567 x.GetAsync<TwitterUsers>(
568 new Uri("lists/members.json", UriKind.Relative),
569 new Dictionary<string, string>
571 { "list_id", "12345" },
572 { "include_entities", "true" },
573 { "include_ext_alt_text", "true" },
574 { "tweet_mode", "extended" },
579 .ReturnsAsync(new TwitterUsers());
581 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
582 twitterApi.ApiConnection = mock.Object;
584 await twitterApi.ListsMembers(12345L, cursor: -1)
585 .ConfigureAwait(false);
591 public async Task ListsMembersShow_Test()
593 var mock = new Mock<IApiConnection>();
595 x.GetAsync<TwitterUser>(
596 new Uri("lists/members/show.json", UriKind.Relative),
597 new Dictionary<string, string>
599 { "list_id", "12345" },
600 { "screen_name", "twitterapi" },
601 { "include_entities", "true" },
602 { "include_ext_alt_text", "true" },
603 { "tweet_mode", "extended" },
605 "/lists/members/show")
607 .ReturnsAsync(new TwitterUser());
609 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
610 twitterApi.ApiConnection = mock.Object;
612 await twitterApi.ListsMembersShow(12345L, "twitterapi")
613 .ConfigureAwait(false);
619 public async Task ListsMembersCreate_Test()
621 var mock = new Mock<IApiConnection>();
623 x.PostLazyAsync<TwitterUser>(
624 new Uri("lists/members/create.json", UriKind.Relative),
625 new Dictionary<string, string>
627 { "list_id", "12345" },
628 { "screen_name", "twitterapi" },
629 { "include_entities", "true" },
630 { "include_ext_alt_text", "true" },
631 { "tweet_mode", "extended" },
634 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
636 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
637 twitterApi.ApiConnection = mock.Object;
639 await twitterApi.ListsMembersCreate(12345L, "twitterapi")
641 .ConfigureAwait(false);
647 public async Task ListsMembersDestroy_Test()
649 var mock = new Mock<IApiConnection>();
651 x.PostLazyAsync<TwitterUser>(
652 new Uri("lists/members/destroy.json", UriKind.Relative),
653 new Dictionary<string, string>
655 { "list_id", "12345" },
656 { "screen_name", "twitterapi" },
657 { "include_entities", "true" },
658 { "include_ext_alt_text", "true" },
659 { "tweet_mode", "extended" },
662 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
664 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
665 twitterApi.ApiConnection = mock.Object;
667 await twitterApi.ListsMembersDestroy(12345L, "twitterapi")
669 .ConfigureAwait(false);
675 public async Task DirectMessagesEventsList_Test()
677 var mock = new Mock<IApiConnection>();
679 x.GetAsync<TwitterMessageEventList>(
680 new Uri("direct_messages/events/list.json", UriKind.Relative),
681 new Dictionary<string, string>
684 { "cursor", "12345abcdefg" },
686 "/direct_messages/events/list")
688 .ReturnsAsync(new TwitterMessageEventList());
690 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
691 twitterApi.ApiConnection = mock.Object;
693 await twitterApi.DirectMessagesEventsList(count: 50, cursor: "12345abcdefg")
694 .ConfigureAwait(false);
700 public async Task DirectMessagesEventsNew_Test()
702 var mock = new Mock<IApiConnection>();
703 var responseText = """
706 "type": "message_create",
709 "recipient_id": "12345"
725 x.PostJsonAsync<TwitterMessageEventSingle>(
726 new Uri("direct_messages/events/new.json", UriKind.Relative),
729 .ReturnsAsync(LazyJson.Create(new TwitterMessageEventSingle()));
731 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
732 twitterApi.ApiConnection = mock.Object;
734 await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge", mediaId: 67890L)
735 .ConfigureAwait(false);
741 public async Task DirectMessagesEventsDestroy_Test()
743 var mock = new Mock<IApiConnection>();
746 new Uri("direct_messages/events/destroy.json?id=100", UriKind.Relative))
748 .Returns(Task.CompletedTask);
750 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
751 twitterApi.ApiConnection = mock.Object;
753 await twitterApi.DirectMessagesEventsDestroy(eventId: new("100"))
754 .ConfigureAwait(false);
760 public async Task UsersShow_Test()
762 var mock = new Mock<IApiConnection>();
764 x.GetAsync<TwitterUser>(
765 new Uri("users/show.json", UriKind.Relative),
766 new Dictionary<string, string>
768 { "screen_name", "twitterapi" },
769 { "include_entities", "true" },
770 { "include_ext_alt_text", "true" },
771 { "tweet_mode", "extended" },
775 .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
777 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
778 twitterApi.ApiConnection = mock.Object;
780 await twitterApi.UsersShow(screenName: "twitterapi")
781 .ConfigureAwait(false);
787 public async Task UsersLookup_Test()
789 var mock = new Mock<IApiConnection>();
791 x.GetAsync<TwitterUser[]>(
792 new Uri("users/lookup.json", UriKind.Relative),
793 new Dictionary<string, string>
795 { "user_id", "11111,22222" },
796 { "include_entities", "true" },
797 { "include_ext_alt_text", "true" },
798 { "tweet_mode", "extended" },
802 .ReturnsAsync(Array.Empty<TwitterUser>());
804 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
805 twitterApi.ApiConnection = mock.Object;
807 await twitterApi.UsersLookup(userIds: new[] { "11111", "22222" })
808 .ConfigureAwait(false);
814 public async Task UsersReportSpam_Test()
816 var mock = new Mock<IApiConnection>();
818 x.PostLazyAsync<TwitterUser>(
819 new Uri("users/report_spam.json", UriKind.Relative),
820 new Dictionary<string, string>
822 { "screen_name", "twitterapi" },
823 { "tweet_mode", "extended" },
826 .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
828 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
829 twitterApi.ApiConnection = mock.Object;
831 await twitterApi.UsersReportSpam(screenName: "twitterapi")
833 .ConfigureAwait(false);
839 public async Task FavoritesList_Test()
841 var mock = new Mock<IApiConnection>();
843 x.GetAsync<TwitterStatus[]>(
844 new Uri("favorites/list.json", UriKind.Relative),
845 new Dictionary<string, string>
847 { "include_entities", "true" },
848 { "include_ext_alt_text", "true" },
849 { "tweet_mode", "extended" },
852 { "since_id", "100" },
856 .ReturnsAsync(Array.Empty<TwitterStatus>());
858 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
859 twitterApi.ApiConnection = mock.Object;
861 await twitterApi.FavoritesList(200, maxId: 900L, sinceId: 100L)
862 .ConfigureAwait(false);
868 public async Task FavoritesCreate_Test()
870 var mock = new Mock<IApiConnection>();
872 x.PostLazyAsync<TwitterStatus>(
873 new Uri("favorites/create.json", UriKind.Relative),
874 new Dictionary<string, string>
877 { "tweet_mode", "extended" },
880 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
882 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
883 twitterApi.ApiConnection = mock.Object;
885 await twitterApi.FavoritesCreate(statusId: new("100"))
887 .ConfigureAwait(false);
893 public async Task FavoritesDestroy_Test()
895 var mock = new Mock<IApiConnection>();
897 x.PostLazyAsync<TwitterStatus>(
898 new Uri("favorites/destroy.json", UriKind.Relative),
899 new Dictionary<string, string>
902 { "tweet_mode", "extended" },
905 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
907 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
908 twitterApi.ApiConnection = mock.Object;
910 await twitterApi.FavoritesDestroy(statusId: new("100"))
912 .ConfigureAwait(false);
918 public async Task FriendshipsShow_Test()
920 var mock = new Mock<IApiConnection>();
922 x.GetAsync<TwitterFriendship>(
923 new Uri("friendships/show.json", UriKind.Relative),
924 new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } },
927 .ReturnsAsync(new TwitterFriendship());
929 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
930 twitterApi.ApiConnection = mock.Object;
932 await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi")
933 .ConfigureAwait(false);
939 public async Task FriendshipsCreate_Test()
941 var mock = new Mock<IApiConnection>();
943 x.PostLazyAsync<TwitterFriendship>(
944 new Uri("friendships/create.json", UriKind.Relative),
945 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
947 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
949 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
950 twitterApi.ApiConnection = mock.Object;
952 await twitterApi.FriendshipsCreate(screenName: "twitterapi")
954 .ConfigureAwait(false);
960 public async Task FriendshipsDestroy_Test()
962 var mock = new Mock<IApiConnection>();
964 x.PostLazyAsync<TwitterFriendship>(
965 new Uri("friendships/destroy.json", UriKind.Relative),
966 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
968 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
970 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
971 twitterApi.ApiConnection = mock.Object;
973 await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
975 .ConfigureAwait(false);
981 public async Task NoRetweetIds_Test()
983 var mock = new Mock<IApiConnection>();
986 new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
988 "/friendships/no_retweets/ids")
990 .ReturnsAsync(Array.Empty<long>());
992 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
993 twitterApi.ApiConnection = mock.Object;
995 await twitterApi.NoRetweetIds()
996 .ConfigureAwait(false);
1002 public async Task FollowersIds_Test()
1004 var mock = new Mock<IApiConnection>();
1006 x.GetAsync<TwitterIds>(
1007 new Uri("followers/ids.json", UriKind.Relative),
1008 new Dictionary<string, string> { { "cursor", "-1" } },
1011 .ReturnsAsync(new TwitterIds());
1013 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1014 twitterApi.ApiConnection = mock.Object;
1016 await twitterApi.FollowersIds(cursor: -1L)
1017 .ConfigureAwait(false);
1023 public async Task MutesUsersIds_Test()
1025 var mock = new Mock<IApiConnection>();
1027 x.GetAsync<TwitterIds>(
1028 new Uri("mutes/users/ids.json", UriKind.Relative),
1029 new Dictionary<string, string> { { "cursor", "-1" } },
1032 .ReturnsAsync(new TwitterIds());
1034 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1035 twitterApi.ApiConnection = mock.Object;
1037 await twitterApi.MutesUsersIds(cursor: -1L)
1038 .ConfigureAwait(false);
1044 public async Task BlocksIds_Test()
1046 var mock = new Mock<IApiConnection>();
1048 x.GetAsync<TwitterIds>(
1049 new Uri("blocks/ids.json", UriKind.Relative),
1050 new Dictionary<string, string> { { "cursor", "-1" } },
1053 .ReturnsAsync(new TwitterIds());
1055 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1056 twitterApi.ApiConnection = mock.Object;
1058 await twitterApi.BlocksIds(cursor: -1L)
1059 .ConfigureAwait(false);
1065 public async Task BlocksCreate_Test()
1067 var mock = new Mock<IApiConnection>();
1069 x.PostLazyAsync<TwitterUser>(
1070 new Uri("blocks/create.json", UriKind.Relative),
1071 new Dictionary<string, string>
1073 { "screen_name", "twitterapi" },
1074 { "tweet_mode", "extended" },
1077 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1079 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1080 twitterApi.ApiConnection = mock.Object;
1082 await twitterApi.BlocksCreate(screenName: "twitterapi")
1084 .ConfigureAwait(false);
1090 public async Task BlocksDestroy_Test()
1092 var mock = new Mock<IApiConnection>();
1094 x.PostLazyAsync<TwitterUser>(
1095 new Uri("blocks/destroy.json", UriKind.Relative),
1096 new Dictionary<string, string>
1098 { "screen_name", "twitterapi" },
1099 { "tweet_mode", "extended" },
1102 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1104 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1105 twitterApi.ApiConnection = mock.Object;
1107 await twitterApi.BlocksDestroy(screenName: "twitterapi")
1109 .ConfigureAwait(false);
1115 public async Task AccountVerifyCredentials_Test()
1117 var mock = new Mock<IApiConnection>();
1119 x.GetAsync<TwitterUser>(
1120 new Uri("account/verify_credentials.json", UriKind.Relative),
1121 new Dictionary<string, string>
1123 { "include_entities", "true" },
1124 { "include_ext_alt_text", "true" },
1125 { "tweet_mode", "extended" },
1127 "/account/verify_credentials")
1129 .ReturnsAsync(new TwitterUser
1132 ScreenName = "opentween",
1135 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1136 twitterApi.ApiConnection = mock.Object;
1138 await twitterApi.AccountVerifyCredentials()
1139 .ConfigureAwait(false);
1141 Assert.Equal(100L, twitterApi.CurrentUserId);
1142 Assert.Equal("opentween", twitterApi.CurrentScreenName);
1148 public async Task AccountUpdateProfile_Test()
1150 var mock = new Mock<IApiConnection>();
1152 x.PostLazyAsync<TwitterUser>(
1153 new Uri("account/update_profile.json", UriKind.Relative),
1154 new Dictionary<string, string>
1156 { "include_entities", "true" },
1157 { "include_ext_alt_text", "true" },
1158 { "tweet_mode", "extended" },
1160 { "url", "http://example.com/" },
1161 { "location", "Location" },
1162 { "description", "<script>alert(1)</script>" },
1165 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1167 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1168 twitterApi.ApiConnection = mock.Object;
1170 await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
1172 .ConfigureAwait(false);
1178 public async Task AccountUpdateProfileImage_Test()
1180 using var image = TestUtils.CreateDummyImage();
1181 using var media = new MemoryImageMediaItem(image);
1182 var mock = new Mock<IApiConnection>();
1184 x.PostLazyAsync<TwitterUser>(
1185 new Uri("account/update_profile_image.json", UriKind.Relative),
1186 new Dictionary<string, string>
1188 { "include_entities", "true" },
1189 { "include_ext_alt_text", "true" },
1190 { "tweet_mode", "extended" },
1192 new Dictionary<string, IMediaItem> { { "image", media } })
1194 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1196 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1197 twitterApi.ApiConnection = mock.Object;
1199 await twitterApi.AccountUpdateProfileImage(media)
1201 .ConfigureAwait(false);
1207 public async Task ApplicationRateLimitStatus_Test()
1209 var mock = new Mock<IApiConnection>();
1211 x.GetAsync<TwitterRateLimits>(
1212 new Uri("application/rate_limit_status.json", UriKind.Relative),
1214 "/application/rate_limit_status")
1216 .ReturnsAsync(new TwitterRateLimits());
1218 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1219 twitterApi.ApiConnection = mock.Object;
1221 await twitterApi.ApplicationRateLimitStatus()
1222 .ConfigureAwait(false);
1228 public async Task Configuration_Test()
1230 var mock = new Mock<IApiConnection>();
1232 x.GetAsync<TwitterConfiguration>(
1233 new Uri("help/configuration.json", UriKind.Relative),
1235 "/help/configuration")
1237 .ReturnsAsync(new TwitterConfiguration());
1239 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1240 twitterApi.ApiConnection = mock.Object;
1242 await twitterApi.Configuration()
1243 .ConfigureAwait(false);
1249 public async Task MediaUploadInit_Test()
1251 var mock = new Mock<IApiConnection>();
1253 x.PostLazyAsync<TwitterUploadMediaInit>(
1254 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1255 new Dictionary<string, string>
1257 { "command", "INIT" },
1258 { "total_bytes", "123456" },
1259 { "media_type", "image/png" },
1260 { "media_category", "dm_image" },
1263 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaInit()));
1265 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1266 twitterApi.ApiConnection = mock.Object;
1268 await twitterApi.MediaUploadInit(totalBytes: 123456L, mediaType: "image/png", mediaCategory: "dm_image")
1270 .ConfigureAwait(false);
1276 public async Task MediaUploadAppend_Test()
1278 using var image = TestUtils.CreateDummyImage();
1279 using var media = new MemoryImageMediaItem(image);
1280 var mock = new Mock<IApiConnection>();
1283 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1284 new Dictionary<string, string>
1286 { "command", "APPEND" },
1287 { "media_id", "11111" },
1288 { "segment_index", "1" },
1290 new Dictionary<string, IMediaItem> { { "media", media } })
1292 .Returns(Task.CompletedTask);
1294 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1295 twitterApi.ApiConnection = mock.Object;
1297 await twitterApi.MediaUploadAppend(mediaId: 11111L, segmentIndex: 1, media: media)
1298 .ConfigureAwait(false);
1304 public async Task MediaUploadFinalize_Test()
1306 var mock = new Mock<IApiConnection>();
1308 x.PostLazyAsync<TwitterUploadMediaResult>(
1309 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1310 new Dictionary<string, string>
1312 { "command", "FINALIZE" },
1313 { "media_id", "11111" },
1316 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
1318 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1319 twitterApi.ApiConnection = mock.Object;
1321 await twitterApi.MediaUploadFinalize(mediaId: 11111L)
1323 .ConfigureAwait(false);
1329 public async Task MediaUploadStatus_Test()
1331 var mock = new Mock<IApiConnection>();
1333 x.GetAsync<TwitterUploadMediaResult>(
1334 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1335 new Dictionary<string, string>
1337 { "command", "STATUS" },
1338 { "media_id", "11111" },
1342 .ReturnsAsync(new TwitterUploadMediaResult());
1344 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1345 twitterApi.ApiConnection = mock.Object;
1347 await twitterApi.MediaUploadStatus(mediaId: 11111L)
1348 .ConfigureAwait(false);
1354 public async Task MediaMetadataCreate_Test()
1356 var mock = new Mock<IApiConnection>();
1359 new Uri("https://upload.twitter.com/1.1/media/metadata/create.json", UriKind.Absolute),
1360 """{"media_id": "12345", "alt_text": {"text": "hogehoge"}}""")
1362 .Returns(Task.CompletedTask);
1364 using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret"));
1365 twitterApi.ApiConnection = mock.Object;
1367 await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge")
1368 .ConfigureAwait(false);