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;
27 using System.Net.Http;
28 using System.Reflection;
29 using System.Runtime.InteropServices;
31 using System.Threading.Tasks;
33 using OpenTween.Api.DataModel;
34 using OpenTween.Connection;
37 namespace OpenTween.Api
39 public class TwitterApiTest
41 public TwitterApiTest()
42 => this.MyCommonSetup();
44 private void MyCommonSetup()
46 var mockAssembly = new Mock<_Assembly>();
47 mockAssembly.Setup(m => m.GetName()).Returns(new AssemblyName("OpenTween"));
49 MyCommon.EntryAssembly = mockAssembly.Object;
53 public void Initialize_Test()
55 using var twitterApi = new TwitterApi();
56 var apiConnection = Assert.IsType<TwitterApiConnection>(twitterApi.Connection);
57 Assert.IsType<TwitterCredentialNone>(apiConnection.Credential);
59 var credential = new TwitterCredentialOAuth1(TwitterAppToken.GetDefault(), "*** AccessToken ***", "*** AccessSecret ***");
60 twitterApi.Initialize(credential, userId: 100L, screenName: "hogehoge");
62 apiConnection = Assert.IsType<TwitterApiConnection>(twitterApi.Connection);
63 Assert.Same(credential, apiConnection.Credential);
65 Assert.Equal(100L, twitterApi.CurrentUserId);
66 Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
68 // 複数回 Initialize を実行した場合は新たに TwitterApiConnection が生成される
69 var credential2 = new TwitterCredentialOAuth1(TwitterAppToken.GetDefault(), "*** AccessToken2 ***", "*** AccessSecret2 ***");
70 twitterApi.Initialize(credential2, userId: 200L, screenName: "foobar");
72 var oldApiConnection = apiConnection;
73 Assert.True(oldApiConnection.IsDisposed);
75 apiConnection = Assert.IsType<TwitterApiConnection>(twitterApi.Connection);
76 Assert.Same(credential2, apiConnection.Credential);
78 Assert.Equal(200L, twitterApi.CurrentUserId);
79 Assert.Equal("foobar", twitterApi.CurrentScreenName);
83 public async Task StatusesHomeTimeline_Test()
85 var mock = new Mock<IApiConnectionLegacy>();
87 x.GetAsync<TwitterStatus[]>(
88 new Uri("statuses/home_timeline.json", UriKind.Relative),
89 new Dictionary<string, string>
91 { "include_entities", "true" },
92 { "include_ext_alt_text", "true" },
93 { "tweet_mode", "extended" },
96 { "since_id", "100" },
98 "/statuses/home_timeline")
100 .ReturnsAsync(Array.Empty<TwitterStatus>());
102 using var twitterApi = new TwitterApi();
103 twitterApi.ApiConnection = mock.Object;
105 await twitterApi.StatusesHomeTimeline(200, maxId: new("900"), sinceId: new("100"));
111 public async Task StatusesMentionsTimeline_Test()
113 var mock = new Mock<IApiConnectionLegacy>();
115 x.GetAsync<TwitterStatus[]>(
116 new Uri("statuses/mentions_timeline.json", UriKind.Relative),
117 new Dictionary<string, string>
119 { "include_entities", "true" },
120 { "include_ext_alt_text", "true" },
121 { "tweet_mode", "extended" },
124 { "since_id", "100" },
126 "/statuses/mentions_timeline")
128 .ReturnsAsync(Array.Empty<TwitterStatus>());
130 using var twitterApi = new TwitterApi();
131 twitterApi.ApiConnection = mock.Object;
133 await twitterApi.StatusesMentionsTimeline(200, maxId: new("900"), sinceId: new("100"));
139 public async Task StatusesUserTimeline_Test()
141 var mock = new Mock<IApiConnectionLegacy>();
143 x.GetAsync<TwitterStatus[]>(
144 new Uri("statuses/user_timeline.json", UriKind.Relative),
145 new Dictionary<string, string>
147 { "screen_name", "twitterapi" },
148 { "include_rts", "true" },
149 { "include_entities", "true" },
150 { "include_ext_alt_text", "true" },
151 { "tweet_mode", "extended" },
154 { "since_id", "100" },
156 "/statuses/user_timeline")
158 .ReturnsAsync(Array.Empty<TwitterStatus>());
160 using var twitterApi = new TwitterApi();
161 twitterApi.ApiConnection = mock.Object;
163 await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: new("900"), sinceId: new("100"));
169 public async Task StatusesShow_Test()
171 var mock = new Mock<IApiConnectionLegacy>();
173 x.GetAsync<TwitterStatus>(
174 new Uri("statuses/show.json", UriKind.Relative),
175 new Dictionary<string, string>
178 { "include_entities", "true" },
179 { "include_ext_alt_text", "true" },
180 { "tweet_mode", "extended" },
182 "/statuses/show/:id")
184 .ReturnsAsync(new TwitterStatus { Id = 100L });
186 using var twitterApi = new TwitterApi();
187 twitterApi.ApiConnection = mock.Object;
189 await twitterApi.StatusesShow(statusId: new("100"));
195 public async Task StatusesLookup_Test()
197 var mock = new Mock<IApiConnectionLegacy>();
199 x.GetAsync<TwitterStatus[]>(
200 new Uri("statuses/lookup.json", UriKind.Relative),
201 new Dictionary<string, string>
204 { "include_entities", "true" },
205 { "include_ext_alt_text", "true" },
206 { "tweet_mode", "extended" },
211 .ReturnsAsync(Array.Empty<TwitterStatus>());
213 using var twitterApi = new TwitterApi();
214 twitterApi.ApiConnection = mock.Object;
216 await twitterApi.StatusesLookup(statusIds: new[] { "100", "200" });
222 public async Task StatusesUpdate_Test()
224 var mock = new Mock<IApiConnectionLegacy>();
226 x.PostLazyAsync<TwitterStatus>(
227 new Uri("statuses/update.json", UriKind.Relative),
228 new Dictionary<string, string>
230 { "status", "hogehoge" },
231 { "include_entities", "true" },
232 { "include_ext_alt_text", "true" },
233 { "tweet_mode", "extended" },
234 { "in_reply_to_status_id", "100" },
235 { "media_ids", "10,20" },
236 { "auto_populate_reply_metadata", "true" },
237 { "exclude_reply_user_ids", "100,200" },
238 { "attachment_url", "https://twitter.com/twitterapi/status/22634515958" },
241 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
243 using var twitterApi = new TwitterApi();
244 twitterApi.ApiConnection = mock.Object;
246 await twitterApi.StatusesUpdate(
248 replyToId: new("100"),
249 mediaIds: new[] { 10L, 20L },
250 autoPopulateReplyMetadata: true,
251 excludeReplyUserIds: new[] { 100L, 200L },
252 attachmentUrl: "https://twitter.com/twitterapi/status/22634515958"
260 public async Task StatusesUpdate_ExcludeReplyUserIdsEmptyTest()
262 var mock = new Mock<IApiConnectionLegacy>();
264 x.PostLazyAsync<TwitterStatus>(
265 new Uri("statuses/update.json", UriKind.Relative),
266 new Dictionary<string, string>
268 { "status", "hogehoge" },
269 { "include_entities", "true" },
270 { "include_ext_alt_text", "true" },
271 { "tweet_mode", "extended" },
272 // exclude_reply_user_ids は空の場合には送信されない
275 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
277 using var twitterApi = new TwitterApi();
278 twitterApi.ApiConnection = mock.Object;
280 await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: Array.Empty<long>())
287 public async Task StatusesDestroy_Test()
289 var mock = new Mock<IApiConnectionLegacy>();
291 x.PostLazyAsync<TwitterStatus>(
292 new Uri("statuses/destroy.json", UriKind.Relative),
293 new Dictionary<string, string> { { "id", "100" } })
295 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
297 using var twitterApi = new TwitterApi();
298 twitterApi.ApiConnection = mock.Object;
300 await twitterApi.StatusesDestroy(statusId: new("100"))
307 public async Task StatusesRetweet_Test()
309 var mock = new Mock<IApiConnectionLegacy>();
311 x.PostLazyAsync<TwitterStatus>(
312 new Uri("statuses/retweet.json", UriKind.Relative),
313 new Dictionary<string, string>
316 { "include_entities", "true" },
317 { "include_ext_alt_text", "true" },
318 { "tweet_mode", "extended" },
321 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
323 using var twitterApi = new TwitterApi();
324 twitterApi.ApiConnection = mock.Object;
326 await twitterApi.StatusesRetweet(new("100"))
333 public async Task SearchTweets_Test()
335 var mock = new Mock<IApiConnectionLegacy>();
337 x.GetAsync<TwitterSearchResult>(
338 new Uri("search/tweets.json", UriKind.Relative),
339 new Dictionary<string, string>
341 { "q", "from:twitterapi" },
342 { "result_type", "recent" },
343 { "include_entities", "true" },
344 { "include_ext_alt_text", "true" },
345 { "tweet_mode", "extended" },
349 { "since_id", "100" },
353 .ReturnsAsync(new TwitterSearchResult());
355 using var twitterApi = new TwitterApi();
356 twitterApi.ApiConnection = mock.Object;
358 await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: new("900"), sinceId: new("100"));
364 public async Task ListsOwnerships_Test()
366 var mock = new Mock<IApiConnectionLegacy>();
368 x.GetAsync<TwitterLists>(
369 new Uri("lists/ownerships.json", UriKind.Relative),
370 new Dictionary<string, string>
372 { "screen_name", "twitterapi" },
378 .ReturnsAsync(new TwitterLists());
380 using var twitterApi = new TwitterApi();
381 twitterApi.ApiConnection = mock.Object;
383 await twitterApi.ListsOwnerships("twitterapi", cursor: -1L, count: 100);
389 public async Task ListsSubscriptions_Test()
391 var mock = new Mock<IApiConnectionLegacy>();
393 x.GetAsync<TwitterLists>(
394 new Uri("lists/subscriptions.json", UriKind.Relative),
395 new Dictionary<string, string>
397 { "screen_name", "twitterapi" },
401 "/lists/subscriptions")
403 .ReturnsAsync(new TwitterLists());
405 using var twitterApi = new TwitterApi();
406 twitterApi.ApiConnection = mock.Object;
408 await twitterApi.ListsSubscriptions("twitterapi", cursor: -1L, count: 100);
414 public async Task ListsMemberships_Test()
416 var mock = new Mock<IApiConnectionLegacy>();
418 x.GetAsync<TwitterLists>(
419 new Uri("lists/memberships.json", UriKind.Relative),
420 new Dictionary<string, string>
422 { "screen_name", "twitterapi" },
425 { "filter_to_owned_lists", "true" },
427 "/lists/memberships")
429 .ReturnsAsync(new TwitterLists());
431 using var twitterApi = new TwitterApi();
432 twitterApi.ApiConnection = mock.Object;
434 await twitterApi.ListsMemberships("twitterapi", cursor: -1L, count: 100, filterToOwnedLists: true);
440 public async Task ListsCreate_Test()
442 var mock = new Mock<IApiConnectionLegacy>();
444 x.PostLazyAsync<TwitterList>(
445 new Uri("lists/create.json", UriKind.Relative),
446 new Dictionary<string, string>
448 { "name", "hogehoge" },
449 { "description", "aaaa" },
450 { "mode", "private" },
453 .ReturnsAsync(LazyJson.Create(new TwitterList()));
455 using var twitterApi = new TwitterApi();
456 twitterApi.ApiConnection = mock.Object;
458 await twitterApi.ListsCreate("hogehoge", description: "aaaa", @private: true)
465 public async Task ListsUpdate_Test()
467 var mock = new Mock<IApiConnectionLegacy>();
469 x.PostLazyAsync<TwitterList>(
470 new Uri("lists/update.json", UriKind.Relative),
471 new Dictionary<string, string>
473 { "list_id", "12345" },
474 { "name", "hogehoge" },
475 { "description", "aaaa" },
476 { "mode", "private" },
479 .ReturnsAsync(LazyJson.Create(new TwitterList()));
481 using var twitterApi = new TwitterApi();
482 twitterApi.ApiConnection = mock.Object;
484 await twitterApi.ListsUpdate(12345L, name: "hogehoge", description: "aaaa", @private: true)
491 public async Task ListsDestroy_Test()
493 var mock = new Mock<IApiConnectionLegacy>();
495 x.PostLazyAsync<TwitterList>(
496 new Uri("lists/destroy.json", UriKind.Relative),
497 new Dictionary<string, string>
499 { "list_id", "12345" },
502 .ReturnsAsync(LazyJson.Create(new TwitterList()));
504 using var twitterApi = new TwitterApi();
505 twitterApi.ApiConnection = mock.Object;
507 await twitterApi.ListsDestroy(12345L)
514 public async Task ListsStatuses_Test()
516 var mock = new Mock<IApiConnectionLegacy>();
518 x.GetAsync<TwitterStatus[]>(
519 new Uri("lists/statuses.json", UriKind.Relative),
520 new Dictionary<string, string>
522 { "list_id", "12345" },
523 { "include_entities", "true" },
524 { "include_ext_alt_text", "true" },
525 { "tweet_mode", "extended" },
528 { "since_id", "100" },
529 { "include_rts", "true" },
533 .ReturnsAsync(Array.Empty<TwitterStatus>());
535 using var twitterApi = new TwitterApi();
536 twitterApi.ApiConnection = mock.Object;
538 await twitterApi.ListsStatuses(12345L, count: 200, maxId: new("900"), sinceId: new("100"), includeRTs: true);
544 public async Task ListsMembers_Test()
546 var mock = new Mock<IApiConnectionLegacy>();
548 x.GetAsync<TwitterUsers>(
549 new Uri("lists/members.json", UriKind.Relative),
550 new Dictionary<string, string>
552 { "list_id", "12345" },
553 { "include_entities", "true" },
554 { "include_ext_alt_text", "true" },
555 { "tweet_mode", "extended" },
560 .ReturnsAsync(new TwitterUsers());
562 using var twitterApi = new TwitterApi();
563 twitterApi.ApiConnection = mock.Object;
565 await twitterApi.ListsMembers(12345L, cursor: -1);
571 public async Task ListsMembersShow_Test()
573 var mock = new Mock<IApiConnectionLegacy>();
575 x.GetAsync<TwitterUser>(
576 new Uri("lists/members/show.json", UriKind.Relative),
577 new Dictionary<string, string>
579 { "list_id", "12345" },
580 { "screen_name", "twitterapi" },
581 { "include_entities", "true" },
582 { "include_ext_alt_text", "true" },
583 { "tweet_mode", "extended" },
585 "/lists/members/show")
587 .ReturnsAsync(new TwitterUser());
589 using var twitterApi = new TwitterApi();
590 twitterApi.ApiConnection = mock.Object;
592 await twitterApi.ListsMembersShow(12345L, "twitterapi");
598 public async Task ListsMembersCreate_Test()
600 var mock = new Mock<IApiConnectionLegacy>();
602 x.PostLazyAsync<TwitterUser>(
603 new Uri("lists/members/create.json", UriKind.Relative),
604 new Dictionary<string, string>
606 { "list_id", "12345" },
607 { "screen_name", "twitterapi" },
608 { "include_entities", "true" },
609 { "include_ext_alt_text", "true" },
610 { "tweet_mode", "extended" },
613 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
615 using var twitterApi = new TwitterApi();
616 twitterApi.ApiConnection = mock.Object;
618 await twitterApi.ListsMembersCreate(12345L, "twitterapi")
625 public async Task ListsMembersDestroy_Test()
627 var mock = new Mock<IApiConnectionLegacy>();
629 x.PostLazyAsync<TwitterUser>(
630 new Uri("lists/members/destroy.json", UriKind.Relative),
631 new Dictionary<string, string>
633 { "list_id", "12345" },
634 { "screen_name", "twitterapi" },
635 { "include_entities", "true" },
636 { "include_ext_alt_text", "true" },
637 { "tweet_mode", "extended" },
640 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
642 using var twitterApi = new TwitterApi();
643 twitterApi.ApiConnection = mock.Object;
645 await twitterApi.ListsMembersDestroy(12345L, "twitterapi")
652 public async Task DirectMessagesEventsList_Test()
654 var mock = new Mock<IApiConnectionLegacy>();
656 x.GetAsync<TwitterMessageEventList>(
657 new Uri("direct_messages/events/list.json", UriKind.Relative),
658 new Dictionary<string, string>
661 { "cursor", "12345abcdefg" },
663 "/direct_messages/events/list")
665 .ReturnsAsync(new TwitterMessageEventList());
667 using var twitterApi = new TwitterApi();
668 twitterApi.ApiConnection = mock.Object;
670 await twitterApi.DirectMessagesEventsList(count: 50, cursor: "12345abcdefg");
676 public async Task DirectMessagesEventsNew_Test()
678 using var responseMessage = new HttpResponseMessage(HttpStatusCode.OK);
679 var mock = new Mock<IApiConnectionLegacy>();
680 var requestJson = """
683 "type": "message_create",
686 "recipient_id": "12345"
703 It.Is<PostJsonRequest>(r =>
704 r.RequestUri == new Uri("direct_messages/events/new.json", UriKind.Relative) &&
705 r.JsonString == requestJson
709 .ReturnsAsync(new ApiResponse(responseMessage));
711 using var twitterApi = new TwitterApi();
712 twitterApi.ApiConnection = mock.Object;
714 await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge", mediaId: 67890L);
720 public async Task DirectMessagesEventsDestroy_Test()
722 var mock = new Mock<IApiConnectionLegacy>();
725 new Uri("direct_messages/events/destroy.json?id=100", UriKind.Relative))
727 .Returns(Task.CompletedTask);
729 using var twitterApi = new TwitterApi();
730 twitterApi.ApiConnection = mock.Object;
732 await twitterApi.DirectMessagesEventsDestroy(eventId: new("100"));
738 public async Task UsersShow_Test()
740 var mock = new Mock<IApiConnectionLegacy>();
742 x.GetAsync<TwitterUser>(
743 new Uri("users/show.json", UriKind.Relative),
744 new Dictionary<string, string>
746 { "screen_name", "twitterapi" },
747 { "include_entities", "true" },
748 { "include_ext_alt_text", "true" },
749 { "tweet_mode", "extended" },
753 .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
755 using var twitterApi = new TwitterApi();
756 twitterApi.ApiConnection = mock.Object;
758 await twitterApi.UsersShow(screenName: "twitterapi");
764 public async Task UsersLookup_Test()
766 var mock = new Mock<IApiConnectionLegacy>();
768 x.GetAsync<TwitterUser[]>(
769 new Uri("users/lookup.json", UriKind.Relative),
770 new Dictionary<string, string>
772 { "user_id", "11111,22222" },
773 { "include_entities", "true" },
774 { "include_ext_alt_text", "true" },
775 { "tweet_mode", "extended" },
779 .ReturnsAsync(Array.Empty<TwitterUser>());
781 using var twitterApi = new TwitterApi();
782 twitterApi.ApiConnection = mock.Object;
784 await twitterApi.UsersLookup(userIds: new[] { "11111", "22222" });
790 public async Task UsersReportSpam_Test()
792 var mock = new Mock<IApiConnectionLegacy>();
794 x.PostLazyAsync<TwitterUser>(
795 new Uri("users/report_spam.json", UriKind.Relative),
796 new Dictionary<string, string>
798 { "screen_name", "twitterapi" },
799 { "tweet_mode", "extended" },
802 .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
804 using var twitterApi = new TwitterApi();
805 twitterApi.ApiConnection = mock.Object;
807 await twitterApi.UsersReportSpam(screenName: "twitterapi")
814 public async Task FavoritesList_Test()
816 var mock = new Mock<IApiConnectionLegacy>();
818 x.GetAsync<TwitterStatus[]>(
819 new Uri("favorites/list.json", UriKind.Relative),
820 new Dictionary<string, string>
822 { "include_entities", "true" },
823 { "include_ext_alt_text", "true" },
824 { "tweet_mode", "extended" },
827 { "since_id", "100" },
831 .ReturnsAsync(Array.Empty<TwitterStatus>());
833 using var twitterApi = new TwitterApi();
834 twitterApi.ApiConnection = mock.Object;
836 await twitterApi.FavoritesList(200, maxId: 900L, sinceId: 100L);
842 public async Task FavoritesCreate_Test()
844 var mock = new Mock<IApiConnectionLegacy>();
846 x.PostLazyAsync<TwitterStatus>(
847 new Uri("favorites/create.json", UriKind.Relative),
848 new Dictionary<string, string>
851 { "tweet_mode", "extended" },
854 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
856 using var twitterApi = new TwitterApi();
857 twitterApi.ApiConnection = mock.Object;
859 await twitterApi.FavoritesCreate(statusId: new("100"))
866 public async Task FavoritesDestroy_Test()
868 var mock = new Mock<IApiConnectionLegacy>();
870 x.PostLazyAsync<TwitterStatus>(
871 new Uri("favorites/destroy.json", UriKind.Relative),
872 new Dictionary<string, string>
875 { "tweet_mode", "extended" },
878 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
880 using var twitterApi = new TwitterApi();
881 twitterApi.ApiConnection = mock.Object;
883 await twitterApi.FavoritesDestroy(statusId: new("100"))
890 public async Task FriendshipsShow_Test()
892 var mock = new Mock<IApiConnectionLegacy>();
894 x.GetAsync<TwitterFriendship>(
895 new Uri("friendships/show.json", UriKind.Relative),
896 new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } },
899 .ReturnsAsync(new TwitterFriendship());
901 using var twitterApi = new TwitterApi();
902 twitterApi.ApiConnection = mock.Object;
904 await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi");
910 public async Task FriendshipsCreate_Test()
912 var mock = new Mock<IApiConnectionLegacy>();
914 x.PostLazyAsync<TwitterFriendship>(
915 new Uri("friendships/create.json", UriKind.Relative),
916 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
918 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
920 using var twitterApi = new TwitterApi();
921 twitterApi.ApiConnection = mock.Object;
923 await twitterApi.FriendshipsCreate(screenName: "twitterapi")
930 public async Task FriendshipsDestroy_Test()
932 var mock = new Mock<IApiConnectionLegacy>();
934 x.PostLazyAsync<TwitterFriendship>(
935 new Uri("friendships/destroy.json", UriKind.Relative),
936 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
938 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
940 using var twitterApi = new TwitterApi();
941 twitterApi.ApiConnection = mock.Object;
943 await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
950 public async Task NoRetweetIds_Test()
952 var mock = new Mock<IApiConnectionLegacy>();
955 new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
957 "/friendships/no_retweets/ids")
959 .ReturnsAsync(Array.Empty<long>());
961 using var twitterApi = new TwitterApi();
962 twitterApi.ApiConnection = mock.Object;
964 await twitterApi.NoRetweetIds();
970 public async Task FollowersIds_Test()
972 var mock = new Mock<IApiConnectionLegacy>();
974 x.GetAsync<TwitterIds>(
975 new Uri("followers/ids.json", UriKind.Relative),
976 new Dictionary<string, string> { { "cursor", "-1" } },
979 .ReturnsAsync(new TwitterIds());
981 using var twitterApi = new TwitterApi();
982 twitterApi.ApiConnection = mock.Object;
984 await twitterApi.FollowersIds(cursor: -1L);
990 public async Task MutesUsersIds_Test()
992 var mock = new Mock<IApiConnectionLegacy>();
994 x.GetAsync<TwitterIds>(
995 new Uri("mutes/users/ids.json", UriKind.Relative),
996 new Dictionary<string, string> { { "cursor", "-1" } },
999 .ReturnsAsync(new TwitterIds());
1001 using var twitterApi = new TwitterApi();
1002 twitterApi.ApiConnection = mock.Object;
1004 await twitterApi.MutesUsersIds(cursor: -1L);
1010 public async Task BlocksIds_Test()
1012 var mock = new Mock<IApiConnectionLegacy>();
1014 x.GetAsync<TwitterIds>(
1015 new Uri("blocks/ids.json", UriKind.Relative),
1016 new Dictionary<string, string> { { "cursor", "-1" } },
1019 .ReturnsAsync(new TwitterIds());
1021 using var twitterApi = new TwitterApi();
1022 twitterApi.ApiConnection = mock.Object;
1024 await twitterApi.BlocksIds(cursor: -1L);
1030 public async Task BlocksCreate_Test()
1032 var mock = new Mock<IApiConnectionLegacy>();
1034 x.PostLazyAsync<TwitterUser>(
1035 new Uri("blocks/create.json", UriKind.Relative),
1036 new Dictionary<string, string>
1038 { "screen_name", "twitterapi" },
1039 { "tweet_mode", "extended" },
1042 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1044 using var twitterApi = new TwitterApi();
1045 twitterApi.ApiConnection = mock.Object;
1047 await twitterApi.BlocksCreate(screenName: "twitterapi")
1054 public async Task BlocksDestroy_Test()
1056 var mock = new Mock<IApiConnectionLegacy>();
1058 x.PostLazyAsync<TwitterUser>(
1059 new Uri("blocks/destroy.json", UriKind.Relative),
1060 new Dictionary<string, string>
1062 { "screen_name", "twitterapi" },
1063 { "tweet_mode", "extended" },
1066 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1068 using var twitterApi = new TwitterApi();
1069 twitterApi.ApiConnection = mock.Object;
1071 await twitterApi.BlocksDestroy(screenName: "twitterapi")
1078 public async Task AccountVerifyCredentials_Test()
1080 var mock = new Mock<IApiConnectionLegacy>();
1082 x.GetAsync<TwitterUser>(
1083 new Uri("account/verify_credentials.json", UriKind.Relative),
1084 new Dictionary<string, string>
1086 { "include_entities", "true" },
1087 { "include_ext_alt_text", "true" },
1088 { "tweet_mode", "extended" },
1090 "/account/verify_credentials")
1092 .ReturnsAsync(new TwitterUser
1095 ScreenName = "opentween",
1098 using var twitterApi = new TwitterApi();
1099 twitterApi.ApiConnection = mock.Object;
1101 await twitterApi.AccountVerifyCredentials();
1103 Assert.Equal(100L, twitterApi.CurrentUserId);
1104 Assert.Equal("opentween", twitterApi.CurrentScreenName);
1110 public async Task AccountUpdateProfile_Test()
1112 var mock = new Mock<IApiConnectionLegacy>();
1114 x.PostLazyAsync<TwitterUser>(
1115 new Uri("account/update_profile.json", UriKind.Relative),
1116 new Dictionary<string, string>
1118 { "include_entities", "true" },
1119 { "include_ext_alt_text", "true" },
1120 { "tweet_mode", "extended" },
1122 { "url", "http://example.com/" },
1123 { "location", "Location" },
1124 { "description", "<script>alert(1)</script>" },
1127 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1129 using var twitterApi = new TwitterApi();
1130 twitterApi.ApiConnection = mock.Object;
1132 await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
1139 public async Task AccountUpdateProfileImage_Test()
1141 using var image = TestUtils.CreateDummyImage();
1142 using var media = new MemoryImageMediaItem(image);
1143 var mock = new Mock<IApiConnectionLegacy>();
1145 x.PostLazyAsync<TwitterUser>(
1146 new Uri("account/update_profile_image.json", UriKind.Relative),
1147 new Dictionary<string, string>
1149 { "include_entities", "true" },
1150 { "include_ext_alt_text", "true" },
1151 { "tweet_mode", "extended" },
1153 new Dictionary<string, IMediaItem> { { "image", media } })
1155 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1157 using var twitterApi = new TwitterApi();
1158 twitterApi.ApiConnection = mock.Object;
1160 await twitterApi.AccountUpdateProfileImage(media)
1167 public async Task ApplicationRateLimitStatus_Test()
1169 var mock = new Mock<IApiConnectionLegacy>();
1171 x.GetAsync<TwitterRateLimits>(
1172 new Uri("application/rate_limit_status.json", UriKind.Relative),
1174 "/application/rate_limit_status")
1176 .ReturnsAsync(new TwitterRateLimits());
1178 using var twitterApi = new TwitterApi();
1179 twitterApi.ApiConnection = mock.Object;
1181 await twitterApi.ApplicationRateLimitStatus();
1187 public async Task Configuration_Test()
1189 var mock = new Mock<IApiConnectionLegacy>();
1191 x.GetAsync<TwitterConfiguration>(
1192 new Uri("help/configuration.json", UriKind.Relative),
1194 "/help/configuration")
1196 .ReturnsAsync(new TwitterConfiguration());
1198 using var twitterApi = new TwitterApi();
1199 twitterApi.ApiConnection = mock.Object;
1201 await twitterApi.Configuration();
1207 public async Task MediaUploadInit_Test()
1209 var mock = new Mock<IApiConnectionLegacy>();
1211 x.PostLazyAsync<TwitterUploadMediaInit>(
1212 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1213 new Dictionary<string, string>
1215 { "command", "INIT" },
1216 { "total_bytes", "123456" },
1217 { "media_type", "image/png" },
1218 { "media_category", "dm_image" },
1221 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaInit()));
1223 using var twitterApi = new TwitterApi();
1224 twitterApi.ApiConnection = mock.Object;
1226 await twitterApi.MediaUploadInit(totalBytes: 123456L, mediaType: "image/png", mediaCategory: "dm_image")
1233 public async Task MediaUploadAppend_Test()
1235 using var image = TestUtils.CreateDummyImage();
1236 using var media = new MemoryImageMediaItem(image);
1237 var mock = new Mock<IApiConnectionLegacy>();
1240 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1241 new Dictionary<string, string>
1243 { "command", "APPEND" },
1244 { "media_id", "11111" },
1245 { "segment_index", "1" },
1247 new Dictionary<string, IMediaItem> { { "media", media } })
1249 .Returns(Task.CompletedTask);
1251 using var twitterApi = new TwitterApi();
1252 twitterApi.ApiConnection = mock.Object;
1254 await twitterApi.MediaUploadAppend(mediaId: 11111L, segmentIndex: 1, media: media);
1260 public async Task MediaUploadFinalize_Test()
1262 var mock = new Mock<IApiConnectionLegacy>();
1264 x.PostLazyAsync<TwitterUploadMediaResult>(
1265 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1266 new Dictionary<string, string>
1268 { "command", "FINALIZE" },
1269 { "media_id", "11111" },
1272 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
1274 using var twitterApi = new TwitterApi();
1275 twitterApi.ApiConnection = mock.Object;
1277 await twitterApi.MediaUploadFinalize(mediaId: 11111L)
1284 public async Task MediaUploadStatus_Test()
1286 var mock = new Mock<IApiConnectionLegacy>();
1288 x.GetAsync<TwitterUploadMediaResult>(
1289 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1290 new Dictionary<string, string>
1292 { "command", "STATUS" },
1293 { "media_id", "11111" },
1297 .ReturnsAsync(new TwitterUploadMediaResult());
1299 using var twitterApi = new TwitterApi();
1300 twitterApi.ApiConnection = mock.Object;
1302 await twitterApi.MediaUploadStatus(mediaId: 11111L);
1308 public async Task MediaMetadataCreate_Test()
1310 var mock = new Mock<IApiConnectionLegacy>();
1313 It.Is<PostJsonRequest>(r =>
1314 r.RequestUri == new Uri("https://upload.twitter.com/1.1/media/metadata/create.json") &&
1315 r.JsonString == """{"media_id": "12345", "alt_text": {"text": "hogehoge"}}"""
1320 using var twitterApi = new TwitterApi();
1321 twitterApi.ApiConnection = mock.Object;
1323 await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge");