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 StatusesShow_Test()
148 using (var twitterApi = new TwitterApi())
150 var mock = new Mock<IApiConnection>();
152 x.GetAsync<TwitterStatus>(
153 new Uri("statuses/show.json", UriKind.Relative),
154 new Dictionary<string, string> {
156 { "include_entities", "true" },
157 { "include_ext_alt_text", "true" },
159 "/statuses/show/:id")
161 .ReturnsAsync(new TwitterStatus { Id = 100L });
163 twitterApi.apiConnection = mock.Object;
165 await twitterApi.StatusesShow(statusId: 100L)
166 .ConfigureAwait(false);
173 public async Task StatusesUpdate_Test()
175 using (var twitterApi = new TwitterApi())
177 var mock = new Mock<IApiConnection>();
179 x.PostLazyAsync<TwitterStatus>(
180 new Uri("statuses/update.json", UriKind.Relative),
181 new Dictionary<string, string> {
182 { "status", "hogehoge" },
183 { "include_entities", "true" },
184 { "include_ext_alt_text", "true" },
185 { "in_reply_to_status_id", "100" },
186 { "media_ids", "10,20" },
189 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
191 twitterApi.apiConnection = mock.Object;
193 await twitterApi.StatusesUpdate("hogehoge", replyToId: 100L, mediaIds: new[] { 10L, 20L })
195 .ConfigureAwait(false);
202 public async Task StatusesDestroy_Test()
204 using (var twitterApi = new TwitterApi())
206 var mock = new Mock<IApiConnection>();
208 x.PostLazyAsync<TwitterStatus>(
209 new Uri("statuses/destroy.json", UriKind.Relative),
210 new Dictionary<string, string> { { "id", "100" } })
212 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
214 twitterApi.apiConnection = mock.Object;
216 await twitterApi.StatusesDestroy(statusId: 100L)
218 .ConfigureAwait(false);
225 public async Task StatusesRetweet_Test()
227 using (var twitterApi = new TwitterApi())
229 var mock = new Mock<IApiConnection>();
231 x.PostLazyAsync<TwitterStatus>(
232 new Uri("statuses/retweet.json", UriKind.Relative),
233 new Dictionary<string, string> {
235 { "include_entities", "true" },
236 { "include_ext_alt_text", "true" },
239 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
241 twitterApi.apiConnection = mock.Object;
243 await twitterApi.StatusesRetweet(100L)
245 .ConfigureAwait(false);
252 public async Task DirectMessagesNew_Test()
254 using (var twitterApi = new TwitterApi())
256 var mock = new Mock<IApiConnection>();
258 x.PostLazyAsync<TwitterDirectMessage>(
259 new Uri("direct_messages/new.json", UriKind.Relative),
260 new Dictionary<string, string> {
261 { "text", "hogehoge" },
262 { "screen_name", "opentween" },
265 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage()));
267 twitterApi.apiConnection = mock.Object;
269 await twitterApi.DirectMessagesNew("hogehoge", "opentween")
271 .ConfigureAwait(false);
278 public async Task DirectMessagesDestroy_Test()
280 using (var twitterApi = new TwitterApi())
282 var mock = new Mock<IApiConnection>();
284 x.PostLazyAsync<TwitterDirectMessage>(
285 new Uri("direct_messages/destroy.json", UriKind.Relative),
286 new Dictionary<string, string> { { "id", "100" } })
288 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage { Id = 100L }));
290 twitterApi.apiConnection = mock.Object;
292 await twitterApi.DirectMessagesDestroy(statusId: 100L)
294 .ConfigureAwait(false);
301 public async Task UsersShow_Test()
303 using (var twitterApi = new TwitterApi())
305 var mock = new Mock<IApiConnection>();
307 x.GetAsync<TwitterUser>(
308 new Uri("users/show.json", UriKind.Relative),
309 new Dictionary<string, string> {
310 { "screen_name", "twitterapi" },
311 { "include_entities", "true" },
312 { "include_ext_alt_text", "true" },
316 .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
318 twitterApi.apiConnection = mock.Object;
320 await twitterApi.UsersShow(screenName: "twitterapi")
321 .ConfigureAwait(false);
328 public async Task UsersReportSpam_Test()
330 using (var twitterApi = new TwitterApi())
332 var mock = new Mock<IApiConnection>();
334 x.PostLazyAsync<TwitterUser>(
335 new Uri("users/report_spam.json", UriKind.Relative),
336 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
338 .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
340 twitterApi.apiConnection = mock.Object;
342 await twitterApi.UsersReportSpam(screenName: "twitterapi")
344 .ConfigureAwait(false);
351 public async Task FavoritesCreate_Test()
353 using (var twitterApi = new TwitterApi())
355 var mock = new Mock<IApiConnection>();
357 x.PostLazyAsync<TwitterStatus>(
358 new Uri("favorites/create.json", UriKind.Relative),
359 new Dictionary<string, string> { { "id", "100" } })
361 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
363 twitterApi.apiConnection = mock.Object;
365 await twitterApi.FavoritesCreate(statusId: 100L)
367 .ConfigureAwait(false);
374 public async Task FavoritesDestroy_Test()
376 using (var twitterApi = new TwitterApi())
378 var mock = new Mock<IApiConnection>();
380 x.PostLazyAsync<TwitterStatus>(
381 new Uri("favorites/destroy.json", UriKind.Relative),
382 new Dictionary<string, string> { { "id", "100" } })
384 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
386 twitterApi.apiConnection = mock.Object;
388 await twitterApi.FavoritesDestroy(statusId: 100L)
390 .ConfigureAwait(false);
397 public async Task FriendshipsShow_Test()
399 using (var twitterApi = new TwitterApi())
401 var mock = new Mock<IApiConnection>();
403 x.GetAsync<TwitterFriendship>(
404 new Uri("friendships/show.json", UriKind.Relative),
405 new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } },
408 .ReturnsAsync(new TwitterFriendship());
410 twitterApi.apiConnection = mock.Object;
412 await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi")
413 .ConfigureAwait(false);
420 public async Task FriendshipsCreate_Test()
422 using (var twitterApi = new TwitterApi())
424 var mock = new Mock<IApiConnection>();
426 x.PostLazyAsync<TwitterFriendship>(
427 new Uri("friendships/create.json", UriKind.Relative),
428 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
430 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
432 twitterApi.apiConnection = mock.Object;
434 await twitterApi.FriendshipsCreate(screenName: "twitterapi")
436 .ConfigureAwait(false);
443 public async Task FriendshipsDestroy_Test()
445 using (var twitterApi = new TwitterApi())
447 var mock = new Mock<IApiConnection>();
449 x.PostLazyAsync<TwitterFriendship>(
450 new Uri("friendships/destroy.json", UriKind.Relative),
451 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
453 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
455 twitterApi.apiConnection = mock.Object;
457 await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
459 .ConfigureAwait(false);
466 public async Task NoRetweetIds_Test()
468 using (var twitterApi = new TwitterApi())
470 var mock = new Mock<IApiConnection>();
473 new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
475 "/friendships/no_retweets/ids")
477 .ReturnsAsync(new long[0]);
479 twitterApi.apiConnection = mock.Object;
481 await twitterApi.NoRetweetIds()
482 .ConfigureAwait(false);
489 public async Task FollowersIds_Test()
491 using (var twitterApi = new TwitterApi())
493 var mock = new Mock<IApiConnection>();
495 x.GetAsync<TwitterIds>(
496 new Uri("followers/ids.json", UriKind.Relative),
497 new Dictionary<string, string> { { "cursor", "-1" } },
500 .ReturnsAsync(new TwitterIds());
502 twitterApi.apiConnection = mock.Object;
504 await twitterApi.FollowersIds(cursor: -1L)
505 .ConfigureAwait(false);
512 public async Task MutesUsersIds_Test()
514 using (var twitterApi = new TwitterApi())
516 var mock = new Mock<IApiConnection>();
518 x.GetAsync<TwitterIds>(
519 new Uri("mutes/users/ids.json", UriKind.Relative),
520 new Dictionary<string, string> { { "cursor", "-1" } },
523 .ReturnsAsync(new TwitterIds());
525 twitterApi.apiConnection = mock.Object;
527 await twitterApi.MutesUsersIds(cursor: -1L)
528 .ConfigureAwait(false);
535 public async Task BlocksIds_Test()
537 using (var twitterApi = new TwitterApi())
539 var mock = new Mock<IApiConnection>();
541 x.GetAsync<TwitterIds>(
542 new Uri("blocks/ids.json", UriKind.Relative),
543 new Dictionary<string, string> { { "cursor", "-1" } },
546 .ReturnsAsync(new TwitterIds());
548 twitterApi.apiConnection = mock.Object;
550 await twitterApi.BlocksIds(cursor: -1L)
551 .ConfigureAwait(false);
558 public async Task BlocksCreate_Test()
560 using (var twitterApi = new TwitterApi())
562 var mock = new Mock<IApiConnection>();
564 x.PostLazyAsync<TwitterUser>(
565 new Uri("blocks/create.json", UriKind.Relative),
566 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
568 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
570 twitterApi.apiConnection = mock.Object;
572 await twitterApi.BlocksCreate(screenName: "twitterapi")
574 .ConfigureAwait(false);
581 public async Task BlocksDestroy_Test()
583 using (var twitterApi = new TwitterApi())
585 var mock = new Mock<IApiConnection>();
587 x.PostLazyAsync<TwitterUser>(
588 new Uri("blocks/destroy.json", UriKind.Relative),
589 new Dictionary<string, string> { { "screen_name", "twitterapi" } })
591 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
593 twitterApi.apiConnection = mock.Object;
595 await twitterApi.BlocksDestroy(screenName: "twitterapi")
597 .ConfigureAwait(false);
604 public async Task AccountUpdateProfile_Test()
606 using (var twitterApi = new TwitterApi())
608 var mock = new Mock<IApiConnection>();
610 x.PostLazyAsync<TwitterUser>(
611 new Uri("account/update_profile.json", UriKind.Relative),
612 new Dictionary<string, string> {
613 { "include_entities", "true" },
614 { "include_ext_alt_text", "true" },
616 { "url", "http://example.com/" },
617 { "location", "Location" },
618 { "description", "<script>alert(1)</script>" },
621 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
623 twitterApi.apiConnection = mock.Object;
625 await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
627 .ConfigureAwait(false);
634 public async Task AccountUpdateProfileImage_Test()
636 using (var twitterApi = new TwitterApi())
637 using (var image = TestUtils.CreateDummyImage())
638 using (var media = new MemoryImageMediaItem(image))
640 var mock = new Mock<IApiConnection>();
642 x.PostLazyAsync<TwitterUser>(
643 new Uri("account/update_profile_image.json", UriKind.Relative),
644 new Dictionary<string, string> {
645 { "include_entities", "true" },
646 { "include_ext_alt_text", "true" },
648 new Dictionary<string, IMediaItem> { { "image", media } })
650 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
652 twitterApi.apiConnection = mock.Object;
654 await twitterApi.AccountUpdateProfileImage(media)
656 .ConfigureAwait(false);
663 public async Task Configuration_Test()
665 using (var twitterApi = new TwitterApi())
667 var mock = new Mock<IApiConnection>();
669 x.GetAsync<TwitterConfiguration>(
670 new Uri("help/configuration.json", UriKind.Relative),
672 "/help/configuration")
674 .ReturnsAsync(new TwitterConfiguration());
676 twitterApi.apiConnection = mock.Object;
678 await twitterApi.Configuration()
679 .ConfigureAwait(false);
686 public async Task MediaUpload_Test()
688 using (var twitterApi = new TwitterApi())
689 using (var image = TestUtils.CreateDummyImage())
690 using (var media = new MemoryImageMediaItem(image))
692 var mock = new Mock<IApiConnection>();
694 x.PostLazyAsync<TwitterUploadMediaResult>(
695 new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
697 new Dictionary<string, IMediaItem> { { "media", media } })
699 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
701 twitterApi.apiConnection = mock.Object;
703 await twitterApi.MediaUpload(media)
705 .ConfigureAwait(false);