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())
56 Assert.Null(twitterApi.apiConnection);
58 twitterApi.Initialize("*** AccessToken ***", "*** AccessSecret ***", userId: 100L, screenName: "hogehoge");
60 Assert.IsType<TwitterApiConnection>(twitterApi.apiConnection);
62 var apiConnection = (TwitterApiConnection)twitterApi.apiConnection;
63 Assert.Equal("*** AccessToken ***", apiConnection.AccessToken);
64 Assert.Equal("*** AccessSecret ***", apiConnection.AccessSecret);
66 Assert.Equal(100L, twitterApi.CurrentUserId);
67 Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
69 // 複数回 Initialize を実行した場合は新たに TwitterApiConnection が生成される
70 twitterApi.Initialize("*** AccessToken2 ***", "*** AccessSecret2 ***", userId: 200L, screenName: "foobar");
72 var oldApiConnection = apiConnection;
73 Assert.True(oldApiConnection.IsDisposed);
75 Assert.IsType<TwitterApiConnection>(twitterApi.apiConnection);
77 apiConnection = (TwitterApiConnection)twitterApi.apiConnection;
78 Assert.Equal("*** AccessToken2 ***", apiConnection.AccessToken);
79 Assert.Equal("*** AccessSecret2 ***", apiConnection.AccessSecret);
81 Assert.Equal(200L, twitterApi.CurrentUserId);
82 Assert.Equal("foobar", twitterApi.CurrentScreenName);
87 public async Task StatusesHomeTimeline_Test()
89 using (var twitterApi = new TwitterApi())
91 var mock = new Mock<IApiConnection>();
93 x.GetAsync<TwitterStatus[]>(
94 new Uri("statuses/home_timeline.json", UriKind.Relative),
95 new Dictionary<string, string> {
96 { "include_entities", "true" },
97 { "include_ext_alt_text", "true" },
98 { "tweet_mode", "extended" },
101 { "since_id", "100" },
103 "/statuses/home_timeline")
105 .ReturnsAsync(Array.Empty<TwitterStatus>());
107 twitterApi.apiConnection = mock.Object;
109 await twitterApi.StatusesHomeTimeline(200, maxId: 900L, sinceId: 100L)
110 .ConfigureAwait(false);
117 public async Task StatusesMentionsTimeline_Test()
119 using (var twitterApi = new TwitterApi())
121 var mock = new Mock<IApiConnection>();
123 x.GetAsync<TwitterStatus[]>(
124 new Uri("statuses/mentions_timeline.json", UriKind.Relative),
125 new Dictionary<string, string> {
126 { "include_entities", "true" },
127 { "include_ext_alt_text", "true" },
128 { "tweet_mode", "extended" },
131 { "since_id", "100" },
133 "/statuses/mentions_timeline")
135 .ReturnsAsync(Array.Empty<TwitterStatus>());
137 twitterApi.apiConnection = mock.Object;
139 await twitterApi.StatusesMentionsTimeline(200, maxId: 900L, sinceId: 100L)
140 .ConfigureAwait(false);
147 public async Task StatusesUserTimeline_Test()
149 using (var twitterApi = new TwitterApi())
151 var mock = new Mock<IApiConnection>();
153 x.GetAsync<TwitterStatus[]>(
154 new Uri("statuses/user_timeline.json", UriKind.Relative),
155 new Dictionary<string, string> {
156 { "screen_name", "twitterapi" },
157 { "include_rts", "true" },
158 { "include_entities", "true" },
159 { "include_ext_alt_text", "true" },
160 { "tweet_mode", "extended" },
163 { "since_id", "100" },
165 "/statuses/user_timeline")
167 .ReturnsAsync(Array.Empty<TwitterStatus>());
169 twitterApi.apiConnection = mock.Object;
171 await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: 900L, sinceId: 100L)
172 .ConfigureAwait(false);
179 public async Task StatusesShow_Test()
181 using (var twitterApi = new TwitterApi())
183 var mock = new Mock<IApiConnection>();
185 x.GetAsync<TwitterStatus>(
186 new Uri("statuses/show.json", UriKind.Relative),
187 new Dictionary<string, string> {
189 { "include_entities", "true" },
190 { "include_ext_alt_text", "true" },
191 { "tweet_mode", "extended" },
193 "/statuses/show/:id")
195 .ReturnsAsync(new TwitterStatus { Id = 100L });
197 twitterApi.apiConnection = mock.Object;
199 await twitterApi.StatusesShow(statusId: 100L)
200 .ConfigureAwait(false);
207 public async Task StatusesUpdate_Test()
209 using (var twitterApi = new TwitterApi())
211 var mock = new Mock<IApiConnection>();
213 x.PostLazyAsync<TwitterStatus>(
214 new Uri("statuses/update.json", UriKind.Relative),
215 new Dictionary<string, string> {
216 { "status", "hogehoge" },
217 { "include_entities", "true" },
218 { "include_ext_alt_text", "true" },
219 { "tweet_mode", "extended" },
220 { "in_reply_to_status_id", "100" },
221 { "media_ids", "10,20" },
222 { "auto_populate_reply_metadata", "true" },
223 { "exclude_reply_user_ids", "100,200" },
224 { "attachment_url", "https://twitter.com/twitterapi/status/22634515958" },
227 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
229 twitterApi.apiConnection = mock.Object;
231 await twitterApi.StatusesUpdate("hogehoge", replyToId: 100L, mediaIds: new[] { 10L, 20L },
232 autoPopulateReplyMetadata: true, excludeReplyUserIds: new[] { 100L, 200L },
233 attachmentUrl: "https://twitter.com/twitterapi/status/22634515958")
235 .ConfigureAwait(false);
242 public async Task StatusesUpdate_ExcludeReplyUserIdsEmptyTest()
244 using (var twitterApi = new TwitterApi())
246 var mock = new Mock<IApiConnection>();
248 x.PostLazyAsync<TwitterStatus>(
249 new Uri("statuses/update.json", UriKind.Relative),
250 new Dictionary<string, string> {
251 { "status", "hogehoge" },
252 { "include_entities", "true" },
253 { "include_ext_alt_text", "true" },
254 { "tweet_mode", "extended" },
255 // exclude_reply_user_ids は空の場合には送信されない
258 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
260 twitterApi.apiConnection = mock.Object;
262 await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: Array.Empty<long>())
264 .ConfigureAwait(false);
271 public async Task StatusesDestroy_Test()
273 using (var twitterApi = new TwitterApi())
275 var mock = new Mock<IApiConnection>();
277 x.PostLazyAsync<TwitterStatus>(
278 new Uri("statuses/destroy.json", UriKind.Relative),
279 new Dictionary<string, string> { { "id", "100" } })
281 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
283 twitterApi.apiConnection = mock.Object;
285 await twitterApi.StatusesDestroy(statusId: 100L)
287 .ConfigureAwait(false);
294 public async Task StatusesRetweet_Test()
296 using (var twitterApi = new TwitterApi())
298 var mock = new Mock<IApiConnection>();
300 x.PostLazyAsync<TwitterStatus>(
301 new Uri("statuses/retweet.json", UriKind.Relative),
302 new Dictionary<string, string> {
304 { "include_entities", "true" },
305 { "include_ext_alt_text", "true" },
306 { "tweet_mode", "extended" },
309 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
311 twitterApi.apiConnection = mock.Object;
313 await twitterApi.StatusesRetweet(100L)
315 .ConfigureAwait(false);
322 public async Task SearchTweets_Test()
324 using (var twitterApi = new TwitterApi())
326 var mock = new Mock<IApiConnection>();
328 x.GetAsync<TwitterSearchResult>(
329 new Uri("search/tweets.json", UriKind.Relative),
330 new Dictionary<string, string> {
331 { "q", "from:twitterapi" },
332 { "result_type", "recent" },
333 { "include_entities", "true" },
334 { "include_ext_alt_text", "true" },
335 { "tweet_mode", "extended" },
339 { "since_id", "100" },
343 .ReturnsAsync(new TwitterSearchResult());
345 twitterApi.apiConnection = mock.Object;
347 await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: 900L, sinceId: 100L)
348 .ConfigureAwait(false);
355 public async Task ListsOwnerships_Test()
357 using (var twitterApi = new TwitterApi())
359 var mock = new Mock<IApiConnection>();
361 x.GetAsync<TwitterLists>(
362 new Uri("lists/ownerships.json", UriKind.Relative),
363 new Dictionary<string, string> {
364 { "screen_name", "twitterapi" },
370 .ReturnsAsync(new TwitterLists());
372 twitterApi.apiConnection = mock.Object;
374 await twitterApi.ListsOwnerships("twitterapi", cursor: -1L, count: 100)
375 .ConfigureAwait(false);
382 public async Task ListsSubscriptions_Test()
384 using (var twitterApi = new TwitterApi())
386 var mock = new Mock<IApiConnection>();
388 x.GetAsync<TwitterLists>(
389 new Uri("lists/subscriptions.json", UriKind.Relative),
390 new Dictionary<string, string> {
391 { "screen_name", "twitterapi" },
395 "/lists/subscriptions")
397 .ReturnsAsync(new TwitterLists());
399 twitterApi.apiConnection = mock.Object;
401 await twitterApi.ListsSubscriptions("twitterapi", cursor: -1L, count: 100)
402 .ConfigureAwait(false);
409 public async Task ListsMemberships_Test()
411 using (var twitterApi = new TwitterApi())
413 var mock = new Mock<IApiConnection>();
415 x.GetAsync<TwitterLists>(
416 new Uri("lists/memberships.json", UriKind.Relative),
417 new Dictionary<string, string> {
418 { "screen_name", "twitterapi" },
421 { "filter_to_owned_lists", "true" },
423 "/lists/memberships")
425 .ReturnsAsync(new TwitterLists());
427 twitterApi.apiConnection = mock.Object;
429 await twitterApi.ListsMemberships("twitterapi", cursor: -1L, count: 100, filterToOwnedLists: true)
430 .ConfigureAwait(false);
437 public async Task ListsCreate_Test()
439 using (var twitterApi = new TwitterApi())
441 var mock = new Mock<IApiConnection>();
443 x.PostLazyAsync<TwitterList>(
444 new Uri("lists/create.json", UriKind.Relative),
445 new Dictionary<string, string> {
446 { "name", "hogehoge" },
447 { "description", "aaaa" },
448 { "mode", "private" },
451 .ReturnsAsync(LazyJson.Create(new TwitterList()));
453 twitterApi.apiConnection = mock.Object;
455 await twitterApi.ListsCreate("hogehoge", description: "aaaa", @private: true)
457 .ConfigureAwait(false);
464 public async Task ListsUpdate_Test()
466 using (var twitterApi = new TwitterApi())
468 var mock = new Mock<IApiConnection>();
470 x.PostLazyAsync<TwitterList>(
471 new Uri("lists/update.json", UriKind.Relative),
472 new Dictionary<string, string> {
473 { "list_id", "12345" },
474 { "name", "hogehoge" },
475 { "description", "aaaa" },
476 { "mode", "private" },
479 .ReturnsAsync(LazyJson.Create(new TwitterList()));
481 twitterApi.apiConnection = mock.Object;
483 await twitterApi.ListsUpdate(12345L, name: "hogehoge", description: "aaaa", @private: true)
485 .ConfigureAwait(false);
492 public async Task ListsDestroy_Test()
494 using (var twitterApi = new TwitterApi())
496 var mock = new Mock<IApiConnection>();
498 x.PostLazyAsync<TwitterList>(
499 new Uri("lists/destroy.json", UriKind.Relative),
500 new Dictionary<string, string> {
501 { "list_id", "12345" },
504 .ReturnsAsync(LazyJson.Create(new TwitterList()));
506 twitterApi.apiConnection = mock.Object;
508 await twitterApi.ListsDestroy(12345L)
510 .ConfigureAwait(false);
517 public async Task ListsStatuses_Test()
519 using (var twitterApi = new TwitterApi())
521 var mock = new Mock<IApiConnection>();
523 x.GetAsync<TwitterStatus[]>(
524 new Uri("lists/statuses.json", UriKind.Relative),
525 new Dictionary<string, string> {
526 { "list_id", "12345" },
527 { "include_entities", "true" },
528 { "include_ext_alt_text", "true" },
529 { "tweet_mode", "extended" },
532 { "since_id", "100" },
533 { "include_rts", "true" },
537 .ReturnsAsync(Array.Empty<TwitterStatus>());
539 twitterApi.apiConnection = mock.Object;
541 await twitterApi.ListsStatuses(12345L, count: 200, maxId: 900L, sinceId: 100L, includeRTs: true)
542 .ConfigureAwait(false);
549 public async Task ListsMembers_Test()
551 using (var twitterApi = new TwitterApi())
553 var mock = new Mock<IApiConnection>();
555 x.GetAsync<TwitterUsers>(
556 new Uri("lists/members.json", UriKind.Relative),
557 new Dictionary<string, string> {
558 { "list_id", "12345" },
559 { "include_entities", "true" },
560 { "include_ext_alt_text", "true" },
561 { "tweet_mode", "extended" },
566 .ReturnsAsync(new TwitterUsers());
568 twitterApi.apiConnection = mock.Object;
570 await twitterApi.ListsMembers(12345L, cursor: -1)
571 .ConfigureAwait(false);
578 public async Task ListsMembersShow_Test()
580 using (var twitterApi = new TwitterApi())
582 var mock = new Mock<IApiConnection>();
584 x.GetAsync<TwitterUser>(
585 new Uri("lists/members/show.json", UriKind.Relative),
586 new Dictionary<string, string> {
587 { "list_id", "12345" },
588 { "screen_name", "twitterapi" },
589 { "include_entities", "true" },
590 { "include_ext_alt_text", "true" },
591 { "tweet_mode", "extended" },
593 "/lists/members/show")
595 .ReturnsAsync(new TwitterUser());
597 twitterApi.apiConnection = mock.Object;
599 await twitterApi.ListsMembersShow(12345L, "twitterapi")
600 .ConfigureAwait(false);
607 public async Task ListsMembersCreate_Test()
609 using (var twitterApi = new TwitterApi())
611 var mock = new Mock<IApiConnection>();
613 x.PostLazyAsync<TwitterUser>(
614 new Uri("lists/members/create.json", UriKind.Relative),
615 new Dictionary<string, string> {
616 { "list_id", "12345" },
617 { "screen_name", "twitterapi" },
618 { "include_entities", "true" },
619 { "include_ext_alt_text", "true" },
620 { "tweet_mode", "extended" },
623 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
625 twitterApi.apiConnection = mock.Object;
627 await twitterApi.ListsMembersCreate(12345L, "twitterapi")
629 .ConfigureAwait(false);
636 public async Task ListsMembersDestroy_Test()
638 using (var twitterApi = new TwitterApi())
640 var mock = new Mock<IApiConnection>();
642 x.PostLazyAsync<TwitterUser>(
643 new Uri("lists/members/destroy.json", UriKind.Relative),
644 new Dictionary<string, string> {
645 { "list_id", "12345" },
646 { "screen_name", "twitterapi" },
647 { "include_entities", "true" },
648 { "include_ext_alt_text", "true" },
649 { "tweet_mode", "extended" },
652 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
654 twitterApi.apiConnection = mock.Object;
656 await twitterApi.ListsMembersDestroy(12345L, "twitterapi")
658 .ConfigureAwait(false);
665 public async Task DirectMessagesEventsList_Test()
667 using (var twitterApi = new TwitterApi())
669 var mock = new Mock<IApiConnection>();
671 x.GetAsync<TwitterMessageEventList>(
672 new Uri("direct_messages/events/list.json", UriKind.Relative),
673 new Dictionary<string, string> {
675 { "cursor", "12345abcdefg" },
677 "/direct_messages/events/list")
679 .ReturnsAsync(new TwitterMessageEventList());
681 twitterApi.apiConnection = mock.Object;
683 await twitterApi.DirectMessagesEventsList(count: 50, cursor: "12345abcdefg")
684 .ConfigureAwait(false);
691 public async Task DirectMessagesEventsNew_Test()
693 using (var twitterApi = new TwitterApi())
695 var mock = new Mock<IApiConnection>();
697 x.PostJsonAsync<TwitterMessageEventSingle>(
698 new Uri("direct_messages/events/new.json", UriKind.Relative),
701 ""type"": ""message_create"",
702 ""message_create"": {
704 ""recipient_id"": ""12345""
707 ""text"": ""hogehoge"",
719 .ReturnsAsync(LazyJson.Create(new TwitterMessageEventSingle()));
721 twitterApi.apiConnection = mock.Object;
723 await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge", mediaId: 67890L)
724 .ConfigureAwait(false);
731 public async Task DirectMessagesEventsDestroy_Test()
733 using (var twitterApi = new TwitterApi())
735 var mock = new Mock<IApiConnection>();
738 new Uri("direct_messages/events/destroy.json?id=100", UriKind.Relative))
740 .Returns(Task.CompletedTask);
742 twitterApi.apiConnection = mock.Object;
744 await twitterApi.DirectMessagesEventsDestroy(eventId: "100")
745 .ConfigureAwait(false);
752 public async Task UsersShow_Test()
754 using (var twitterApi = new TwitterApi())
756 var mock = new Mock<IApiConnection>();
758 x.GetAsync<TwitterUser>(
759 new Uri("users/show.json", UriKind.Relative),
760 new Dictionary<string, string> {
761 { "screen_name", "twitterapi" },
762 { "include_entities", "true" },
763 { "include_ext_alt_text", "true" },
764 { "tweet_mode", "extended" },
768 .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
770 twitterApi.apiConnection = mock.Object;
772 await twitterApi.UsersShow(screenName: "twitterapi")
773 .ConfigureAwait(false);
780 public async Task UsersLookup_Test()
782 using (var twitterApi = new TwitterApi())
784 var mock = new Mock<IApiConnection>();
786 x.GetAsync<TwitterUser[]>(
787 new Uri("users/lookup.json", UriKind.Relative),
788 new Dictionary<string, string> {
789 { "user_id", "11111,22222" },
790 { "include_entities", "true" },
791 { "include_ext_alt_text", "true" },
792 { "tweet_mode", "extended" },
796 .ReturnsAsync(Array.Empty<TwitterUser>());
798 twitterApi.apiConnection = mock.Object;
800 await twitterApi.UsersLookup(userIds: new[] { "11111", "22222" })
801 .ConfigureAwait(false);
808 public async Task UsersReportSpam_Test()
810 using (var twitterApi = new TwitterApi())
812 var mock = new Mock<IApiConnection>();
814 x.PostLazyAsync<TwitterUser>(
815 new Uri("users/report_spam.json", UriKind.Relative),
816 new Dictionary<string, string> {
817 { "screen_name", "twitterapi" },
818 { "tweet_mode", "extended" },
821 .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
823 twitterApi.apiConnection = mock.Object;
825 await twitterApi.UsersReportSpam(screenName: "twitterapi")
827 .ConfigureAwait(false);
834 public async Task FavoritesList_Test()
836 using (var twitterApi = new TwitterApi())
838 var mock = new Mock<IApiConnection>();
840 x.GetAsync<TwitterStatus[]>(
841 new Uri("favorites/list.json", UriKind.Relative),
842 new Dictionary<string, string> {
843 { "include_entities", "true" },
844 { "include_ext_alt_text", "true" },
845 { "tweet_mode", "extended" },
848 { "since_id", "100" },
852 .ReturnsAsync(Array.Empty<TwitterStatus>());
854 twitterApi.apiConnection = mock.Object;
856 await twitterApi.FavoritesList(200, maxId: 900L, sinceId: 100L)
857 .ConfigureAwait(false);
864 public async Task FavoritesCreate_Test()
866 using (var twitterApi = new TwitterApi())
868 var mock = new Mock<IApiConnection>();
870 x.PostLazyAsync<TwitterStatus>(
871 new Uri("favorites/create.json", UriKind.Relative),
872 new Dictionary<string, string> {
874 { "tweet_mode", "extended" },
877 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
879 twitterApi.apiConnection = mock.Object;
881 await twitterApi.FavoritesCreate(statusId: 100L)
883 .ConfigureAwait(false);
890 public async Task FavoritesDestroy_Test()
892 using (var twitterApi = new TwitterApi())
894 var mock = new Mock<IApiConnection>();
896 x.PostLazyAsync<TwitterStatus>(
897 new Uri("favorites/destroy.json", UriKind.Relative),
898 new Dictionary<string, string> {
900 { "tweet_mode", "extended" },
903 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
905 twitterApi.apiConnection = mock.Object;
907 await twitterApi.FavoritesDestroy(statusId: 100L)
909 .ConfigureAwait(false);
916 public async Task FriendshipsShow_Test()
918 using (var twitterApi = new TwitterApi())
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 twitterApi.apiConnection = mock.Object;
931 await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi")
932 .ConfigureAwait(false);
939 public async Task FriendshipsCreate_Test()
941 using (var twitterApi = new TwitterApi())
943 var mock = new Mock<IApiConnection>();
945 x.PostLazyAsync<TwitterFriendship>(
946 new Uri("friendships/create.json", UriKind.Relative),
947 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
949 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
951 twitterApi.apiConnection = mock.Object;
953 await twitterApi.FriendshipsCreate(screenName: "twitterapi")
955 .ConfigureAwait(false);
962 public async Task FriendshipsDestroy_Test()
964 using (var twitterApi = new TwitterApi())
966 var mock = new Mock<IApiConnection>();
968 x.PostLazyAsync<TwitterFriendship>(
969 new Uri("friendships/destroy.json", UriKind.Relative),
970 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
972 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
974 twitterApi.apiConnection = mock.Object;
976 await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
978 .ConfigureAwait(false);
985 public async Task NoRetweetIds_Test()
987 using (var twitterApi = new TwitterApi())
989 var mock = new Mock<IApiConnection>();
992 new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
994 "/friendships/no_retweets/ids")
996 .ReturnsAsync(Array.Empty<long>());
998 twitterApi.apiConnection = mock.Object;
1000 await twitterApi.NoRetweetIds()
1001 .ConfigureAwait(false);
1008 public async Task FollowersIds_Test()
1010 using (var twitterApi = new TwitterApi())
1012 var mock = new Mock<IApiConnection>();
1014 x.GetAsync<TwitterIds>(
1015 new Uri("followers/ids.json", UriKind.Relative),
1016 new Dictionary<string, string> { { "cursor", "-1" } },
1019 .ReturnsAsync(new TwitterIds());
1021 twitterApi.apiConnection = mock.Object;
1023 await twitterApi.FollowersIds(cursor: -1L)
1024 .ConfigureAwait(false);
1031 public async Task MutesUsersIds_Test()
1033 using (var twitterApi = new TwitterApi())
1035 var mock = new Mock<IApiConnection>();
1037 x.GetAsync<TwitterIds>(
1038 new Uri("mutes/users/ids.json", UriKind.Relative),
1039 new Dictionary<string, string> { { "cursor", "-1" } },
1042 .ReturnsAsync(new TwitterIds());
1044 twitterApi.apiConnection = mock.Object;
1046 await twitterApi.MutesUsersIds(cursor: -1L)
1047 .ConfigureAwait(false);
1054 public async Task BlocksIds_Test()
1056 using (var twitterApi = new TwitterApi())
1058 var mock = new Mock<IApiConnection>();
1060 x.GetAsync<TwitterIds>(
1061 new Uri("blocks/ids.json", UriKind.Relative),
1062 new Dictionary<string, string> { { "cursor", "-1" } },
1065 .ReturnsAsync(new TwitterIds());
1067 twitterApi.apiConnection = mock.Object;
1069 await twitterApi.BlocksIds(cursor: -1L)
1070 .ConfigureAwait(false);
1077 public async Task BlocksCreate_Test()
1079 using (var twitterApi = new TwitterApi())
1081 var mock = new Mock<IApiConnection>();
1083 x.PostLazyAsync<TwitterUser>(
1084 new Uri("blocks/create.json", UriKind.Relative),
1085 new Dictionary<string, string> {
1086 { "screen_name", "twitterapi" },
1087 { "tweet_mode", "extended" },
1090 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1092 twitterApi.apiConnection = mock.Object;
1094 await twitterApi.BlocksCreate(screenName: "twitterapi")
1096 .ConfigureAwait(false);
1103 public async Task BlocksDestroy_Test()
1105 using (var twitterApi = new TwitterApi())
1107 var mock = new Mock<IApiConnection>();
1109 x.PostLazyAsync<TwitterUser>(
1110 new Uri("blocks/destroy.json", UriKind.Relative),
1111 new Dictionary<string, string> {
1112 { "screen_name", "twitterapi" },
1113 { "tweet_mode", "extended" },
1116 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1118 twitterApi.apiConnection = mock.Object;
1120 await twitterApi.BlocksDestroy(screenName: "twitterapi")
1122 .ConfigureAwait(false);
1129 public async Task AccountVerifyCredentials_Test()
1131 using (var twitterApi = new TwitterApi())
1133 var mock = new Mock<IApiConnection>();
1135 x.GetAsync<TwitterUser>(
1136 new Uri("account/verify_credentials.json", UriKind.Relative),
1137 new Dictionary<string, string> {
1138 { "include_entities", "true" },
1139 { "include_ext_alt_text", "true" },
1140 { "tweet_mode", "extended" },
1142 "/account/verify_credentials")
1144 .ReturnsAsync(new TwitterUser {
1146 ScreenName = "opentween",
1149 twitterApi.apiConnection = mock.Object;
1151 await twitterApi.AccountVerifyCredentials()
1152 .ConfigureAwait(false);
1154 Assert.Equal(100L, twitterApi.CurrentUserId);
1155 Assert.Equal("opentween", twitterApi.CurrentScreenName);
1162 public async Task AccountUpdateProfile_Test()
1164 using (var twitterApi = new TwitterApi())
1166 var mock = new Mock<IApiConnection>();
1168 x.PostLazyAsync<TwitterUser>(
1169 new Uri("account/update_profile.json", UriKind.Relative),
1170 new Dictionary<string, string> {
1171 { "include_entities", "true" },
1172 { "include_ext_alt_text", "true" },
1173 { "tweet_mode", "extended" },
1175 { "url", "http://example.com/" },
1176 { "location", "Location" },
1177 { "description", "<script>alert(1)</script>" },
1180 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1182 twitterApi.apiConnection = mock.Object;
1184 await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
1186 .ConfigureAwait(false);
1193 public async Task AccountUpdateProfileImage_Test()
1195 using (var twitterApi = new TwitterApi())
1196 using (var image = TestUtils.CreateDummyImage())
1197 using (var media = new MemoryImageMediaItem(image))
1199 var mock = new Mock<IApiConnection>();
1201 x.PostLazyAsync<TwitterUser>(
1202 new Uri("account/update_profile_image.json", UriKind.Relative),
1203 new Dictionary<string, string> {
1204 { "include_entities", "true" },
1205 { "include_ext_alt_text", "true" },
1206 { "tweet_mode", "extended" },
1208 new Dictionary<string, IMediaItem> { { "image", media } })
1210 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1212 twitterApi.apiConnection = mock.Object;
1214 await twitterApi.AccountUpdateProfileImage(media)
1216 .ConfigureAwait(false);
1223 public async Task ApplicationRateLimitStatus_Test()
1225 using (var twitterApi = new TwitterApi())
1227 var mock = new Mock<IApiConnection>();
1229 x.GetAsync<TwitterRateLimits>(
1230 new Uri("application/rate_limit_status.json", UriKind.Relative),
1232 "/application/rate_limit_status")
1234 .ReturnsAsync(new TwitterRateLimits());
1236 twitterApi.apiConnection = mock.Object;
1238 await twitterApi.ApplicationRateLimitStatus()
1239 .ConfigureAwait(false);
1246 public async Task Configuration_Test()
1248 using (var twitterApi = new TwitterApi())
1250 var mock = new Mock<IApiConnection>();
1252 x.GetAsync<TwitterConfiguration>(
1253 new Uri("help/configuration.json", UriKind.Relative),
1255 "/help/configuration")
1257 .ReturnsAsync(new TwitterConfiguration());
1259 twitterApi.apiConnection = mock.Object;
1261 await twitterApi.Configuration()
1262 .ConfigureAwait(false);
1269 public async Task MediaUploadInit_Test()
1271 using (var twitterApi = new TwitterApi())
1273 var mock = new Mock<IApiConnection>();
1275 x.PostLazyAsync<TwitterUploadMediaInit>(
1276 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1277 new Dictionary<string, string> {
1278 { "command", "INIT" },
1279 { "total_bytes", "123456" },
1280 { "media_type", "image/png" },
1281 { "media_category", "dm_image" },
1284 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaInit()));
1286 twitterApi.apiConnection = mock.Object;
1288 await twitterApi.MediaUploadInit(totalBytes: 123456L, mediaType: "image/png", mediaCategory: "dm_image")
1290 .ConfigureAwait(false);
1297 public async Task MediaUploadAppend_Test()
1299 using (var twitterApi = new TwitterApi())
1300 using (var image = TestUtils.CreateDummyImage())
1301 using (var media = new MemoryImageMediaItem(image))
1303 var mock = new Mock<IApiConnection>();
1306 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1307 new Dictionary<string, string> {
1308 { "command", "APPEND" },
1309 { "media_id", "11111" },
1310 { "segment_index", "1" },
1312 new Dictionary<string, IMediaItem> { { "media", media } })
1314 .Returns(Task.CompletedTask);
1316 twitterApi.apiConnection = mock.Object;
1318 await twitterApi.MediaUploadAppend(mediaId: 11111L, segmentIndex: 1, media: media)
1319 .ConfigureAwait(false);
1326 public async Task MediaUploadFinalize_Test()
1328 using (var twitterApi = new TwitterApi())
1330 var mock = new Mock<IApiConnection>();
1332 x.PostLazyAsync<TwitterUploadMediaResult>(
1333 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1334 new Dictionary<string, string> {
1335 { "command", "FINALIZE" },
1336 { "media_id", "11111" },
1339 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
1341 twitterApi.apiConnection = mock.Object;
1343 await twitterApi.MediaUploadFinalize(mediaId: 11111L)
1345 .ConfigureAwait(false);
1352 public async Task MediaUploadStatus_Test()
1354 using (var twitterApi = new TwitterApi())
1356 var mock = new Mock<IApiConnection>();
1358 x.GetAsync<TwitterUploadMediaResult>(
1359 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1360 new Dictionary<string, string> {
1361 { "command", "STATUS" },
1362 { "media_id", "11111" },
1366 .ReturnsAsync(new TwitterUploadMediaResult());
1368 twitterApi.apiConnection = mock.Object;
1370 await twitterApi.MediaUploadStatus(mediaId: 11111L)
1371 .ConfigureAwait(false);
1378 public async Task MediaMetadataCreate_Test()
1380 using (var twitterApi = new TwitterApi())
1382 var mock = new Mock<IApiConnection>();
1385 new Uri("https://upload.twitter.com/1.1/media/metadata/create.json", UriKind.Absolute),
1386 "{\"media_id\": \"12345\", \"alt_text\": {\"text\": \"hogehoge\"}}")
1388 .Returns(Task.CompletedTask);
1390 twitterApi.apiConnection = mock.Object;
1392 await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge")
1393 .ConfigureAwait(false);
1400 public async Task UserStreams_Test()
1402 using (var twitterApi = new TwitterApi())
1404 var mock = new Mock<IApiConnection>();
1406 x.GetStreamingStreamAsync(
1407 new Uri("https://userstream.twitter.com/1.1/user.json", UriKind.Absolute),
1408 new Dictionary<string, string> {
1409 { "replies", "all" },
1410 { "track", "OpenTween" },
1413 .ReturnsAsync(new MemoryStream());
1415 twitterApi.apiConnection = mock.Object;
1417 var observable = twitterApi.UserStreams(replies: "all", track: "OpenTween");
1418 await observable.ForEachAsync(x => { });