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();
55 var apiConnection = Assert.IsType<TwitterApiConnection>(twitterApi.Connection);
56 Assert.IsType<TwitterCredentialNone>(apiConnection.Credential);
58 var credential = new TwitterCredentialOAuth1(TwitterAppToken.GetDefault(), "*** AccessToken ***", "*** AccessSecret ***");
59 twitterApi.Initialize(credential, userId: 100L, screenName: "hogehoge");
61 apiConnection = Assert.IsType<TwitterApiConnection>(twitterApi.Connection);
62 Assert.Same(credential, apiConnection.Credential);
64 Assert.Equal(100L, twitterApi.CurrentUserId);
65 Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
67 // 複数回 Initialize を実行した場合は新たに TwitterApiConnection が生成される
68 var credential2 = new TwitterCredentialOAuth1(TwitterAppToken.GetDefault(), "*** AccessToken2 ***", "*** AccessSecret2 ***");
69 twitterApi.Initialize(credential2, userId: 200L, screenName: "foobar");
71 var oldApiConnection = apiConnection;
72 Assert.True(oldApiConnection.IsDisposed);
74 apiConnection = Assert.IsType<TwitterApiConnection>(twitterApi.Connection);
75 Assert.Same(credential2, apiConnection.Credential);
77 Assert.Equal(200L, twitterApi.CurrentUserId);
78 Assert.Equal("foobar", twitterApi.CurrentScreenName);
82 public async Task StatusesHomeTimeline_Test()
84 var mock = new Mock<IApiConnectionLegacy>();
86 x.GetAsync<TwitterStatus[]>(
87 new Uri("statuses/home_timeline.json", UriKind.Relative),
88 new Dictionary<string, string>
90 { "include_entities", "true" },
91 { "include_ext_alt_text", "true" },
92 { "tweet_mode", "extended" },
95 { "since_id", "100" },
97 "/statuses/home_timeline")
99 .ReturnsAsync(Array.Empty<TwitterStatus>());
101 using var twitterApi = new TwitterApi();
102 twitterApi.ApiConnection = mock.Object;
104 await twitterApi.StatusesHomeTimeline(200, maxId: new("900"), sinceId: new("100"));
110 public async Task StatusesMentionsTimeline_Test()
112 var mock = new Mock<IApiConnectionLegacy>();
114 x.GetAsync<TwitterStatus[]>(
115 new Uri("statuses/mentions_timeline.json", UriKind.Relative),
116 new Dictionary<string, string>
118 { "include_entities", "true" },
119 { "include_ext_alt_text", "true" },
120 { "tweet_mode", "extended" },
123 { "since_id", "100" },
125 "/statuses/mentions_timeline")
127 .ReturnsAsync(Array.Empty<TwitterStatus>());
129 using var twitterApi = new TwitterApi();
130 twitterApi.ApiConnection = mock.Object;
132 await twitterApi.StatusesMentionsTimeline(200, maxId: new("900"), sinceId: new("100"));
138 public async Task StatusesUserTimeline_Test()
140 var mock = new Mock<IApiConnectionLegacy>();
142 x.GetAsync<TwitterStatus[]>(
143 new Uri("statuses/user_timeline.json", UriKind.Relative),
144 new Dictionary<string, string>
146 { "screen_name", "twitterapi" },
147 { "include_rts", "true" },
148 { "include_entities", "true" },
149 { "include_ext_alt_text", "true" },
150 { "tweet_mode", "extended" },
153 { "since_id", "100" },
155 "/statuses/user_timeline")
157 .ReturnsAsync(Array.Empty<TwitterStatus>());
159 using var twitterApi = new TwitterApi();
160 twitterApi.ApiConnection = mock.Object;
162 await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: new("900"), sinceId: new("100"));
168 public async Task StatusesShow_Test()
170 var mock = new Mock<IApiConnectionLegacy>();
172 x.GetAsync<TwitterStatus>(
173 new Uri("statuses/show.json", UriKind.Relative),
174 new Dictionary<string, string>
177 { "include_entities", "true" },
178 { "include_ext_alt_text", "true" },
179 { "tweet_mode", "extended" },
181 "/statuses/show/:id")
183 .ReturnsAsync(new TwitterStatus { Id = 100L });
185 using var twitterApi = new TwitterApi();
186 twitterApi.ApiConnection = mock.Object;
188 await twitterApi.StatusesShow(statusId: new("100"));
194 public async Task StatusesLookup_Test()
196 var mock = new Mock<IApiConnectionLegacy>();
198 x.GetAsync<TwitterStatus[]>(
199 new Uri("statuses/lookup.json", UriKind.Relative),
200 new Dictionary<string, string>
203 { "include_entities", "true" },
204 { "include_ext_alt_text", "true" },
205 { "tweet_mode", "extended" },
210 .ReturnsAsync(Array.Empty<TwitterStatus>());
212 using var twitterApi = new TwitterApi();
213 twitterApi.ApiConnection = mock.Object;
215 await twitterApi.StatusesLookup(statusIds: new[] { "100", "200" });
221 public async Task StatusesUpdate_Test()
223 var mock = new Mock<IApiConnectionLegacy>();
225 x.PostLazyAsync<TwitterStatus>(
226 new Uri("statuses/update.json", UriKind.Relative),
227 new Dictionary<string, string>
229 { "status", "hogehoge" },
230 { "include_entities", "true" },
231 { "include_ext_alt_text", "true" },
232 { "tweet_mode", "extended" },
233 { "in_reply_to_status_id", "100" },
234 { "media_ids", "10,20" },
235 { "auto_populate_reply_metadata", "true" },
236 { "exclude_reply_user_ids", "100,200" },
237 { "attachment_url", "https://twitter.com/twitterapi/status/22634515958" },
240 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
242 using var twitterApi = new TwitterApi();
243 twitterApi.ApiConnection = mock.Object;
245 await twitterApi.StatusesUpdate(
247 replyToId: new("100"),
248 mediaIds: new[] { 10L, 20L },
249 autoPopulateReplyMetadata: true,
250 excludeReplyUserIds: new[] { 100L, 200L },
251 attachmentUrl: "https://twitter.com/twitterapi/status/22634515958"
259 public async Task StatusesUpdate_ExcludeReplyUserIdsEmptyTest()
261 var mock = new Mock<IApiConnectionLegacy>();
263 x.PostLazyAsync<TwitterStatus>(
264 new Uri("statuses/update.json", UriKind.Relative),
265 new Dictionary<string, string>
267 { "status", "hogehoge" },
268 { "include_entities", "true" },
269 { "include_ext_alt_text", "true" },
270 { "tweet_mode", "extended" },
271 // exclude_reply_user_ids は空の場合には送信されない
274 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
276 using var twitterApi = new TwitterApi();
277 twitterApi.ApiConnection = mock.Object;
279 await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: Array.Empty<long>())
286 public async Task StatusesDestroy_Test()
288 var mock = new Mock<IApiConnectionLegacy>();
290 x.PostLazyAsync<TwitterStatus>(
291 new Uri("statuses/destroy.json", UriKind.Relative),
292 new Dictionary<string, string> { { "id", "100" } })
294 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
296 using var twitterApi = new TwitterApi();
297 twitterApi.ApiConnection = mock.Object;
299 await twitterApi.StatusesDestroy(statusId: new("100"))
306 public async Task StatusesRetweet_Test()
308 var mock = new Mock<IApiConnectionLegacy>();
310 x.PostLazyAsync<TwitterStatus>(
311 new Uri("statuses/retweet.json", UriKind.Relative),
312 new Dictionary<string, string>
315 { "include_entities", "true" },
316 { "include_ext_alt_text", "true" },
317 { "tweet_mode", "extended" },
320 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
322 using var twitterApi = new TwitterApi();
323 twitterApi.ApiConnection = mock.Object;
325 await twitterApi.StatusesRetweet(new("100"))
332 public async Task SearchTweets_Test()
334 var mock = new Mock<IApiConnectionLegacy>();
336 x.GetAsync<TwitterSearchResult>(
337 new Uri("search/tweets.json", UriKind.Relative),
338 new Dictionary<string, string>
340 { "q", "from:twitterapi" },
341 { "result_type", "recent" },
342 { "include_entities", "true" },
343 { "include_ext_alt_text", "true" },
344 { "tweet_mode", "extended" },
348 { "since_id", "100" },
352 .ReturnsAsync(new TwitterSearchResult());
354 using var twitterApi = new TwitterApi();
355 twitterApi.ApiConnection = mock.Object;
357 await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: new("900"), sinceId: new("100"));
363 public async Task ListsOwnerships_Test()
365 var mock = new Mock<IApiConnectionLegacy>();
367 x.GetAsync<TwitterLists>(
368 new Uri("lists/ownerships.json", UriKind.Relative),
369 new Dictionary<string, string>
371 { "screen_name", "twitterapi" },
377 .ReturnsAsync(new TwitterLists());
379 using var twitterApi = new TwitterApi();
380 twitterApi.ApiConnection = mock.Object;
382 await twitterApi.ListsOwnerships("twitterapi", cursor: -1L, count: 100);
388 public async Task ListsSubscriptions_Test()
390 var mock = new Mock<IApiConnectionLegacy>();
392 x.GetAsync<TwitterLists>(
393 new Uri("lists/subscriptions.json", UriKind.Relative),
394 new Dictionary<string, string>
396 { "screen_name", "twitterapi" },
400 "/lists/subscriptions")
402 .ReturnsAsync(new TwitterLists());
404 using var twitterApi = new TwitterApi();
405 twitterApi.ApiConnection = mock.Object;
407 await twitterApi.ListsSubscriptions("twitterapi", cursor: -1L, count: 100);
413 public async Task ListsMemberships_Test()
415 var mock = new Mock<IApiConnectionLegacy>();
417 x.GetAsync<TwitterLists>(
418 new Uri("lists/memberships.json", UriKind.Relative),
419 new Dictionary<string, string>
421 { "screen_name", "twitterapi" },
424 { "filter_to_owned_lists", "true" },
426 "/lists/memberships")
428 .ReturnsAsync(new TwitterLists());
430 using var twitterApi = new TwitterApi();
431 twitterApi.ApiConnection = mock.Object;
433 await twitterApi.ListsMemberships("twitterapi", cursor: -1L, count: 100, filterToOwnedLists: true);
439 public async Task ListsCreate_Test()
441 var mock = new Mock<IApiConnectionLegacy>();
443 x.PostLazyAsync<TwitterList>(
444 new Uri("lists/create.json", UriKind.Relative),
445 new Dictionary<string, string>
447 { "name", "hogehoge" },
448 { "description", "aaaa" },
449 { "mode", "private" },
452 .ReturnsAsync(LazyJson.Create(new TwitterList()));
454 using var twitterApi = new TwitterApi();
455 twitterApi.ApiConnection = mock.Object;
457 await twitterApi.ListsCreate("hogehoge", description: "aaaa", @private: true)
464 public async Task ListsUpdate_Test()
466 var mock = new Mock<IApiConnectionLegacy>();
468 x.PostLazyAsync<TwitterList>(
469 new Uri("lists/update.json", UriKind.Relative),
470 new Dictionary<string, string>
472 { "list_id", "12345" },
473 { "name", "hogehoge" },
474 { "description", "aaaa" },
475 { "mode", "private" },
478 .ReturnsAsync(LazyJson.Create(new TwitterList()));
480 using var twitterApi = new TwitterApi();
481 twitterApi.ApiConnection = mock.Object;
483 await twitterApi.ListsUpdate(12345L, name: "hogehoge", description: "aaaa", @private: true)
490 public async Task ListsDestroy_Test()
492 var mock = new Mock<IApiConnectionLegacy>();
494 x.PostLazyAsync<TwitterList>(
495 new Uri("lists/destroy.json", UriKind.Relative),
496 new Dictionary<string, string>
498 { "list_id", "12345" },
501 .ReturnsAsync(LazyJson.Create(new TwitterList()));
503 using var twitterApi = new TwitterApi();
504 twitterApi.ApiConnection = mock.Object;
506 await twitterApi.ListsDestroy(12345L)
513 public async Task ListsStatuses_Test()
515 var mock = new Mock<IApiConnectionLegacy>();
517 x.GetAsync<TwitterStatus[]>(
518 new Uri("lists/statuses.json", UriKind.Relative),
519 new Dictionary<string, string>
521 { "list_id", "12345" },
522 { "include_entities", "true" },
523 { "include_ext_alt_text", "true" },
524 { "tweet_mode", "extended" },
527 { "since_id", "100" },
528 { "include_rts", "true" },
532 .ReturnsAsync(Array.Empty<TwitterStatus>());
534 using var twitterApi = new TwitterApi();
535 twitterApi.ApiConnection = mock.Object;
537 await twitterApi.ListsStatuses(12345L, count: 200, maxId: new("900"), sinceId: new("100"), includeRTs: true);
543 public async Task ListsMembers_Test()
545 var mock = new Mock<IApiConnectionLegacy>();
547 x.GetAsync<TwitterUsers>(
548 new Uri("lists/members.json", UriKind.Relative),
549 new Dictionary<string, string>
551 { "list_id", "12345" },
552 { "include_entities", "true" },
553 { "include_ext_alt_text", "true" },
554 { "tweet_mode", "extended" },
559 .ReturnsAsync(new TwitterUsers());
561 using var twitterApi = new TwitterApi();
562 twitterApi.ApiConnection = mock.Object;
564 await twitterApi.ListsMembers(12345L, cursor: -1);
570 public async Task ListsMembersShow_Test()
572 var mock = new Mock<IApiConnectionLegacy>();
574 x.GetAsync<TwitterUser>(
575 new Uri("lists/members/show.json", UriKind.Relative),
576 new Dictionary<string, string>
578 { "list_id", "12345" },
579 { "screen_name", "twitterapi" },
580 { "include_entities", "true" },
581 { "include_ext_alt_text", "true" },
582 { "tweet_mode", "extended" },
584 "/lists/members/show")
586 .ReturnsAsync(new TwitterUser());
588 using var twitterApi = new TwitterApi();
589 twitterApi.ApiConnection = mock.Object;
591 await twitterApi.ListsMembersShow(12345L, "twitterapi");
597 public async Task ListsMembersCreate_Test()
599 var mock = new Mock<IApiConnectionLegacy>();
601 x.PostLazyAsync<TwitterUser>(
602 new Uri("lists/members/create.json", UriKind.Relative),
603 new Dictionary<string, string>
605 { "list_id", "12345" },
606 { "screen_name", "twitterapi" },
607 { "include_entities", "true" },
608 { "include_ext_alt_text", "true" },
609 { "tweet_mode", "extended" },
612 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
614 using var twitterApi = new TwitterApi();
615 twitterApi.ApiConnection = mock.Object;
617 await twitterApi.ListsMembersCreate(12345L, "twitterapi")
624 public async Task ListsMembersDestroy_Test()
626 var mock = new Mock<IApiConnectionLegacy>();
628 x.PostLazyAsync<TwitterUser>(
629 new Uri("lists/members/destroy.json", UriKind.Relative),
630 new Dictionary<string, string>
632 { "list_id", "12345" },
633 { "screen_name", "twitterapi" },
634 { "include_entities", "true" },
635 { "include_ext_alt_text", "true" },
636 { "tweet_mode", "extended" },
639 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
641 using var twitterApi = new TwitterApi();
642 twitterApi.ApiConnection = mock.Object;
644 await twitterApi.ListsMembersDestroy(12345L, "twitterapi")
651 public async Task DirectMessagesEventsList_Test()
653 var mock = new Mock<IApiConnectionLegacy>();
655 x.GetAsync<TwitterMessageEventList>(
656 new Uri("direct_messages/events/list.json", UriKind.Relative),
657 new Dictionary<string, string>
660 { "cursor", "12345abcdefg" },
662 "/direct_messages/events/list")
664 .ReturnsAsync(new TwitterMessageEventList());
666 using var twitterApi = new TwitterApi();
667 twitterApi.ApiConnection = mock.Object;
669 await twitterApi.DirectMessagesEventsList(count: 50, cursor: "12345abcdefg");
675 public async Task DirectMessagesEventsNew_Test()
677 var mock = new Mock<IApiConnectionLegacy>();
678 var responseText = """
681 "type": "message_create",
684 "recipient_id": "12345"
700 x.PostJsonAsync<TwitterMessageEventSingle>(
701 new Uri("direct_messages/events/new.json", UriKind.Relative),
704 .ReturnsAsync(LazyJson.Create(new TwitterMessageEventSingle()));
706 using var twitterApi = new TwitterApi();
707 twitterApi.ApiConnection = mock.Object;
709 await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge", mediaId: 67890L);
715 public async Task DirectMessagesEventsDestroy_Test()
717 var mock = new Mock<IApiConnectionLegacy>();
720 new Uri("direct_messages/events/destroy.json?id=100", UriKind.Relative))
722 .Returns(Task.CompletedTask);
724 using var twitterApi = new TwitterApi();
725 twitterApi.ApiConnection = mock.Object;
727 await twitterApi.DirectMessagesEventsDestroy(eventId: new("100"));
733 public async Task UsersShow_Test()
735 var mock = new Mock<IApiConnectionLegacy>();
737 x.GetAsync<TwitterUser>(
738 new Uri("users/show.json", UriKind.Relative),
739 new Dictionary<string, string>
741 { "screen_name", "twitterapi" },
742 { "include_entities", "true" },
743 { "include_ext_alt_text", "true" },
744 { "tweet_mode", "extended" },
748 .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
750 using var twitterApi = new TwitterApi();
751 twitterApi.ApiConnection = mock.Object;
753 await twitterApi.UsersShow(screenName: "twitterapi");
759 public async Task UsersLookup_Test()
761 var mock = new Mock<IApiConnectionLegacy>();
763 x.GetAsync<TwitterUser[]>(
764 new Uri("users/lookup.json", UriKind.Relative),
765 new Dictionary<string, string>
767 { "user_id", "11111,22222" },
768 { "include_entities", "true" },
769 { "include_ext_alt_text", "true" },
770 { "tweet_mode", "extended" },
774 .ReturnsAsync(Array.Empty<TwitterUser>());
776 using var twitterApi = new TwitterApi();
777 twitterApi.ApiConnection = mock.Object;
779 await twitterApi.UsersLookup(userIds: new[] { "11111", "22222" });
785 public async Task UsersReportSpam_Test()
787 var mock = new Mock<IApiConnectionLegacy>();
789 x.PostLazyAsync<TwitterUser>(
790 new Uri("users/report_spam.json", UriKind.Relative),
791 new Dictionary<string, string>
793 { "screen_name", "twitterapi" },
794 { "tweet_mode", "extended" },
797 .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
799 using var twitterApi = new TwitterApi();
800 twitterApi.ApiConnection = mock.Object;
802 await twitterApi.UsersReportSpam(screenName: "twitterapi")
809 public async Task FavoritesList_Test()
811 var mock = new Mock<IApiConnectionLegacy>();
813 x.GetAsync<TwitterStatus[]>(
814 new Uri("favorites/list.json", UriKind.Relative),
815 new Dictionary<string, string>
817 { "include_entities", "true" },
818 { "include_ext_alt_text", "true" },
819 { "tweet_mode", "extended" },
822 { "since_id", "100" },
826 .ReturnsAsync(Array.Empty<TwitterStatus>());
828 using var twitterApi = new TwitterApi();
829 twitterApi.ApiConnection = mock.Object;
831 await twitterApi.FavoritesList(200, maxId: 900L, sinceId: 100L);
837 public async Task FavoritesCreate_Test()
839 var mock = new Mock<IApiConnectionLegacy>();
841 x.PostLazyAsync<TwitterStatus>(
842 new Uri("favorites/create.json", UriKind.Relative),
843 new Dictionary<string, string>
846 { "tweet_mode", "extended" },
849 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
851 using var twitterApi = new TwitterApi();
852 twitterApi.ApiConnection = mock.Object;
854 await twitterApi.FavoritesCreate(statusId: new("100"))
861 public async Task FavoritesDestroy_Test()
863 var mock = new Mock<IApiConnectionLegacy>();
865 x.PostLazyAsync<TwitterStatus>(
866 new Uri("favorites/destroy.json", UriKind.Relative),
867 new Dictionary<string, string>
870 { "tweet_mode", "extended" },
873 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
875 using var twitterApi = new TwitterApi();
876 twitterApi.ApiConnection = mock.Object;
878 await twitterApi.FavoritesDestroy(statusId: new("100"))
885 public async Task FriendshipsShow_Test()
887 var mock = new Mock<IApiConnectionLegacy>();
889 x.GetAsync<TwitterFriendship>(
890 new Uri("friendships/show.json", UriKind.Relative),
891 new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } },
894 .ReturnsAsync(new TwitterFriendship());
896 using var twitterApi = new TwitterApi();
897 twitterApi.ApiConnection = mock.Object;
899 await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi");
905 public async Task FriendshipsCreate_Test()
907 var mock = new Mock<IApiConnectionLegacy>();
909 x.PostLazyAsync<TwitterFriendship>(
910 new Uri("friendships/create.json", UriKind.Relative),
911 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
913 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
915 using var twitterApi = new TwitterApi();
916 twitterApi.ApiConnection = mock.Object;
918 await twitterApi.FriendshipsCreate(screenName: "twitterapi")
925 public async Task FriendshipsDestroy_Test()
927 var mock = new Mock<IApiConnectionLegacy>();
929 x.PostLazyAsync<TwitterFriendship>(
930 new Uri("friendships/destroy.json", UriKind.Relative),
931 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
933 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
935 using var twitterApi = new TwitterApi();
936 twitterApi.ApiConnection = mock.Object;
938 await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
945 public async Task NoRetweetIds_Test()
947 var mock = new Mock<IApiConnectionLegacy>();
950 new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
952 "/friendships/no_retweets/ids")
954 .ReturnsAsync(Array.Empty<long>());
956 using var twitterApi = new TwitterApi();
957 twitterApi.ApiConnection = mock.Object;
959 await twitterApi.NoRetweetIds();
965 public async Task FollowersIds_Test()
967 var mock = new Mock<IApiConnectionLegacy>();
969 x.GetAsync<TwitterIds>(
970 new Uri("followers/ids.json", UriKind.Relative),
971 new Dictionary<string, string> { { "cursor", "-1" } },
974 .ReturnsAsync(new TwitterIds());
976 using var twitterApi = new TwitterApi();
977 twitterApi.ApiConnection = mock.Object;
979 await twitterApi.FollowersIds(cursor: -1L);
985 public async Task MutesUsersIds_Test()
987 var mock = new Mock<IApiConnectionLegacy>();
989 x.GetAsync<TwitterIds>(
990 new Uri("mutes/users/ids.json", UriKind.Relative),
991 new Dictionary<string, string> { { "cursor", "-1" } },
994 .ReturnsAsync(new TwitterIds());
996 using var twitterApi = new TwitterApi();
997 twitterApi.ApiConnection = mock.Object;
999 await twitterApi.MutesUsersIds(cursor: -1L);
1005 public async Task BlocksIds_Test()
1007 var mock = new Mock<IApiConnectionLegacy>();
1009 x.GetAsync<TwitterIds>(
1010 new Uri("blocks/ids.json", UriKind.Relative),
1011 new Dictionary<string, string> { { "cursor", "-1" } },
1014 .ReturnsAsync(new TwitterIds());
1016 using var twitterApi = new TwitterApi();
1017 twitterApi.ApiConnection = mock.Object;
1019 await twitterApi.BlocksIds(cursor: -1L);
1025 public async Task BlocksCreate_Test()
1027 var mock = new Mock<IApiConnectionLegacy>();
1029 x.PostLazyAsync<TwitterUser>(
1030 new Uri("blocks/create.json", UriKind.Relative),
1031 new Dictionary<string, string>
1033 { "screen_name", "twitterapi" },
1034 { "tweet_mode", "extended" },
1037 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1039 using var twitterApi = new TwitterApi();
1040 twitterApi.ApiConnection = mock.Object;
1042 await twitterApi.BlocksCreate(screenName: "twitterapi")
1049 public async Task BlocksDestroy_Test()
1051 var mock = new Mock<IApiConnectionLegacy>();
1053 x.PostLazyAsync<TwitterUser>(
1054 new Uri("blocks/destroy.json", UriKind.Relative),
1055 new Dictionary<string, string>
1057 { "screen_name", "twitterapi" },
1058 { "tweet_mode", "extended" },
1061 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1063 using var twitterApi = new TwitterApi();
1064 twitterApi.ApiConnection = mock.Object;
1066 await twitterApi.BlocksDestroy(screenName: "twitterapi")
1073 public async Task AccountVerifyCredentials_Test()
1075 var mock = new Mock<IApiConnectionLegacy>();
1077 x.GetAsync<TwitterUser>(
1078 new Uri("account/verify_credentials.json", UriKind.Relative),
1079 new Dictionary<string, string>
1081 { "include_entities", "true" },
1082 { "include_ext_alt_text", "true" },
1083 { "tweet_mode", "extended" },
1085 "/account/verify_credentials")
1087 .ReturnsAsync(new TwitterUser
1090 ScreenName = "opentween",
1093 using var twitterApi = new TwitterApi();
1094 twitterApi.ApiConnection = mock.Object;
1096 await twitterApi.AccountVerifyCredentials();
1098 Assert.Equal(100L, twitterApi.CurrentUserId);
1099 Assert.Equal("opentween", twitterApi.CurrentScreenName);
1105 public async Task AccountUpdateProfile_Test()
1107 var mock = new Mock<IApiConnectionLegacy>();
1109 x.PostLazyAsync<TwitterUser>(
1110 new Uri("account/update_profile.json", UriKind.Relative),
1111 new Dictionary<string, string>
1113 { "include_entities", "true" },
1114 { "include_ext_alt_text", "true" },
1115 { "tweet_mode", "extended" },
1117 { "url", "http://example.com/" },
1118 { "location", "Location" },
1119 { "description", "<script>alert(1)</script>" },
1122 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1124 using var twitterApi = new TwitterApi();
1125 twitterApi.ApiConnection = mock.Object;
1127 await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
1134 public async Task AccountUpdateProfileImage_Test()
1136 using var image = TestUtils.CreateDummyImage();
1137 using var media = new MemoryImageMediaItem(image);
1138 var mock = new Mock<IApiConnectionLegacy>();
1140 x.PostLazyAsync<TwitterUser>(
1141 new Uri("account/update_profile_image.json", UriKind.Relative),
1142 new Dictionary<string, string>
1144 { "include_entities", "true" },
1145 { "include_ext_alt_text", "true" },
1146 { "tweet_mode", "extended" },
1148 new Dictionary<string, IMediaItem> { { "image", media } })
1150 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1152 using var twitterApi = new TwitterApi();
1153 twitterApi.ApiConnection = mock.Object;
1155 await twitterApi.AccountUpdateProfileImage(media)
1162 public async Task ApplicationRateLimitStatus_Test()
1164 var mock = new Mock<IApiConnectionLegacy>();
1166 x.GetAsync<TwitterRateLimits>(
1167 new Uri("application/rate_limit_status.json", UriKind.Relative),
1169 "/application/rate_limit_status")
1171 .ReturnsAsync(new TwitterRateLimits());
1173 using var twitterApi = new TwitterApi();
1174 twitterApi.ApiConnection = mock.Object;
1176 await twitterApi.ApplicationRateLimitStatus();
1182 public async Task Configuration_Test()
1184 var mock = new Mock<IApiConnectionLegacy>();
1186 x.GetAsync<TwitterConfiguration>(
1187 new Uri("help/configuration.json", UriKind.Relative),
1189 "/help/configuration")
1191 .ReturnsAsync(new TwitterConfiguration());
1193 using var twitterApi = new TwitterApi();
1194 twitterApi.ApiConnection = mock.Object;
1196 await twitterApi.Configuration();
1202 public async Task MediaUploadInit_Test()
1204 var mock = new Mock<IApiConnectionLegacy>();
1206 x.PostLazyAsync<TwitterUploadMediaInit>(
1207 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1208 new Dictionary<string, string>
1210 { "command", "INIT" },
1211 { "total_bytes", "123456" },
1212 { "media_type", "image/png" },
1213 { "media_category", "dm_image" },
1216 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaInit()));
1218 using var twitterApi = new TwitterApi();
1219 twitterApi.ApiConnection = mock.Object;
1221 await twitterApi.MediaUploadInit(totalBytes: 123456L, mediaType: "image/png", mediaCategory: "dm_image")
1228 public async Task MediaUploadAppend_Test()
1230 using var image = TestUtils.CreateDummyImage();
1231 using var media = new MemoryImageMediaItem(image);
1232 var mock = new Mock<IApiConnectionLegacy>();
1235 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1236 new Dictionary<string, string>
1238 { "command", "APPEND" },
1239 { "media_id", "11111" },
1240 { "segment_index", "1" },
1242 new Dictionary<string, IMediaItem> { { "media", media } })
1244 .Returns(Task.CompletedTask);
1246 using var twitterApi = new TwitterApi();
1247 twitterApi.ApiConnection = mock.Object;
1249 await twitterApi.MediaUploadAppend(mediaId: 11111L, segmentIndex: 1, media: media);
1255 public async Task MediaUploadFinalize_Test()
1257 var mock = new Mock<IApiConnectionLegacy>();
1259 x.PostLazyAsync<TwitterUploadMediaResult>(
1260 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1261 new Dictionary<string, string>
1263 { "command", "FINALIZE" },
1264 { "media_id", "11111" },
1267 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
1269 using var twitterApi = new TwitterApi();
1270 twitterApi.ApiConnection = mock.Object;
1272 await twitterApi.MediaUploadFinalize(mediaId: 11111L)
1279 public async Task MediaUploadStatus_Test()
1281 var mock = new Mock<IApiConnectionLegacy>();
1283 x.GetAsync<TwitterUploadMediaResult>(
1284 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1285 new Dictionary<string, string>
1287 { "command", "STATUS" },
1288 { "media_id", "11111" },
1292 .ReturnsAsync(new TwitterUploadMediaResult());
1294 using var twitterApi = new TwitterApi();
1295 twitterApi.ApiConnection = mock.Object;
1297 await twitterApi.MediaUploadStatus(mediaId: 11111L);
1303 public async Task MediaMetadataCreate_Test()
1305 var mock = new Mock<IApiConnectionLegacy>();
1308 new Uri("https://upload.twitter.com/1.1/media/metadata/create.json", UriKind.Absolute),
1309 """{"media_id": "12345", "alt_text": {"text": "hogehoge"}}""")
1313 using var twitterApi = new TwitterApi();
1314 twitterApi.ApiConnection = mock.Object;
1316 await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge");