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()
45 public void MyCommonSetup()
47 var mockAssembly = new Mock<_Assembly>();
48 mockAssembly.Setup(m => m.GetName()).Returns(new AssemblyName("OpenTween"));
50 MyCommon.EntryAssembly = mockAssembly.Object;
54 public void Initialize_Test()
56 using (var twitterApi = new TwitterApi())
58 Assert.Null(twitterApi.apiConnection);
60 twitterApi.Initialize("*** AccessToken ***", "*** AccessSecret ***", userId: 100L, screenName: "hogehoge");
62 Assert.IsType<TwitterApiConnection>(twitterApi.apiConnection);
64 var apiConnection = (TwitterApiConnection)twitterApi.apiConnection;
65 Assert.Equal("*** AccessToken ***", apiConnection.AccessToken);
66 Assert.Equal("*** AccessSecret ***", apiConnection.AccessSecret);
68 Assert.Equal(100L, twitterApi.CurrentUserId);
69 Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
71 // 複数回 Initialize を実行した場合は新たに TwitterApiConnection が生成される
72 twitterApi.Initialize("*** AccessToken2 ***", "*** AccessSecret2 ***", userId: 200L, screenName: "foobar");
74 var oldApiConnection = apiConnection;
75 Assert.True(oldApiConnection.IsDisposed);
77 Assert.IsType<TwitterApiConnection>(twitterApi.apiConnection);
79 apiConnection = (TwitterApiConnection)twitterApi.apiConnection;
80 Assert.Equal("*** AccessToken2 ***", apiConnection.AccessToken);
81 Assert.Equal("*** AccessSecret2 ***", apiConnection.AccessSecret);
83 Assert.Equal(200L, twitterApi.CurrentUserId);
84 Assert.Equal("foobar", twitterApi.CurrentScreenName);
89 public async Task StatusesHomeTimeline_Test()
91 using (var twitterApi = new TwitterApi())
93 var mock = new Mock<IApiConnection>();
95 x.GetAsync<TwitterStatus[]>(
96 new Uri("statuses/home_timeline.json", UriKind.Relative),
97 new Dictionary<string, string> {
98 { "include_entities", "true" },
99 { "include_ext_alt_text", "true" },
100 { "tweet_mode", "extended" },
103 { "since_id", "100" },
105 "/statuses/home_timeline")
107 .ReturnsAsync(new TwitterStatus[0]);
109 twitterApi.apiConnection = mock.Object;
111 await twitterApi.StatusesHomeTimeline(200, maxId: 900L, sinceId: 100L)
112 .ConfigureAwait(false);
119 public async Task StatusesMentionsTimeline_Test()
121 using (var twitterApi = new TwitterApi())
123 var mock = new Mock<IApiConnection>();
125 x.GetAsync<TwitterStatus[]>(
126 new Uri("statuses/mentions_timeline.json", UriKind.Relative),
127 new Dictionary<string, string> {
128 { "include_entities", "true" },
129 { "include_ext_alt_text", "true" },
130 { "tweet_mode", "extended" },
133 { "since_id", "100" },
135 "/statuses/mentions_timeline")
137 .ReturnsAsync(new TwitterStatus[0]);
139 twitterApi.apiConnection = mock.Object;
141 await twitterApi.StatusesMentionsTimeline(200, maxId: 900L, sinceId: 100L)
142 .ConfigureAwait(false);
149 public async Task StatusesUserTimeline_Test()
151 using (var twitterApi = new TwitterApi())
153 var mock = new Mock<IApiConnection>();
155 x.GetAsync<TwitterStatus[]>(
156 new Uri("statuses/user_timeline.json", UriKind.Relative),
157 new Dictionary<string, string> {
158 { "screen_name", "twitterapi" },
159 { "include_rts", "true" },
160 { "include_entities", "true" },
161 { "include_ext_alt_text", "true" },
162 { "tweet_mode", "extended" },
165 { "since_id", "100" },
167 "/statuses/user_timeline")
169 .ReturnsAsync(new TwitterStatus[0]);
171 twitterApi.apiConnection = mock.Object;
173 await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: 900L, sinceId: 100L)
174 .ConfigureAwait(false);
181 public async Task StatusesShow_Test()
183 using (var twitterApi = new TwitterApi())
185 var mock = new Mock<IApiConnection>();
187 x.GetAsync<TwitterStatus>(
188 new Uri("statuses/show.json", UriKind.Relative),
189 new Dictionary<string, string> {
191 { "include_entities", "true" },
192 { "include_ext_alt_text", "true" },
193 { "tweet_mode", "extended" },
195 "/statuses/show/:id")
197 .ReturnsAsync(new TwitterStatus { Id = 100L });
199 twitterApi.apiConnection = mock.Object;
201 await twitterApi.StatusesShow(statusId: 100L)
202 .ConfigureAwait(false);
209 public async Task StatusesUpdate_Test()
211 using (var twitterApi = new TwitterApi())
213 var mock = new Mock<IApiConnection>();
215 x.PostLazyAsync<TwitterStatus>(
216 new Uri("statuses/update.json", UriKind.Relative),
217 new Dictionary<string, string> {
218 { "status", "hogehoge" },
219 { "include_entities", "true" },
220 { "include_ext_alt_text", "true" },
221 { "tweet_mode", "extended" },
222 { "in_reply_to_status_id", "100" },
223 { "media_ids", "10,20" },
224 { "auto_populate_reply_metadata", "true" },
225 { "exclude_reply_user_ids", "100,200" },
228 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
230 twitterApi.apiConnection = mock.Object;
232 await twitterApi.StatusesUpdate("hogehoge", replyToId: 100L, mediaIds: new[] { 10L, 20L },
233 autoPopulateReplyMetadata: true, excludeReplyUserIds: new[] { 100L, 200L })
235 .ConfigureAwait(false);
242 public async Task StatusesDestroy_Test()
244 using (var twitterApi = new TwitterApi())
246 var mock = new Mock<IApiConnection>();
248 x.PostLazyAsync<TwitterStatus>(
249 new Uri("statuses/destroy.json", UriKind.Relative),
250 new Dictionary<string, string> { { "id", "100" } })
252 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
254 twitterApi.apiConnection = mock.Object;
256 await twitterApi.StatusesDestroy(statusId: 100L)
258 .ConfigureAwait(false);
265 public async Task StatusesRetweet_Test()
267 using (var twitterApi = new TwitterApi())
269 var mock = new Mock<IApiConnection>();
271 x.PostLazyAsync<TwitterStatus>(
272 new Uri("statuses/retweet.json", UriKind.Relative),
273 new Dictionary<string, string> {
275 { "include_entities", "true" },
276 { "include_ext_alt_text", "true" },
277 { "tweet_mode", "extended" },
280 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
282 twitterApi.apiConnection = mock.Object;
284 await twitterApi.StatusesRetweet(100L)
286 .ConfigureAwait(false);
293 public async Task SearchTweets_Test()
295 using (var twitterApi = new TwitterApi())
297 var mock = new Mock<IApiConnection>();
299 x.GetAsync<TwitterSearchResult>(
300 new Uri("search/tweets.json", UriKind.Relative),
301 new Dictionary<string, string> {
302 { "q", "from:twitterapi" },
303 { "result_type", "recent" },
304 { "include_entities", "true" },
305 { "include_ext_alt_text", "true" },
306 { "tweet_mode", "extended" },
310 { "since_id", "100" },
314 .ReturnsAsync(new TwitterSearchResult());
316 twitterApi.apiConnection = mock.Object;
318 await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: 900L, sinceId: 100L)
319 .ConfigureAwait(false);
326 public async Task ListsOwnerships_Test()
328 using (var twitterApi = new TwitterApi())
330 var mock = new Mock<IApiConnection>();
332 x.GetAsync<TwitterLists>(
333 new Uri("lists/ownerships.json", UriKind.Relative),
334 new Dictionary<string, string> {
335 { "screen_name", "twitterapi" },
341 .ReturnsAsync(new TwitterLists());
343 twitterApi.apiConnection = mock.Object;
345 await twitterApi.ListsOwnerships("twitterapi", cursor: -1L, count: 100)
346 .ConfigureAwait(false);
353 public async Task ListsSubscriptions_Test()
355 using (var twitterApi = new TwitterApi())
357 var mock = new Mock<IApiConnection>();
359 x.GetAsync<TwitterLists>(
360 new Uri("lists/subscriptions.json", UriKind.Relative),
361 new Dictionary<string, string> {
362 { "screen_name", "twitterapi" },
366 "/lists/subscriptions")
368 .ReturnsAsync(new TwitterLists());
370 twitterApi.apiConnection = mock.Object;
372 await twitterApi.ListsSubscriptions("twitterapi", cursor: -1L, count: 100)
373 .ConfigureAwait(false);
380 public async Task ListsMemberships_Test()
382 using (var twitterApi = new TwitterApi())
384 var mock = new Mock<IApiConnection>();
386 x.GetAsync<TwitterLists>(
387 new Uri("lists/memberships.json", UriKind.Relative),
388 new Dictionary<string, string> {
389 { "screen_name", "twitterapi" },
392 { "filter_to_owned_lists", "true" },
394 "/lists/memberships")
396 .ReturnsAsync(new TwitterLists());
398 twitterApi.apiConnection = mock.Object;
400 await twitterApi.ListsMemberships("twitterapi", cursor: -1L, count: 100, filterToOwnedLists: true)
401 .ConfigureAwait(false);
408 public async Task ListsCreate_Test()
410 using (var twitterApi = new TwitterApi())
412 var mock = new Mock<IApiConnection>();
414 x.PostLazyAsync<TwitterList>(
415 new Uri("lists/create.json", UriKind.Relative),
416 new Dictionary<string, string> {
417 { "name", "hogehoge" },
418 { "description", "aaaa" },
419 { "mode", "private" },
422 .ReturnsAsync(LazyJson.Create(new TwitterList()));
424 twitterApi.apiConnection = mock.Object;
426 await twitterApi.ListsCreate("hogehoge", description: "aaaa", @private: true)
428 .ConfigureAwait(false);
435 public async Task ListsUpdate_Test()
437 using (var twitterApi = new TwitterApi())
439 var mock = new Mock<IApiConnection>();
441 x.PostLazyAsync<TwitterList>(
442 new Uri("lists/update.json", UriKind.Relative),
443 new Dictionary<string, string> {
444 { "list_id", "12345" },
445 { "name", "hogehoge" },
446 { "description", "aaaa" },
447 { "mode", "private" },
450 .ReturnsAsync(LazyJson.Create(new TwitterList()));
452 twitterApi.apiConnection = mock.Object;
454 await twitterApi.ListsUpdate(12345L, name: "hogehoge", description: "aaaa", @private: true)
456 .ConfigureAwait(false);
463 public async Task ListsDestroy_Test()
465 using (var twitterApi = new TwitterApi())
467 var mock = new Mock<IApiConnection>();
469 x.PostLazyAsync<TwitterList>(
470 new Uri("lists/destroy.json", UriKind.Relative),
471 new Dictionary<string, string> {
472 { "list_id", "12345" },
475 .ReturnsAsync(LazyJson.Create(new TwitterList()));
477 twitterApi.apiConnection = mock.Object;
479 await twitterApi.ListsDestroy(12345L)
481 .ConfigureAwait(false);
488 public async Task ListsStatuses_Test()
490 using (var twitterApi = new TwitterApi())
492 var mock = new Mock<IApiConnection>();
494 x.GetAsync<TwitterStatus[]>(
495 new Uri("lists/statuses.json", UriKind.Relative),
496 new Dictionary<string, string> {
497 { "list_id", "12345" },
498 { "include_entities", "true" },
499 { "include_ext_alt_text", "true" },
500 { "tweet_mode", "extended" },
503 { "since_id", "100" },
504 { "include_rts", "true" },
508 .ReturnsAsync(new TwitterStatus[0]);
510 twitterApi.apiConnection = mock.Object;
512 await twitterApi.ListsStatuses(12345L, count: 200, maxId: 900L, sinceId: 100L, includeRTs: true)
513 .ConfigureAwait(false);
520 public async Task ListsMembers_Test()
522 using (var twitterApi = new TwitterApi())
524 var mock = new Mock<IApiConnection>();
526 x.GetAsync<TwitterUsers>(
527 new Uri("lists/members.json", UriKind.Relative),
528 new Dictionary<string, string> {
529 { "list_id", "12345" },
530 { "include_entities", "true" },
531 { "include_ext_alt_text", "true" },
532 { "tweet_mode", "extended" },
537 .ReturnsAsync(new TwitterUsers());
539 twitterApi.apiConnection = mock.Object;
541 await twitterApi.ListsMembers(12345L, cursor: -1)
542 .ConfigureAwait(false);
549 public async Task ListsMembersShow_Test()
551 using (var twitterApi = new TwitterApi())
553 var mock = new Mock<IApiConnection>();
555 x.GetAsync<TwitterUser>(
556 new Uri("lists/members/show.json", UriKind.Relative),
557 new Dictionary<string, string> {
558 { "list_id", "12345" },
559 { "screen_name", "twitterapi" },
560 { "include_entities", "true" },
561 { "include_ext_alt_text", "true" },
562 { "tweet_mode", "extended" },
564 "/lists/members/show")
566 .ReturnsAsync(new TwitterUser());
568 twitterApi.apiConnection = mock.Object;
570 await twitterApi.ListsMembersShow(12345L, "twitterapi")
571 .ConfigureAwait(false);
578 public async Task ListsMembersCreate_Test()
580 using (var twitterApi = new TwitterApi())
582 var mock = new Mock<IApiConnection>();
584 x.PostLazyAsync<TwitterUser>(
585 new Uri("lists/members/create.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" },
594 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
596 twitterApi.apiConnection = mock.Object;
598 await twitterApi.ListsMembersCreate(12345L, "twitterapi")
600 .ConfigureAwait(false);
607 public async Task ListsMembersDestroy_Test()
609 using (var twitterApi = new TwitterApi())
611 var mock = new Mock<IApiConnection>();
613 x.PostLazyAsync<TwitterUser>(
614 new Uri("lists/members/destroy.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.ListsMembersDestroy(12345L, "twitterapi")
629 .ConfigureAwait(false);
636 public async Task DirectMessagesRecv_Test()
638 using (var twitterApi = new TwitterApi())
640 var mock = new Mock<IApiConnection>();
642 x.GetAsync<TwitterDirectMessage[]>(
643 new Uri("direct_messages.json", UriKind.Relative),
644 new Dictionary<string, string> {
645 { "full_text", "true" },
646 { "include_entities", "true" },
647 { "include_ext_alt_text", "true" },
650 { "since_id", "100" },
654 .ReturnsAsync(new TwitterDirectMessage[0]);
656 twitterApi.apiConnection = mock.Object;
658 await twitterApi.DirectMessagesRecv(count: 200, maxId: 900L, sinceId: 100L)
659 .ConfigureAwait(false);
666 public async Task DirectMessagesSent_Test()
668 using (var twitterApi = new TwitterApi())
670 var mock = new Mock<IApiConnection>();
672 x.GetAsync<TwitterDirectMessage[]>(
673 new Uri("direct_messages/sent.json", UriKind.Relative),
674 new Dictionary<string, string> {
675 { "full_text", "true" },
676 { "include_entities", "true" },
677 { "include_ext_alt_text", "true" },
680 { "since_id", "100" },
682 "/direct_messages/sent")
684 .ReturnsAsync(new TwitterDirectMessage[0]);
686 twitterApi.apiConnection = mock.Object;
688 await twitterApi.DirectMessagesSent(count: 200, maxId: 900L, sinceId: 100L)
689 .ConfigureAwait(false);
696 public async Task DirectMessagesNew_Test()
698 using (var twitterApi = new TwitterApi())
700 var mock = new Mock<IApiConnection>();
702 x.PostLazyAsync<TwitterDirectMessage>(
703 new Uri("direct_messages/new.json", UriKind.Relative),
704 new Dictionary<string, string> {
705 { "text", "hogehoge" },
706 { "screen_name", "opentween" },
709 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage()));
711 twitterApi.apiConnection = mock.Object;
713 await twitterApi.DirectMessagesNew("hogehoge", "opentween")
715 .ConfigureAwait(false);
722 public async Task DirectMessagesDestroy_Test()
724 using (var twitterApi = new TwitterApi())
726 var mock = new Mock<IApiConnection>();
728 x.PostLazyAsync<TwitterDirectMessage>(
729 new Uri("direct_messages/destroy.json", UriKind.Relative),
730 new Dictionary<string, string> { { "id", "100" } })
732 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage { Id = 100L }));
734 twitterApi.apiConnection = mock.Object;
736 await twitterApi.DirectMessagesDestroy(statusId: 100L)
738 .ConfigureAwait(false);
745 public async Task UsersShow_Test()
747 using (var twitterApi = new TwitterApi())
749 var mock = new Mock<IApiConnection>();
751 x.GetAsync<TwitterUser>(
752 new Uri("users/show.json", UriKind.Relative),
753 new Dictionary<string, string> {
754 { "screen_name", "twitterapi" },
755 { "include_entities", "true" },
756 { "include_ext_alt_text", "true" },
757 { "tweet_mode", "extended" },
761 .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
763 twitterApi.apiConnection = mock.Object;
765 await twitterApi.UsersShow(screenName: "twitterapi")
766 .ConfigureAwait(false);
773 public async Task UsersReportSpam_Test()
775 using (var twitterApi = new TwitterApi())
777 var mock = new Mock<IApiConnection>();
779 x.PostLazyAsync<TwitterUser>(
780 new Uri("users/report_spam.json", UriKind.Relative),
781 new Dictionary<string, string> {
782 { "screen_name", "twitterapi" },
783 { "tweet_mode", "extended" },
786 .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
788 twitterApi.apiConnection = mock.Object;
790 await twitterApi.UsersReportSpam(screenName: "twitterapi")
792 .ConfigureAwait(false);
799 public async Task FavoritesList_Test()
801 using (var twitterApi = new TwitterApi())
803 var mock = new Mock<IApiConnection>();
805 x.GetAsync<TwitterStatus[]>(
806 new Uri("favorites/list.json", UriKind.Relative),
807 new Dictionary<string, string> {
808 { "include_entities", "true" },
809 { "include_ext_alt_text", "true" },
810 { "tweet_mode", "extended" },
813 { "since_id", "100" },
817 .ReturnsAsync(new TwitterStatus[0]);
819 twitterApi.apiConnection = mock.Object;
821 await twitterApi.FavoritesList(200, maxId: 900L, sinceId: 100L)
822 .ConfigureAwait(false);
829 public async Task FavoritesCreate_Test()
831 using (var twitterApi = new TwitterApi())
833 var mock = new Mock<IApiConnection>();
835 x.PostLazyAsync<TwitterStatus>(
836 new Uri("favorites/create.json", UriKind.Relative),
837 new Dictionary<string, string> {
839 { "tweet_mode", "extended" },
842 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
844 twitterApi.apiConnection = mock.Object;
846 await twitterApi.FavoritesCreate(statusId: 100L)
848 .ConfigureAwait(false);
855 public async Task FavoritesDestroy_Test()
857 using (var twitterApi = new TwitterApi())
859 var mock = new Mock<IApiConnection>();
861 x.PostLazyAsync<TwitterStatus>(
862 new Uri("favorites/destroy.json", UriKind.Relative),
863 new Dictionary<string, string> {
865 { "tweet_mode", "extended" },
868 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
870 twitterApi.apiConnection = mock.Object;
872 await twitterApi.FavoritesDestroy(statusId: 100L)
874 .ConfigureAwait(false);
881 public async Task FriendshipsShow_Test()
883 using (var twitterApi = new TwitterApi())
885 var mock = new Mock<IApiConnection>();
887 x.GetAsync<TwitterFriendship>(
888 new Uri("friendships/show.json", UriKind.Relative),
889 new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } },
892 .ReturnsAsync(new TwitterFriendship());
894 twitterApi.apiConnection = mock.Object;
896 await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi")
897 .ConfigureAwait(false);
904 public async Task FriendshipsCreate_Test()
906 using (var twitterApi = new TwitterApi())
908 var mock = new Mock<IApiConnection>();
910 x.PostLazyAsync<TwitterFriendship>(
911 new Uri("friendships/create.json", UriKind.Relative),
912 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
914 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
916 twitterApi.apiConnection = mock.Object;
918 await twitterApi.FriendshipsCreate(screenName: "twitterapi")
920 .ConfigureAwait(false);
927 public async Task FriendshipsDestroy_Test()
929 using (var twitterApi = new TwitterApi())
931 var mock = new Mock<IApiConnection>();
933 x.PostLazyAsync<TwitterFriendship>(
934 new Uri("friendships/destroy.json", UriKind.Relative),
935 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
937 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
939 twitterApi.apiConnection = mock.Object;
941 await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
943 .ConfigureAwait(false);
950 public async Task NoRetweetIds_Test()
952 using (var twitterApi = new TwitterApi())
954 var mock = new Mock<IApiConnection>();
957 new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
959 "/friendships/no_retweets/ids")
961 .ReturnsAsync(new long[0]);
963 twitterApi.apiConnection = mock.Object;
965 await twitterApi.NoRetweetIds()
966 .ConfigureAwait(false);
973 public async Task FollowersIds_Test()
975 using (var twitterApi = new TwitterApi())
977 var mock = new Mock<IApiConnection>();
979 x.GetAsync<TwitterIds>(
980 new Uri("followers/ids.json", UriKind.Relative),
981 new Dictionary<string, string> { { "cursor", "-1" } },
984 .ReturnsAsync(new TwitterIds());
986 twitterApi.apiConnection = mock.Object;
988 await twitterApi.FollowersIds(cursor: -1L)
989 .ConfigureAwait(false);
996 public async Task MutesUsersIds_Test()
998 using (var twitterApi = new TwitterApi())
1000 var mock = new Mock<IApiConnection>();
1002 x.GetAsync<TwitterIds>(
1003 new Uri("mutes/users/ids.json", UriKind.Relative),
1004 new Dictionary<string, string> { { "cursor", "-1" } },
1007 .ReturnsAsync(new TwitterIds());
1009 twitterApi.apiConnection = mock.Object;
1011 await twitterApi.MutesUsersIds(cursor: -1L)
1012 .ConfigureAwait(false);
1019 public async Task BlocksIds_Test()
1021 using (var twitterApi = new TwitterApi())
1023 var mock = new Mock<IApiConnection>();
1025 x.GetAsync<TwitterIds>(
1026 new Uri("blocks/ids.json", UriKind.Relative),
1027 new Dictionary<string, string> { { "cursor", "-1" } },
1030 .ReturnsAsync(new TwitterIds());
1032 twitterApi.apiConnection = mock.Object;
1034 await twitterApi.BlocksIds(cursor: -1L)
1035 .ConfigureAwait(false);
1042 public async Task BlocksCreate_Test()
1044 using (var twitterApi = new TwitterApi())
1046 var mock = new Mock<IApiConnection>();
1048 x.PostLazyAsync<TwitterUser>(
1049 new Uri("blocks/create.json", UriKind.Relative),
1050 new Dictionary<string, string> {
1051 { "screen_name", "twitterapi" },
1052 { "tweet_mode", "extended" },
1055 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1057 twitterApi.apiConnection = mock.Object;
1059 await twitterApi.BlocksCreate(screenName: "twitterapi")
1061 .ConfigureAwait(false);
1068 public async Task BlocksDestroy_Test()
1070 using (var twitterApi = new TwitterApi())
1072 var mock = new Mock<IApiConnection>();
1074 x.PostLazyAsync<TwitterUser>(
1075 new Uri("blocks/destroy.json", UriKind.Relative),
1076 new Dictionary<string, string> {
1077 { "screen_name", "twitterapi" },
1078 { "tweet_mode", "extended" },
1081 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1083 twitterApi.apiConnection = mock.Object;
1085 await twitterApi.BlocksDestroy(screenName: "twitterapi")
1087 .ConfigureAwait(false);
1094 public async Task AccountVerifyCredentials_Test()
1096 using (var twitterApi = new TwitterApi())
1098 var mock = new Mock<IApiConnection>();
1100 x.GetAsync<TwitterUser>(
1101 new Uri("account/verify_credentials.json", UriKind.Relative),
1102 new Dictionary<string, string> {
1103 { "include_entities", "true" },
1104 { "include_ext_alt_text", "true" },
1105 { "tweet_mode", "extended" },
1107 "/account/verify_credentials")
1109 .ReturnsAsync(new TwitterUser {
1111 ScreenName = "opentween",
1114 twitterApi.apiConnection = mock.Object;
1116 await twitterApi.AccountVerifyCredentials()
1117 .ConfigureAwait(false);
1119 Assert.Equal(100L, twitterApi.CurrentUserId);
1120 Assert.Equal("opentween", twitterApi.CurrentScreenName);
1127 public async Task AccountUpdateProfile_Test()
1129 using (var twitterApi = new TwitterApi())
1131 var mock = new Mock<IApiConnection>();
1133 x.PostLazyAsync<TwitterUser>(
1134 new Uri("account/update_profile.json", UriKind.Relative),
1135 new Dictionary<string, string> {
1136 { "include_entities", "true" },
1137 { "include_ext_alt_text", "true" },
1138 { "tweet_mode", "extended" },
1140 { "url", "http://example.com/" },
1141 { "location", "Location" },
1142 { "description", "<script>alert(1)</script>" },
1145 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1147 twitterApi.apiConnection = mock.Object;
1149 await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
1151 .ConfigureAwait(false);
1158 public async Task AccountUpdateProfileImage_Test()
1160 using (var twitterApi = new TwitterApi())
1161 using (var image = TestUtils.CreateDummyImage())
1162 using (var media = new MemoryImageMediaItem(image))
1164 var mock = new Mock<IApiConnection>();
1166 x.PostLazyAsync<TwitterUser>(
1167 new Uri("account/update_profile_image.json", UriKind.Relative),
1168 new Dictionary<string, string> {
1169 { "include_entities", "true" },
1170 { "include_ext_alt_text", "true" },
1171 { "tweet_mode", "extended" },
1173 new Dictionary<string, IMediaItem> { { "image", media } })
1175 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1177 twitterApi.apiConnection = mock.Object;
1179 await twitterApi.AccountUpdateProfileImage(media)
1181 .ConfigureAwait(false);
1188 public async Task ApplicationRateLimitStatus_Test()
1190 using (var twitterApi = new TwitterApi())
1192 var mock = new Mock<IApiConnection>();
1194 x.GetAsync<TwitterRateLimits>(
1195 new Uri("application/rate_limit_status.json", UriKind.Relative),
1197 "/application/rate_limit_status")
1199 .ReturnsAsync(new TwitterRateLimits());
1201 twitterApi.apiConnection = mock.Object;
1203 await twitterApi.ApplicationRateLimitStatus()
1204 .ConfigureAwait(false);
1211 public async Task Configuration_Test()
1213 using (var twitterApi = new TwitterApi())
1215 var mock = new Mock<IApiConnection>();
1217 x.GetAsync<TwitterConfiguration>(
1218 new Uri("help/configuration.json", UriKind.Relative),
1220 "/help/configuration")
1222 .ReturnsAsync(new TwitterConfiguration());
1224 twitterApi.apiConnection = mock.Object;
1226 await twitterApi.Configuration()
1227 .ConfigureAwait(false);
1234 public async Task MediaUpload_Test()
1236 using (var twitterApi = new TwitterApi())
1237 using (var image = TestUtils.CreateDummyImage())
1238 using (var media = new MemoryImageMediaItem(image))
1240 var mock = new Mock<IApiConnection>();
1242 x.PostLazyAsync<TwitterUploadMediaResult>(
1243 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1245 new Dictionary<string, IMediaItem> { { "media", media } })
1247 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
1249 twitterApi.apiConnection = mock.Object;
1251 await twitterApi.MediaUpload(media)
1253 .ConfigureAwait(false);
1260 public async Task MediaMetadataCreate_Test()
1262 using (var twitterApi = new TwitterApi())
1264 var mock = new Mock<IApiConnection>();
1267 new Uri("https://upload.twitter.com/1.1/media/metadata/create.json", UriKind.Absolute),
1268 "{\"media_id\": \"12345\", \"alt_text\": {\"text\": \"hogehoge\"}}")
1270 .Returns(Task.FromResult(0));
1272 twitterApi.apiConnection = mock.Object;
1274 await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge")
1275 .ConfigureAwait(false);
1282 public async Task UserStreams_Test()
1284 using (var twitterApi = new TwitterApi())
1286 var mock = new Mock<IApiConnection>();
1288 x.GetStreamingStreamAsync(
1289 new Uri("https://userstream.twitter.com/1.1/user.json", UriKind.Absolute),
1290 new Dictionary<string, string> {
1291 { "replies", "all" },
1292 { "track", "OpenTween" },
1295 .ReturnsAsync(new MemoryStream());
1297 twitterApi.apiConnection = mock.Object;
1299 var stream = await twitterApi.UserStreams(replies: "all", track: "OpenTween")
1300 .ConfigureAwait(false);
1309 [InlineData("", "")]
1310 [InlineData("123ABCabc", "123ABCabc")]
1311 [InlineData(@"\", @"\\")]
1312 [InlineData("\"", "\\\"")]
1313 [InlineData("\n", @"\u000A")]
1314 [InlineData("\U0001D11E", @"\uD834\uDD1E")]
1315 public void EscapeJsonString_Test(string targetText, string expectedText)
1317 Assert.Equal(expectedText, TwitterApi.EscapeJsonString(targetText));