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" },
226 { "attachment_url", "https://twitter.com/twitterapi/status/22634515958" },
229 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
231 twitterApi.apiConnection = mock.Object;
233 await twitterApi.StatusesUpdate("hogehoge", replyToId: 100L, mediaIds: new[] { 10L, 20L },
234 autoPopulateReplyMetadata: true, excludeReplyUserIds: new[] { 100L, 200L },
235 attachmentUrl: "https://twitter.com/twitterapi/status/22634515958")
237 .ConfigureAwait(false);
244 public async Task StatusesUpdate_ExcludeReplyUserIdsEmptyTest()
246 using (var twitterApi = new TwitterApi())
248 var mock = new Mock<IApiConnection>();
250 x.PostLazyAsync<TwitterStatus>(
251 new Uri("statuses/update.json", UriKind.Relative),
252 new Dictionary<string, string> {
253 { "status", "hogehoge" },
254 { "include_entities", "true" },
255 { "include_ext_alt_text", "true" },
256 { "tweet_mode", "extended" },
257 // exclude_reply_user_ids は空の場合には送信されない
260 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
262 twitterApi.apiConnection = mock.Object;
264 await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: new long[0])
266 .ConfigureAwait(false);
273 public async Task StatusesDestroy_Test()
275 using (var twitterApi = new TwitterApi())
277 var mock = new Mock<IApiConnection>();
279 x.PostLazyAsync<TwitterStatus>(
280 new Uri("statuses/destroy.json", UriKind.Relative),
281 new Dictionary<string, string> { { "id", "100" } })
283 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
285 twitterApi.apiConnection = mock.Object;
287 await twitterApi.StatusesDestroy(statusId: 100L)
289 .ConfigureAwait(false);
296 public async Task StatusesRetweet_Test()
298 using (var twitterApi = new TwitterApi())
300 var mock = new Mock<IApiConnection>();
302 x.PostLazyAsync<TwitterStatus>(
303 new Uri("statuses/retweet.json", UriKind.Relative),
304 new Dictionary<string, string> {
306 { "include_entities", "true" },
307 { "include_ext_alt_text", "true" },
308 { "tweet_mode", "extended" },
311 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
313 twitterApi.apiConnection = mock.Object;
315 await twitterApi.StatusesRetweet(100L)
317 .ConfigureAwait(false);
324 public async Task SearchTweets_Test()
326 using (var twitterApi = new TwitterApi())
328 var mock = new Mock<IApiConnection>();
330 x.GetAsync<TwitterSearchResult>(
331 new Uri("search/tweets.json", UriKind.Relative),
332 new Dictionary<string, string> {
333 { "q", "from:twitterapi" },
334 { "result_type", "recent" },
335 { "include_entities", "true" },
336 { "include_ext_alt_text", "true" },
337 { "tweet_mode", "extended" },
341 { "since_id", "100" },
345 .ReturnsAsync(new TwitterSearchResult());
347 twitterApi.apiConnection = mock.Object;
349 await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: 900L, sinceId: 100L)
350 .ConfigureAwait(false);
357 public async Task ListsOwnerships_Test()
359 using (var twitterApi = new TwitterApi())
361 var mock = new Mock<IApiConnection>();
363 x.GetAsync<TwitterLists>(
364 new Uri("lists/ownerships.json", UriKind.Relative),
365 new Dictionary<string, string> {
366 { "screen_name", "twitterapi" },
372 .ReturnsAsync(new TwitterLists());
374 twitterApi.apiConnection = mock.Object;
376 await twitterApi.ListsOwnerships("twitterapi", cursor: -1L, count: 100)
377 .ConfigureAwait(false);
384 public async Task ListsSubscriptions_Test()
386 using (var twitterApi = new TwitterApi())
388 var mock = new Mock<IApiConnection>();
390 x.GetAsync<TwitterLists>(
391 new Uri("lists/subscriptions.json", UriKind.Relative),
392 new Dictionary<string, string> {
393 { "screen_name", "twitterapi" },
397 "/lists/subscriptions")
399 .ReturnsAsync(new TwitterLists());
401 twitterApi.apiConnection = mock.Object;
403 await twitterApi.ListsSubscriptions("twitterapi", cursor: -1L, count: 100)
404 .ConfigureAwait(false);
411 public async Task ListsMemberships_Test()
413 using (var twitterApi = new TwitterApi())
415 var mock = new Mock<IApiConnection>();
417 x.GetAsync<TwitterLists>(
418 new Uri("lists/memberships.json", UriKind.Relative),
419 new Dictionary<string, string> {
420 { "screen_name", "twitterapi" },
423 { "filter_to_owned_lists", "true" },
425 "/lists/memberships")
427 .ReturnsAsync(new TwitterLists());
429 twitterApi.apiConnection = mock.Object;
431 await twitterApi.ListsMemberships("twitterapi", cursor: -1L, count: 100, filterToOwnedLists: true)
432 .ConfigureAwait(false);
439 public async Task ListsCreate_Test()
441 using (var twitterApi = new TwitterApi())
443 var mock = new Mock<IApiConnection>();
445 x.PostLazyAsync<TwitterList>(
446 new Uri("lists/create.json", UriKind.Relative),
447 new Dictionary<string, string> {
448 { "name", "hogehoge" },
449 { "description", "aaaa" },
450 { "mode", "private" },
453 .ReturnsAsync(LazyJson.Create(new TwitterList()));
455 twitterApi.apiConnection = mock.Object;
457 await twitterApi.ListsCreate("hogehoge", description: "aaaa", @private: true)
459 .ConfigureAwait(false);
466 public async Task ListsUpdate_Test()
468 using (var twitterApi = new TwitterApi())
470 var mock = new Mock<IApiConnection>();
472 x.PostLazyAsync<TwitterList>(
473 new Uri("lists/update.json", UriKind.Relative),
474 new Dictionary<string, string> {
475 { "list_id", "12345" },
476 { "name", "hogehoge" },
477 { "description", "aaaa" },
478 { "mode", "private" },
481 .ReturnsAsync(LazyJson.Create(new TwitterList()));
483 twitterApi.apiConnection = mock.Object;
485 await twitterApi.ListsUpdate(12345L, name: "hogehoge", description: "aaaa", @private: true)
487 .ConfigureAwait(false);
494 public async Task ListsDestroy_Test()
496 using (var twitterApi = new TwitterApi())
498 var mock = new Mock<IApiConnection>();
500 x.PostLazyAsync<TwitterList>(
501 new Uri("lists/destroy.json", UriKind.Relative),
502 new Dictionary<string, string> {
503 { "list_id", "12345" },
506 .ReturnsAsync(LazyJson.Create(new TwitterList()));
508 twitterApi.apiConnection = mock.Object;
510 await twitterApi.ListsDestroy(12345L)
512 .ConfigureAwait(false);
519 public async Task ListsStatuses_Test()
521 using (var twitterApi = new TwitterApi())
523 var mock = new Mock<IApiConnection>();
525 x.GetAsync<TwitterStatus[]>(
526 new Uri("lists/statuses.json", UriKind.Relative),
527 new Dictionary<string, string> {
528 { "list_id", "12345" },
529 { "include_entities", "true" },
530 { "include_ext_alt_text", "true" },
531 { "tweet_mode", "extended" },
534 { "since_id", "100" },
535 { "include_rts", "true" },
539 .ReturnsAsync(new TwitterStatus[0]);
541 twitterApi.apiConnection = mock.Object;
543 await twitterApi.ListsStatuses(12345L, count: 200, maxId: 900L, sinceId: 100L, includeRTs: true)
544 .ConfigureAwait(false);
551 public async Task ListsMembers_Test()
553 using (var twitterApi = new TwitterApi())
555 var mock = new Mock<IApiConnection>();
557 x.GetAsync<TwitterUsers>(
558 new Uri("lists/members.json", UriKind.Relative),
559 new Dictionary<string, string> {
560 { "list_id", "12345" },
561 { "include_entities", "true" },
562 { "include_ext_alt_text", "true" },
563 { "tweet_mode", "extended" },
568 .ReturnsAsync(new TwitterUsers());
570 twitterApi.apiConnection = mock.Object;
572 await twitterApi.ListsMembers(12345L, cursor: -1)
573 .ConfigureAwait(false);
580 public async Task ListsMembersShow_Test()
582 using (var twitterApi = new TwitterApi())
584 var mock = new Mock<IApiConnection>();
586 x.GetAsync<TwitterUser>(
587 new Uri("lists/members/show.json", UriKind.Relative),
588 new Dictionary<string, string> {
589 { "list_id", "12345" },
590 { "screen_name", "twitterapi" },
591 { "include_entities", "true" },
592 { "include_ext_alt_text", "true" },
593 { "tweet_mode", "extended" },
595 "/lists/members/show")
597 .ReturnsAsync(new TwitterUser());
599 twitterApi.apiConnection = mock.Object;
601 await twitterApi.ListsMembersShow(12345L, "twitterapi")
602 .ConfigureAwait(false);
609 public async Task ListsMembersCreate_Test()
611 using (var twitterApi = new TwitterApi())
613 var mock = new Mock<IApiConnection>();
615 x.PostLazyAsync<TwitterUser>(
616 new Uri("lists/members/create.json", UriKind.Relative),
617 new Dictionary<string, string> {
618 { "list_id", "12345" },
619 { "screen_name", "twitterapi" },
620 { "include_entities", "true" },
621 { "include_ext_alt_text", "true" },
622 { "tweet_mode", "extended" },
625 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
627 twitterApi.apiConnection = mock.Object;
629 await twitterApi.ListsMembersCreate(12345L, "twitterapi")
631 .ConfigureAwait(false);
638 public async Task ListsMembersDestroy_Test()
640 using (var twitterApi = new TwitterApi())
642 var mock = new Mock<IApiConnection>();
644 x.PostLazyAsync<TwitterUser>(
645 new Uri("lists/members/destroy.json", UriKind.Relative),
646 new Dictionary<string, string> {
647 { "list_id", "12345" },
648 { "screen_name", "twitterapi" },
649 { "include_entities", "true" },
650 { "include_ext_alt_text", "true" },
651 { "tweet_mode", "extended" },
654 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
656 twitterApi.apiConnection = mock.Object;
658 await twitterApi.ListsMembersDestroy(12345L, "twitterapi")
660 .ConfigureAwait(false);
667 public async Task DirectMessagesRecv_Test()
669 using (var twitterApi = new TwitterApi())
671 var mock = new Mock<IApiConnection>();
673 x.GetAsync<TwitterDirectMessage[]>(
674 new Uri("direct_messages.json", UriKind.Relative),
675 new Dictionary<string, string> {
676 { "full_text", "true" },
677 { "include_entities", "true" },
678 { "include_ext_alt_text", "true" },
681 { "since_id", "100" },
685 .ReturnsAsync(new TwitterDirectMessage[0]);
687 twitterApi.apiConnection = mock.Object;
689 await twitterApi.DirectMessagesRecv(count: 200, maxId: 900L, sinceId: 100L)
690 .ConfigureAwait(false);
697 public async Task DirectMessagesSent_Test()
699 using (var twitterApi = new TwitterApi())
701 var mock = new Mock<IApiConnection>();
703 x.GetAsync<TwitterDirectMessage[]>(
704 new Uri("direct_messages/sent.json", UriKind.Relative),
705 new Dictionary<string, string> {
706 { "full_text", "true" },
707 { "include_entities", "true" },
708 { "include_ext_alt_text", "true" },
711 { "since_id", "100" },
713 "/direct_messages/sent")
715 .ReturnsAsync(new TwitterDirectMessage[0]);
717 twitterApi.apiConnection = mock.Object;
719 await twitterApi.DirectMessagesSent(count: 200, maxId: 900L, sinceId: 100L)
720 .ConfigureAwait(false);
727 public async Task DirectMessagesNew_Test()
729 using (var twitterApi = new TwitterApi())
731 var mock = new Mock<IApiConnection>();
733 x.PostLazyAsync<TwitterDirectMessage>(
734 new Uri("direct_messages/new.json", UriKind.Relative),
735 new Dictionary<string, string> {
736 { "text", "hogehoge" },
737 { "screen_name", "opentween" },
740 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage()));
742 twitterApi.apiConnection = mock.Object;
744 await twitterApi.DirectMessagesNew("hogehoge", "opentween")
746 .ConfigureAwait(false);
753 public async Task DirectMessagesDestroy_Test()
755 using (var twitterApi = new TwitterApi())
757 var mock = new Mock<IApiConnection>();
759 x.PostLazyAsync<TwitterDirectMessage>(
760 new Uri("direct_messages/destroy.json", UriKind.Relative),
761 new Dictionary<string, string> { { "id", "100" } })
763 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage { Id = 100L }));
765 twitterApi.apiConnection = mock.Object;
767 await twitterApi.DirectMessagesDestroy(statusId: 100L)
769 .ConfigureAwait(false);
776 public async Task UsersShow_Test()
778 using (var twitterApi = new TwitterApi())
780 var mock = new Mock<IApiConnection>();
782 x.GetAsync<TwitterUser>(
783 new Uri("users/show.json", UriKind.Relative),
784 new Dictionary<string, string> {
785 { "screen_name", "twitterapi" },
786 { "include_entities", "true" },
787 { "include_ext_alt_text", "true" },
788 { "tweet_mode", "extended" },
792 .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
794 twitterApi.apiConnection = mock.Object;
796 await twitterApi.UsersShow(screenName: "twitterapi")
797 .ConfigureAwait(false);
804 public async Task UsersReportSpam_Test()
806 using (var twitterApi = new TwitterApi())
808 var mock = new Mock<IApiConnection>();
810 x.PostLazyAsync<TwitterUser>(
811 new Uri("users/report_spam.json", UriKind.Relative),
812 new Dictionary<string, string> {
813 { "screen_name", "twitterapi" },
814 { "tweet_mode", "extended" },
817 .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
819 twitterApi.apiConnection = mock.Object;
821 await twitterApi.UsersReportSpam(screenName: "twitterapi")
823 .ConfigureAwait(false);
830 public async Task FavoritesList_Test()
832 using (var twitterApi = new TwitterApi())
834 var mock = new Mock<IApiConnection>();
836 x.GetAsync<TwitterStatus[]>(
837 new Uri("favorites/list.json", UriKind.Relative),
838 new Dictionary<string, string> {
839 { "include_entities", "true" },
840 { "include_ext_alt_text", "true" },
841 { "tweet_mode", "extended" },
844 { "since_id", "100" },
848 .ReturnsAsync(new TwitterStatus[0]);
850 twitterApi.apiConnection = mock.Object;
852 await twitterApi.FavoritesList(200, maxId: 900L, sinceId: 100L)
853 .ConfigureAwait(false);
860 public async Task FavoritesCreate_Test()
862 using (var twitterApi = new TwitterApi())
864 var mock = new Mock<IApiConnection>();
866 x.PostLazyAsync<TwitterStatus>(
867 new Uri("favorites/create.json", UriKind.Relative),
868 new Dictionary<string, string> {
870 { "tweet_mode", "extended" },
873 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
875 twitterApi.apiConnection = mock.Object;
877 await twitterApi.FavoritesCreate(statusId: 100L)
879 .ConfigureAwait(false);
886 public async Task FavoritesDestroy_Test()
888 using (var twitterApi = new TwitterApi())
890 var mock = new Mock<IApiConnection>();
892 x.PostLazyAsync<TwitterStatus>(
893 new Uri("favorites/destroy.json", UriKind.Relative),
894 new Dictionary<string, string> {
896 { "tweet_mode", "extended" },
899 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
901 twitterApi.apiConnection = mock.Object;
903 await twitterApi.FavoritesDestroy(statusId: 100L)
905 .ConfigureAwait(false);
912 public async Task FriendshipsShow_Test()
914 using (var twitterApi = new TwitterApi())
916 var mock = new Mock<IApiConnection>();
918 x.GetAsync<TwitterFriendship>(
919 new Uri("friendships/show.json", UriKind.Relative),
920 new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } },
923 .ReturnsAsync(new TwitterFriendship());
925 twitterApi.apiConnection = mock.Object;
927 await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi")
928 .ConfigureAwait(false);
935 public async Task FriendshipsCreate_Test()
937 using (var twitterApi = new TwitterApi())
939 var mock = new Mock<IApiConnection>();
941 x.PostLazyAsync<TwitterFriendship>(
942 new Uri("friendships/create.json", UriKind.Relative),
943 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
945 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
947 twitterApi.apiConnection = mock.Object;
949 await twitterApi.FriendshipsCreate(screenName: "twitterapi")
951 .ConfigureAwait(false);
958 public async Task FriendshipsDestroy_Test()
960 using (var twitterApi = new TwitterApi())
962 var mock = new Mock<IApiConnection>();
964 x.PostLazyAsync<TwitterFriendship>(
965 new Uri("friendships/destroy.json", UriKind.Relative),
966 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
968 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
970 twitterApi.apiConnection = mock.Object;
972 await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
974 .ConfigureAwait(false);
981 public async Task NoRetweetIds_Test()
983 using (var twitterApi = new TwitterApi())
985 var mock = new Mock<IApiConnection>();
988 new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
990 "/friendships/no_retweets/ids")
992 .ReturnsAsync(new long[0]);
994 twitterApi.apiConnection = mock.Object;
996 await twitterApi.NoRetweetIds()
997 .ConfigureAwait(false);
1004 public async Task FollowersIds_Test()
1006 using (var twitterApi = new TwitterApi())
1008 var mock = new Mock<IApiConnection>();
1010 x.GetAsync<TwitterIds>(
1011 new Uri("followers/ids.json", UriKind.Relative),
1012 new Dictionary<string, string> { { "cursor", "-1" } },
1015 .ReturnsAsync(new TwitterIds());
1017 twitterApi.apiConnection = mock.Object;
1019 await twitterApi.FollowersIds(cursor: -1L)
1020 .ConfigureAwait(false);
1027 public async Task MutesUsersIds_Test()
1029 using (var twitterApi = new TwitterApi())
1031 var mock = new Mock<IApiConnection>();
1033 x.GetAsync<TwitterIds>(
1034 new Uri("mutes/users/ids.json", UriKind.Relative),
1035 new Dictionary<string, string> { { "cursor", "-1" } },
1038 .ReturnsAsync(new TwitterIds());
1040 twitterApi.apiConnection = mock.Object;
1042 await twitterApi.MutesUsersIds(cursor: -1L)
1043 .ConfigureAwait(false);
1050 public async Task BlocksIds_Test()
1052 using (var twitterApi = new TwitterApi())
1054 var mock = new Mock<IApiConnection>();
1056 x.GetAsync<TwitterIds>(
1057 new Uri("blocks/ids.json", UriKind.Relative),
1058 new Dictionary<string, string> { { "cursor", "-1" } },
1061 .ReturnsAsync(new TwitterIds());
1063 twitterApi.apiConnection = mock.Object;
1065 await twitterApi.BlocksIds(cursor: -1L)
1066 .ConfigureAwait(false);
1073 public async Task BlocksCreate_Test()
1075 using (var twitterApi = new TwitterApi())
1077 var mock = new Mock<IApiConnection>();
1079 x.PostLazyAsync<TwitterUser>(
1080 new Uri("blocks/create.json", UriKind.Relative),
1081 new Dictionary<string, string> {
1082 { "screen_name", "twitterapi" },
1083 { "tweet_mode", "extended" },
1086 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1088 twitterApi.apiConnection = mock.Object;
1090 await twitterApi.BlocksCreate(screenName: "twitterapi")
1092 .ConfigureAwait(false);
1099 public async Task BlocksDestroy_Test()
1101 using (var twitterApi = new TwitterApi())
1103 var mock = new Mock<IApiConnection>();
1105 x.PostLazyAsync<TwitterUser>(
1106 new Uri("blocks/destroy.json", UriKind.Relative),
1107 new Dictionary<string, string> {
1108 { "screen_name", "twitterapi" },
1109 { "tweet_mode", "extended" },
1112 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1114 twitterApi.apiConnection = mock.Object;
1116 await twitterApi.BlocksDestroy(screenName: "twitterapi")
1118 .ConfigureAwait(false);
1125 public async Task AccountVerifyCredentials_Test()
1127 using (var twitterApi = new TwitterApi())
1129 var mock = new Mock<IApiConnection>();
1131 x.GetAsync<TwitterUser>(
1132 new Uri("account/verify_credentials.json", UriKind.Relative),
1133 new Dictionary<string, string> {
1134 { "include_entities", "true" },
1135 { "include_ext_alt_text", "true" },
1136 { "tweet_mode", "extended" },
1138 "/account/verify_credentials")
1140 .ReturnsAsync(new TwitterUser {
1142 ScreenName = "opentween",
1145 twitterApi.apiConnection = mock.Object;
1147 await twitterApi.AccountVerifyCredentials()
1148 .ConfigureAwait(false);
1150 Assert.Equal(100L, twitterApi.CurrentUserId);
1151 Assert.Equal("opentween", twitterApi.CurrentScreenName);
1158 public async Task AccountUpdateProfile_Test()
1160 using (var twitterApi = new TwitterApi())
1162 var mock = new Mock<IApiConnection>();
1164 x.PostLazyAsync<TwitterUser>(
1165 new Uri("account/update_profile.json", UriKind.Relative),
1166 new Dictionary<string, string> {
1167 { "include_entities", "true" },
1168 { "include_ext_alt_text", "true" },
1169 { "tweet_mode", "extended" },
1171 { "url", "http://example.com/" },
1172 { "location", "Location" },
1173 { "description", "<script>alert(1)</script>" },
1176 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1178 twitterApi.apiConnection = mock.Object;
1180 await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
1182 .ConfigureAwait(false);
1189 public async Task AccountUpdateProfileImage_Test()
1191 using (var twitterApi = new TwitterApi())
1192 using (var image = TestUtils.CreateDummyImage())
1193 using (var media = new MemoryImageMediaItem(image))
1195 var mock = new Mock<IApiConnection>();
1197 x.PostLazyAsync<TwitterUser>(
1198 new Uri("account/update_profile_image.json", UriKind.Relative),
1199 new Dictionary<string, string> {
1200 { "include_entities", "true" },
1201 { "include_ext_alt_text", "true" },
1202 { "tweet_mode", "extended" },
1204 new Dictionary<string, IMediaItem> { { "image", media } })
1206 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1208 twitterApi.apiConnection = mock.Object;
1210 await twitterApi.AccountUpdateProfileImage(media)
1212 .ConfigureAwait(false);
1219 public async Task ApplicationRateLimitStatus_Test()
1221 using (var twitterApi = new TwitterApi())
1223 var mock = new Mock<IApiConnection>();
1225 x.GetAsync<TwitterRateLimits>(
1226 new Uri("application/rate_limit_status.json", UriKind.Relative),
1228 "/application/rate_limit_status")
1230 .ReturnsAsync(new TwitterRateLimits());
1232 twitterApi.apiConnection = mock.Object;
1234 await twitterApi.ApplicationRateLimitStatus()
1235 .ConfigureAwait(false);
1242 public async Task Configuration_Test()
1244 using (var twitterApi = new TwitterApi())
1246 var mock = new Mock<IApiConnection>();
1248 x.GetAsync<TwitterConfiguration>(
1249 new Uri("help/configuration.json", UriKind.Relative),
1251 "/help/configuration")
1253 .ReturnsAsync(new TwitterConfiguration());
1255 twitterApi.apiConnection = mock.Object;
1257 await twitterApi.Configuration()
1258 .ConfigureAwait(false);
1265 public async Task MediaUpload_Test()
1267 using (var twitterApi = new TwitterApi())
1268 using (var image = TestUtils.CreateDummyImage())
1269 using (var media = new MemoryImageMediaItem(image))
1271 var mock = new Mock<IApiConnection>();
1273 x.PostLazyAsync<TwitterUploadMediaResult>(
1274 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1276 new Dictionary<string, IMediaItem> { { "media", media } })
1278 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
1280 twitterApi.apiConnection = mock.Object;
1282 await twitterApi.MediaUpload(media)
1284 .ConfigureAwait(false);
1291 public async Task MediaMetadataCreate_Test()
1293 using (var twitterApi = new TwitterApi())
1295 var mock = new Mock<IApiConnection>();
1298 new Uri("https://upload.twitter.com/1.1/media/metadata/create.json", UriKind.Absolute),
1299 "{\"media_id\": \"12345\", \"alt_text\": {\"text\": \"hogehoge\"}}")
1301 .Returns(Task.FromResult(0));
1303 twitterApi.apiConnection = mock.Object;
1305 await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge")
1306 .ConfigureAwait(false);
1313 public async Task UserStreams_Test()
1315 using (var twitterApi = new TwitterApi())
1317 var mock = new Mock<IApiConnection>();
1319 x.GetStreamingStreamAsync(
1320 new Uri("https://userstream.twitter.com/1.1/user.json", UriKind.Absolute),
1321 new Dictionary<string, string> {
1322 { "replies", "all" },
1323 { "track", "OpenTween" },
1326 .ReturnsAsync(new MemoryStream());
1328 twitterApi.apiConnection = mock.Object;
1330 var stream = await twitterApi.UserStreams(replies: "all", track: "OpenTween")
1331 .ConfigureAwait(false);
1340 [InlineData("", "")]
1341 [InlineData("123ABCabc", "123ABCabc")]
1342 [InlineData(@"\", @"\\")]
1343 [InlineData("\"", "\\\"")]
1344 [InlineData("\n", @"\u000A")]
1345 [InlineData("\U0001D11E", @"\uD834\uDD1E")]
1346 public void EscapeJsonString_Test(string targetText, string expectedText)
1348 Assert.Equal(expectedText, TwitterApi.EscapeJsonString(targetText));