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;
25 using System.Net.Http;
26 using System.Reflection;
27 using System.Runtime.InteropServices;
29 using System.Threading.Tasks;
31 using OpenTween.Api.DataModel;
32 using OpenTween.Connection;
35 namespace OpenTween.Api
37 public class TwitterApiTest
39 public TwitterApiTest()
44 public 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())
57 Assert.Null(twitterApi.apiConnection);
59 twitterApi.Initialize("*** AccessToken ***", "*** AccessSecret ***", userId: 100L, screenName: "hogehoge");
61 Assert.IsType<TwitterApiConnection>(twitterApi.apiConnection);
63 var apiConnection = (TwitterApiConnection)twitterApi.apiConnection;
64 Assert.Equal("*** AccessToken ***", apiConnection.AccessToken);
65 Assert.Equal("*** AccessSecret ***", apiConnection.AccessSecret);
67 Assert.Equal(100L, twitterApi.CurrentUserId);
68 Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
70 // 複数回 Initialize を実行した場合は新たに TwitterApiConnection が生成される
71 twitterApi.Initialize("*** AccessToken2 ***", "*** AccessSecret2 ***", userId: 200L, screenName: "foobar");
73 var oldApiConnection = apiConnection;
74 Assert.True(oldApiConnection.IsDisposed);
76 Assert.IsType<TwitterApiConnection>(twitterApi.apiConnection);
78 apiConnection = (TwitterApiConnection)twitterApi.apiConnection;
79 Assert.Equal("*** AccessToken2 ***", apiConnection.AccessToken);
80 Assert.Equal("*** AccessSecret2 ***", apiConnection.AccessSecret);
82 Assert.Equal(200L, twitterApi.CurrentUserId);
83 Assert.Equal("foobar", twitterApi.CurrentScreenName);
88 public async Task StatusesHomeTimeline_Test()
90 using (var twitterApi = new TwitterApi())
92 var mock = new Mock<IApiConnection>();
94 x.GetAsync<TwitterStatus[]>(
95 new Uri("statuses/home_timeline.json", UriKind.Relative),
96 new Dictionary<string, string> {
97 { "include_entities", "true" },
98 { "include_ext_alt_text", "true" },
101 { "since_id", "100" },
103 "/statuses/home_timeline")
105 .ReturnsAsync(new TwitterStatus[0]);
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" },
130 { "since_id", "100" },
132 "/statuses/mentions_timeline")
134 .ReturnsAsync(new TwitterStatus[0]);
136 twitterApi.apiConnection = mock.Object;
138 await twitterApi.StatusesMentionsTimeline(200, maxId: 900L, sinceId: 100L)
139 .ConfigureAwait(false);
146 public async Task StatusesUserTimeline_Test()
148 using (var twitterApi = new TwitterApi())
150 var mock = new Mock<IApiConnection>();
152 x.GetAsync<TwitterStatus[]>(
153 new Uri("statuses/user_timeline.json", UriKind.Relative),
154 new Dictionary<string, string> {
155 { "screen_name", "twitterapi" },
156 { "include_rts", "true" },
157 { "include_entities", "true" },
158 { "include_ext_alt_text", "true" },
161 { "since_id", "100" },
163 "/statuses/user_timeline")
165 .ReturnsAsync(new TwitterStatus[0]);
167 twitterApi.apiConnection = mock.Object;
169 await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: 900L, sinceId: 100L)
170 .ConfigureAwait(false);
177 public async Task StatusesShow_Test()
179 using (var twitterApi = new TwitterApi())
181 var mock = new Mock<IApiConnection>();
183 x.GetAsync<TwitterStatus>(
184 new Uri("statuses/show.json", UriKind.Relative),
185 new Dictionary<string, string> {
187 { "include_entities", "true" },
188 { "include_ext_alt_text", "true" },
190 "/statuses/show/:id")
192 .ReturnsAsync(new TwitterStatus { Id = 100L });
194 twitterApi.apiConnection = mock.Object;
196 await twitterApi.StatusesShow(statusId: 100L)
197 .ConfigureAwait(false);
204 public async Task StatusesUpdate_Test()
206 using (var twitterApi = new TwitterApi())
208 var mock = new Mock<IApiConnection>();
210 x.PostLazyAsync<TwitterStatus>(
211 new Uri("statuses/update.json", UriKind.Relative),
212 new Dictionary<string, string> {
213 { "status", "hogehoge" },
214 { "include_entities", "true" },
215 { "include_ext_alt_text", "true" },
216 { "in_reply_to_status_id", "100" },
217 { "media_ids", "10,20" },
220 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
222 twitterApi.apiConnection = mock.Object;
224 await twitterApi.StatusesUpdate("hogehoge", replyToId: 100L, mediaIds: new[] { 10L, 20L })
226 .ConfigureAwait(false);
233 public async Task StatusesDestroy_Test()
235 using (var twitterApi = new TwitterApi())
237 var mock = new Mock<IApiConnection>();
239 x.PostLazyAsync<TwitterStatus>(
240 new Uri("statuses/destroy.json", UriKind.Relative),
241 new Dictionary<string, string> { { "id", "100" } })
243 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
245 twitterApi.apiConnection = mock.Object;
247 await twitterApi.StatusesDestroy(statusId: 100L)
249 .ConfigureAwait(false);
256 public async Task StatusesRetweet_Test()
258 using (var twitterApi = new TwitterApi())
260 var mock = new Mock<IApiConnection>();
262 x.PostLazyAsync<TwitterStatus>(
263 new Uri("statuses/retweet.json", UriKind.Relative),
264 new Dictionary<string, string> {
266 { "include_entities", "true" },
267 { "include_ext_alt_text", "true" },
270 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
272 twitterApi.apiConnection = mock.Object;
274 await twitterApi.StatusesRetweet(100L)
276 .ConfigureAwait(false);
283 public async Task ListsStatuses_Test()
285 using (var twitterApi = new TwitterApi())
287 var mock = new Mock<IApiConnection>();
289 x.GetAsync<TwitterStatus[]>(
290 new Uri("lists/statuses.json", UriKind.Relative),
291 new Dictionary<string, string> {
292 { "list_id", "12345" },
293 { "include_entities", "true" },
294 { "include_ext_alt_text", "true" },
297 { "since_id", "100" },
298 { "include_rts", "true" },
302 .ReturnsAsync(new TwitterStatus[0]);
304 twitterApi.apiConnection = mock.Object;
306 await twitterApi.ListsStatuses(12345L, count: 200, maxId: 900L, sinceId: 100L, includeRTs: true)
307 .ConfigureAwait(false);
314 public async Task DirectMessagesRecv_Test()
316 using (var twitterApi = new TwitterApi())
318 var mock = new Mock<IApiConnection>();
320 x.GetAsync<TwitterDirectMessage[]>(
321 new Uri("direct_messages.json", UriKind.Relative),
322 new Dictionary<string, string> {
323 { "full_text", "true" },
324 { "include_entities", "true" },
325 { "include_ext_alt_text", "true" },
328 { "since_id", "100" },
332 .ReturnsAsync(new TwitterDirectMessage[0]);
334 twitterApi.apiConnection = mock.Object;
336 await twitterApi.DirectMessagesRecv(count: 200, maxId: 900L, sinceId: 100L)
337 .ConfigureAwait(false);
344 public async Task DirectMessagesSent_Test()
346 using (var twitterApi = new TwitterApi())
348 var mock = new Mock<IApiConnection>();
350 x.GetAsync<TwitterDirectMessage[]>(
351 new Uri("direct_messages/sent.json", UriKind.Relative),
352 new Dictionary<string, string> {
353 { "full_text", "true" },
354 { "include_entities", "true" },
355 { "include_ext_alt_text", "true" },
358 { "since_id", "100" },
360 "/direct_messages/sent")
362 .ReturnsAsync(new TwitterDirectMessage[0]);
364 twitterApi.apiConnection = mock.Object;
366 await twitterApi.DirectMessagesSent(count: 200, maxId: 900L, sinceId: 100L)
367 .ConfigureAwait(false);
374 public async Task DirectMessagesNew_Test()
376 using (var twitterApi = new TwitterApi())
378 var mock = new Mock<IApiConnection>();
380 x.PostLazyAsync<TwitterDirectMessage>(
381 new Uri("direct_messages/new.json", UriKind.Relative),
382 new Dictionary<string, string> {
383 { "text", "hogehoge" },
384 { "screen_name", "opentween" },
387 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage()));
389 twitterApi.apiConnection = mock.Object;
391 await twitterApi.DirectMessagesNew("hogehoge", "opentween")
393 .ConfigureAwait(false);
400 public async Task DirectMessagesDestroy_Test()
402 using (var twitterApi = new TwitterApi())
404 var mock = new Mock<IApiConnection>();
406 x.PostLazyAsync<TwitterDirectMessage>(
407 new Uri("direct_messages/destroy.json", UriKind.Relative),
408 new Dictionary<string, string> { { "id", "100" } })
410 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage { Id = 100L }));
412 twitterApi.apiConnection = mock.Object;
414 await twitterApi.DirectMessagesDestroy(statusId: 100L)
416 .ConfigureAwait(false);
423 public async Task UsersShow_Test()
425 using (var twitterApi = new TwitterApi())
427 var mock = new Mock<IApiConnection>();
429 x.GetAsync<TwitterUser>(
430 new Uri("users/show.json", UriKind.Relative),
431 new Dictionary<string, string> {
432 { "screen_name", "twitterapi" },
433 { "include_entities", "true" },
434 { "include_ext_alt_text", "true" },
438 .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
440 twitterApi.apiConnection = mock.Object;
442 await twitterApi.UsersShow(screenName: "twitterapi")
443 .ConfigureAwait(false);
450 public async Task UsersReportSpam_Test()
452 using (var twitterApi = new TwitterApi())
454 var mock = new Mock<IApiConnection>();
456 x.PostLazyAsync<TwitterUser>(
457 new Uri("users/report_spam.json", UriKind.Relative),
458 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
460 .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
462 twitterApi.apiConnection = mock.Object;
464 await twitterApi.UsersReportSpam(screenName: "twitterapi")
466 .ConfigureAwait(false);
473 public async Task FavoritesCreate_Test()
475 using (var twitterApi = new TwitterApi())
477 var mock = new Mock<IApiConnection>();
479 x.PostLazyAsync<TwitterStatus>(
480 new Uri("favorites/create.json", UriKind.Relative),
481 new Dictionary<string, string> { { "id", "100" } })
483 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
485 twitterApi.apiConnection = mock.Object;
487 await twitterApi.FavoritesCreate(statusId: 100L)
489 .ConfigureAwait(false);
496 public async Task FavoritesDestroy_Test()
498 using (var twitterApi = new TwitterApi())
500 var mock = new Mock<IApiConnection>();
502 x.PostLazyAsync<TwitterStatus>(
503 new Uri("favorites/destroy.json", UriKind.Relative),
504 new Dictionary<string, string> { { "id", "100" } })
506 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
508 twitterApi.apiConnection = mock.Object;
510 await twitterApi.FavoritesDestroy(statusId: 100L)
512 .ConfigureAwait(false);
519 public async Task FriendshipsShow_Test()
521 using (var twitterApi = new TwitterApi())
523 var mock = new Mock<IApiConnection>();
525 x.GetAsync<TwitterFriendship>(
526 new Uri("friendships/show.json", UriKind.Relative),
527 new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } },
530 .ReturnsAsync(new TwitterFriendship());
532 twitterApi.apiConnection = mock.Object;
534 await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi")
535 .ConfigureAwait(false);
542 public async Task FriendshipsCreate_Test()
544 using (var twitterApi = new TwitterApi())
546 var mock = new Mock<IApiConnection>();
548 x.PostLazyAsync<TwitterFriendship>(
549 new Uri("friendships/create.json", UriKind.Relative),
550 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
552 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
554 twitterApi.apiConnection = mock.Object;
556 await twitterApi.FriendshipsCreate(screenName: "twitterapi")
558 .ConfigureAwait(false);
565 public async Task FriendshipsDestroy_Test()
567 using (var twitterApi = new TwitterApi())
569 var mock = new Mock<IApiConnection>();
571 x.PostLazyAsync<TwitterFriendship>(
572 new Uri("friendships/destroy.json", UriKind.Relative),
573 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
575 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
577 twitterApi.apiConnection = mock.Object;
579 await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
581 .ConfigureAwait(false);
588 public async Task NoRetweetIds_Test()
590 using (var twitterApi = new TwitterApi())
592 var mock = new Mock<IApiConnection>();
595 new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
597 "/friendships/no_retweets/ids")
599 .ReturnsAsync(new long[0]);
601 twitterApi.apiConnection = mock.Object;
603 await twitterApi.NoRetweetIds()
604 .ConfigureAwait(false);
611 public async Task FollowersIds_Test()
613 using (var twitterApi = new TwitterApi())
615 var mock = new Mock<IApiConnection>();
617 x.GetAsync<TwitterIds>(
618 new Uri("followers/ids.json", UriKind.Relative),
619 new Dictionary<string, string> { { "cursor", "-1" } },
622 .ReturnsAsync(new TwitterIds());
624 twitterApi.apiConnection = mock.Object;
626 await twitterApi.FollowersIds(cursor: -1L)
627 .ConfigureAwait(false);
634 public async Task MutesUsersIds_Test()
636 using (var twitterApi = new TwitterApi())
638 var mock = new Mock<IApiConnection>();
640 x.GetAsync<TwitterIds>(
641 new Uri("mutes/users/ids.json", UriKind.Relative),
642 new Dictionary<string, string> { { "cursor", "-1" } },
645 .ReturnsAsync(new TwitterIds());
647 twitterApi.apiConnection = mock.Object;
649 await twitterApi.MutesUsersIds(cursor: -1L)
650 .ConfigureAwait(false);
657 public async Task BlocksIds_Test()
659 using (var twitterApi = new TwitterApi())
661 var mock = new Mock<IApiConnection>();
663 x.GetAsync<TwitterIds>(
664 new Uri("blocks/ids.json", UriKind.Relative),
665 new Dictionary<string, string> { { "cursor", "-1" } },
668 .ReturnsAsync(new TwitterIds());
670 twitterApi.apiConnection = mock.Object;
672 await twitterApi.BlocksIds(cursor: -1L)
673 .ConfigureAwait(false);
680 public async Task BlocksCreate_Test()
682 using (var twitterApi = new TwitterApi())
684 var mock = new Mock<IApiConnection>();
686 x.PostLazyAsync<TwitterUser>(
687 new Uri("blocks/create.json", UriKind.Relative),
688 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
690 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
692 twitterApi.apiConnection = mock.Object;
694 await twitterApi.BlocksCreate(screenName: "twitterapi")
696 .ConfigureAwait(false);
703 public async Task BlocksDestroy_Test()
705 using (var twitterApi = new TwitterApi())
707 var mock = new Mock<IApiConnection>();
709 x.PostLazyAsync<TwitterUser>(
710 new Uri("blocks/destroy.json", UriKind.Relative),
711 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
713 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
715 twitterApi.apiConnection = mock.Object;
717 await twitterApi.BlocksDestroy(screenName: "twitterapi")
719 .ConfigureAwait(false);
726 public async Task AccountUpdateProfile_Test()
728 using (var twitterApi = new TwitterApi())
730 var mock = new Mock<IApiConnection>();
732 x.PostLazyAsync<TwitterUser>(
733 new Uri("account/update_profile.json", UriKind.Relative),
734 new Dictionary<string, string> {
735 { "include_entities", "true" },
736 { "include_ext_alt_text", "true" },
738 { "url", "http://example.com/" },
739 { "location", "Location" },
740 { "description", "<script>alert(1)</script>" },
743 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
745 twitterApi.apiConnection = mock.Object;
747 await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
749 .ConfigureAwait(false);
756 public async Task AccountUpdateProfileImage_Test()
758 using (var twitterApi = new TwitterApi())
759 using (var image = TestUtils.CreateDummyImage())
760 using (var media = new MemoryImageMediaItem(image))
762 var mock = new Mock<IApiConnection>();
764 x.PostLazyAsync<TwitterUser>(
765 new Uri("account/update_profile_image.json", UriKind.Relative),
766 new Dictionary<string, string> {
767 { "include_entities", "true" },
768 { "include_ext_alt_text", "true" },
770 new Dictionary<string, IMediaItem> { { "image", media } })
772 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
774 twitterApi.apiConnection = mock.Object;
776 await twitterApi.AccountUpdateProfileImage(media)
778 .ConfigureAwait(false);
785 public async Task Configuration_Test()
787 using (var twitterApi = new TwitterApi())
789 var mock = new Mock<IApiConnection>();
791 x.GetAsync<TwitterConfiguration>(
792 new Uri("help/configuration.json", UriKind.Relative),
794 "/help/configuration")
796 .ReturnsAsync(new TwitterConfiguration());
798 twitterApi.apiConnection = mock.Object;
800 await twitterApi.Configuration()
801 .ConfigureAwait(false);
808 public async Task MediaUpload_Test()
810 using (var twitterApi = new TwitterApi())
811 using (var image = TestUtils.CreateDummyImage())
812 using (var media = new MemoryImageMediaItem(image))
814 var mock = new Mock<IApiConnection>();
816 x.PostLazyAsync<TwitterUploadMediaResult>(
817 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
819 new Dictionary<string, IMediaItem> { { "media", media } })
821 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
823 twitterApi.apiConnection = mock.Object;
825 await twitterApi.MediaUpload(media)
827 .ConfigureAwait(false);