OSDN Git Service

HttpTwitter.HomeTimeline, MentionsメソッドをTwitterApiクラスに置き換え
[opentween/open-tween.git] / OpenTween.Tests / Api / TwitterApiTest.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2016 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
4 //
5 // This file is part of OpenTween.
6 //
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)
10 // any later version.
11 //
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
15 // for more details.
16 //
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.
21
22 using System;
23 using System.Collections.Generic;
24 using System.Linq;
25 using System.Net.Http;
26 using System.Reflection;
27 using System.Runtime.InteropServices;
28 using System.Text;
29 using System.Threading.Tasks;
30 using Moq;
31 using OpenTween.Api.DataModel;
32 using OpenTween.Connection;
33 using Xunit;
34
35 namespace OpenTween.Api
36 {
37     public class TwitterApiTest
38     {
39         public TwitterApiTest()
40         {
41             this.MyCommonSetup();
42         }
43
44         public void MyCommonSetup()
45         {
46             var mockAssembly = new Mock<_Assembly>();
47             mockAssembly.Setup(m => m.GetName()).Returns(new AssemblyName("OpenTween"));
48
49             MyCommon.EntryAssembly = mockAssembly.Object;
50         }
51
52         [Fact]
53         public void Initialize_Test()
54         {
55             using (var twitterApi = new TwitterApi())
56             {
57                 Assert.Null(twitterApi.apiConnection);
58
59                 twitterApi.Initialize("*** AccessToken ***", "*** AccessSecret ***", userId: 100L, screenName: "hogehoge");
60
61                 Assert.IsType<TwitterApiConnection>(twitterApi.apiConnection);
62
63                 var apiConnection = (TwitterApiConnection)twitterApi.apiConnection;
64                 Assert.Equal("*** AccessToken ***", apiConnection.AccessToken);
65                 Assert.Equal("*** AccessSecret ***", apiConnection.AccessSecret);
66
67                 Assert.Equal(100L, twitterApi.CurrentUserId);
68                 Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
69
70                 // 複数回 Initialize を実行した場合は新たに TwitterApiConnection が生成される
71                 twitterApi.Initialize("*** AccessToken2 ***", "*** AccessSecret2 ***", userId: 200L, screenName: "foobar");
72
73                 var oldApiConnection = apiConnection;
74                 Assert.True(oldApiConnection.IsDisposed);
75
76                 Assert.IsType<TwitterApiConnection>(twitterApi.apiConnection);
77
78                 apiConnection = (TwitterApiConnection)twitterApi.apiConnection;
79                 Assert.Equal("*** AccessToken2 ***", apiConnection.AccessToken);
80                 Assert.Equal("*** AccessSecret2 ***", apiConnection.AccessSecret);
81
82                 Assert.Equal(200L, twitterApi.CurrentUserId);
83                 Assert.Equal("foobar", twitterApi.CurrentScreenName);
84             }
85         }
86
87         [Fact]
88         public async Task StatusesHomeTimeline_Test()
89         {
90             using (var twitterApi = new TwitterApi())
91             {
92                 var mock = new Mock<IApiConnection>();
93                 mock.Setup(x =>
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" },
99                             { "count", "200" },
100                             { "max_id", "900" },
101                             { "since_id", "100" },
102                         },
103                         "/statuses/home_timeline")
104                 )
105                 .ReturnsAsync(new TwitterStatus[0]);
106
107                 twitterApi.apiConnection = mock.Object;
108
109                 await twitterApi.StatusesHomeTimeline(200, maxId: 900L, sinceId: 100L)
110                     .ConfigureAwait(false);
111
112                 mock.VerifyAll();
113             }
114         }
115
116         [Fact]
117         public async Task StatusesMentionsTimeline_Test()
118         {
119             using (var twitterApi = new TwitterApi())
120             {
121                 var mock = new Mock<IApiConnection>();
122                 mock.Setup(x =>
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                             { "count", "200" },
129                             { "max_id", "900" },
130                             { "since_id", "100" },
131                         },
132                         "/statuses/mentions_timeline")
133                 )
134                 .ReturnsAsync(new TwitterStatus[0]);
135
136                 twitterApi.apiConnection = mock.Object;
137
138                 await twitterApi.StatusesMentionsTimeline(200, maxId: 900L, sinceId: 100L)
139                     .ConfigureAwait(false);
140
141                 mock.VerifyAll();
142             }
143         }
144
145         [Fact]
146         public async Task StatusesShow_Test()
147         {
148             using (var twitterApi = new TwitterApi())
149             {
150                 var mock = new Mock<IApiConnection>();
151                 mock.Setup(x =>
152                     x.GetAsync<TwitterStatus>(
153                         new Uri("statuses/show.json", UriKind.Relative),
154                         new Dictionary<string, string> {
155                             { "id", "100" },
156                             { "include_entities", "true" },
157                             { "include_ext_alt_text", "true" },
158                         },
159                         "/statuses/show/:id")
160                 )
161                 .ReturnsAsync(new TwitterStatus { Id = 100L });
162
163                 twitterApi.apiConnection = mock.Object;
164
165                 await twitterApi.StatusesShow(statusId: 100L)
166                     .ConfigureAwait(false);
167
168                 mock.VerifyAll();
169             }
170         }
171
172         [Fact]
173         public async Task StatusesUpdate_Test()
174         {
175             using (var twitterApi = new TwitterApi())
176             {
177                 var mock = new Mock<IApiConnection>();
178                 mock.Setup(x =>
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" },
187                         })
188                 )
189                 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
190
191                 twitterApi.apiConnection = mock.Object;
192
193                 await twitterApi.StatusesUpdate("hogehoge", replyToId: 100L, mediaIds: new[] { 10L, 20L })
194                     .IgnoreResponse()
195                     .ConfigureAwait(false);
196
197                 mock.VerifyAll();
198             }
199         }
200
201         [Fact]
202         public async Task StatusesDestroy_Test()
203         {
204             using (var twitterApi = new TwitterApi())
205             {
206                 var mock = new Mock<IApiConnection>();
207                 mock.Setup(x =>
208                     x.PostLazyAsync<TwitterStatus>(
209                         new Uri("statuses/destroy.json", UriKind.Relative),
210                         new Dictionary<string, string> { { "id", "100" } })
211                 )
212                 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
213
214                 twitterApi.apiConnection = mock.Object;
215
216                 await twitterApi.StatusesDestroy(statusId: 100L)
217                     .IgnoreResponse()
218                     .ConfigureAwait(false);
219
220                 mock.VerifyAll();
221             }
222         }
223
224         [Fact]
225         public async Task StatusesRetweet_Test()
226         {
227             using (var twitterApi = new TwitterApi())
228             {
229                 var mock = new Mock<IApiConnection>();
230                 mock.Setup(x =>
231                     x.PostLazyAsync<TwitterStatus>(
232                         new Uri("statuses/retweet.json", UriKind.Relative),
233                         new Dictionary<string, string> {
234                             { "id", "100" },
235                             { "include_entities", "true" },
236                             { "include_ext_alt_text", "true" },
237                         })
238                 )
239                 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
240
241                 twitterApi.apiConnection = mock.Object;
242
243                 await twitterApi.StatusesRetweet(100L)
244                     .IgnoreResponse()
245                     .ConfigureAwait(false);
246
247                 mock.VerifyAll();
248             }
249         }
250
251         [Fact]
252         public async Task DirectMessagesNew_Test()
253         {
254             using (var twitterApi = new TwitterApi())
255             {
256                 var mock = new Mock<IApiConnection>();
257                 mock.Setup(x =>
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" },
263                         })
264                 )
265                 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage()));
266
267                 twitterApi.apiConnection = mock.Object;
268
269                 await twitterApi.DirectMessagesNew("hogehoge", "opentween")
270                     .IgnoreResponse()
271                     .ConfigureAwait(false);
272
273                 mock.VerifyAll();
274             }
275         }
276
277         [Fact]
278         public async Task DirectMessagesDestroy_Test()
279         {
280             using (var twitterApi = new TwitterApi())
281             {
282                 var mock = new Mock<IApiConnection>();
283                 mock.Setup(x =>
284                     x.PostLazyAsync<TwitterDirectMessage>(
285                         new Uri("direct_messages/destroy.json", UriKind.Relative),
286                         new Dictionary<string, string> { { "id", "100" } })
287                 )
288                 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage { Id = 100L }));
289
290                 twitterApi.apiConnection = mock.Object;
291
292                 await twitterApi.DirectMessagesDestroy(statusId: 100L)
293                     .IgnoreResponse()
294                     .ConfigureAwait(false);
295
296                 mock.VerifyAll();
297             }
298         }
299
300         [Fact]
301         public async Task UsersShow_Test()
302         {
303             using (var twitterApi = new TwitterApi())
304             {
305                 var mock = new Mock<IApiConnection>();
306                 mock.Setup(x =>
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" },
313                         },
314                         "/users/show/:id")
315                 )
316                 .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
317
318                 twitterApi.apiConnection = mock.Object;
319
320                 await twitterApi.UsersShow(screenName: "twitterapi")
321                     .ConfigureAwait(false);
322
323                 mock.VerifyAll();
324             }
325         }
326
327         [Fact]
328         public async Task UsersReportSpam_Test()
329         {
330             using (var twitterApi = new TwitterApi())
331             {
332                 var mock = new Mock<IApiConnection>();
333                 mock.Setup(x =>
334                     x.PostLazyAsync<TwitterUser>(
335                         new Uri("users/report_spam.json", UriKind.Relative),
336                         new Dictionary<string, string> { { "screen_name", "twitterapi" } })
337                 )
338                 .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
339
340                 twitterApi.apiConnection = mock.Object;
341
342                 await twitterApi.UsersReportSpam(screenName: "twitterapi")
343                     .IgnoreResponse()
344                     .ConfigureAwait(false);
345
346                 mock.VerifyAll();
347             }
348         }
349
350         [Fact]
351         public async Task FavoritesCreate_Test()
352         {
353             using (var twitterApi = new TwitterApi())
354             {
355                 var mock = new Mock<IApiConnection>();
356                 mock.Setup(x =>
357                     x.PostLazyAsync<TwitterStatus>(
358                         new Uri("favorites/create.json", UriKind.Relative),
359                         new Dictionary<string, string> { { "id", "100" } })
360                 )
361                 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
362
363                 twitterApi.apiConnection = mock.Object;
364
365                 await twitterApi.FavoritesCreate(statusId: 100L)
366                     .IgnoreResponse()
367                     .ConfigureAwait(false);
368
369                 mock.VerifyAll();
370             }
371         }
372
373         [Fact]
374         public async Task FavoritesDestroy_Test()
375         {
376             using (var twitterApi = new TwitterApi())
377             {
378                 var mock = new Mock<IApiConnection>();
379                 mock.Setup(x =>
380                     x.PostLazyAsync<TwitterStatus>(
381                         new Uri("favorites/destroy.json", UriKind.Relative),
382                         new Dictionary<string, string> { { "id", "100" } })
383                 )
384                 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
385
386                 twitterApi.apiConnection = mock.Object;
387
388                 await twitterApi.FavoritesDestroy(statusId: 100L)
389                     .IgnoreResponse()
390                     .ConfigureAwait(false);
391
392                 mock.VerifyAll();
393             }
394         }
395
396         [Fact]
397         public async Task FriendshipsShow_Test()
398         {
399             using (var twitterApi = new TwitterApi())
400             {
401                 var mock = new Mock<IApiConnection>();
402                 mock.Setup(x =>
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" } },
406                         "/friendships/show")
407                 )
408                 .ReturnsAsync(new TwitterFriendship());
409
410                 twitterApi.apiConnection = mock.Object;
411
412                 await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi")
413                     .ConfigureAwait(false);
414
415                 mock.VerifyAll();
416             }
417         }
418
419         [Fact]
420         public async Task FriendshipsCreate_Test()
421         {
422             using (var twitterApi = new TwitterApi())
423             {
424                 var mock = new Mock<IApiConnection>();
425                 mock.Setup(x =>
426                     x.PostLazyAsync<TwitterFriendship>(
427                         new Uri("friendships/create.json", UriKind.Relative),
428                         new Dictionary<string, string> { { "screen_name", "twitterapi" } })
429                 )
430                 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
431
432                 twitterApi.apiConnection = mock.Object;
433
434                 await twitterApi.FriendshipsCreate(screenName: "twitterapi")
435                     .IgnoreResponse()
436                     .ConfigureAwait(false);
437
438                 mock.VerifyAll();
439             }
440         }
441
442         [Fact]
443         public async Task FriendshipsDestroy_Test()
444         {
445             using (var twitterApi = new TwitterApi())
446             {
447                 var mock = new Mock<IApiConnection>();
448                 mock.Setup(x =>
449                     x.PostLazyAsync<TwitterFriendship>(
450                         new Uri("friendships/destroy.json", UriKind.Relative),
451                         new Dictionary<string, string> { { "screen_name", "twitterapi" } })
452                 )
453                 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
454
455                 twitterApi.apiConnection = mock.Object;
456
457                 await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
458                     .IgnoreResponse()
459                     .ConfigureAwait(false);
460
461                 mock.VerifyAll();
462             }
463         }
464
465         [Fact]
466         public async Task NoRetweetIds_Test()
467         {
468             using (var twitterApi = new TwitterApi())
469             {
470                 var mock = new Mock<IApiConnection>();
471                 mock.Setup(x =>
472                     x.GetAsync<long[]>(
473                         new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
474                         null,
475                         "/friendships/no_retweets/ids")
476                 )
477                 .ReturnsAsync(new long[0]);
478
479                 twitterApi.apiConnection = mock.Object;
480
481                 await twitterApi.NoRetweetIds()
482                     .ConfigureAwait(false);
483
484                 mock.VerifyAll();
485             }
486         }
487
488         [Fact]
489         public async Task FollowersIds_Test()
490         {
491             using (var twitterApi = new TwitterApi())
492             {
493                 var mock = new Mock<IApiConnection>();
494                 mock.Setup(x =>
495                     x.GetAsync<TwitterIds>(
496                         new Uri("followers/ids.json", UriKind.Relative),
497                         new Dictionary<string, string> { { "cursor", "-1" } },
498                         "/followers/ids")
499                 )
500                 .ReturnsAsync(new TwitterIds());
501
502                 twitterApi.apiConnection = mock.Object;
503
504                 await twitterApi.FollowersIds(cursor: -1L)
505                     .ConfigureAwait(false);
506
507                 mock.VerifyAll();
508             }
509         }
510
511         [Fact]
512         public async Task MutesUsersIds_Test()
513         {
514             using (var twitterApi = new TwitterApi())
515             {
516                 var mock = new Mock<IApiConnection>();
517                 mock.Setup(x =>
518                     x.GetAsync<TwitterIds>(
519                         new Uri("mutes/users/ids.json", UriKind.Relative),
520                         new Dictionary<string, string> { { "cursor", "-1" } },
521                         "/mutes/users/ids")
522                 )
523                 .ReturnsAsync(new TwitterIds());
524
525                 twitterApi.apiConnection = mock.Object;
526
527                 await twitterApi.MutesUsersIds(cursor: -1L)
528                     .ConfigureAwait(false);
529
530                 mock.VerifyAll();
531             }
532         }
533
534         [Fact]
535         public async Task BlocksIds_Test()
536         {
537             using (var twitterApi = new TwitterApi())
538             {
539                 var mock = new Mock<IApiConnection>();
540                 mock.Setup(x =>
541                     x.GetAsync<TwitterIds>(
542                         new Uri("blocks/ids.json", UriKind.Relative),
543                         new Dictionary<string, string> { { "cursor", "-1" } },
544                         "/blocks/ids")
545                 )
546                 .ReturnsAsync(new TwitterIds());
547
548                 twitterApi.apiConnection = mock.Object;
549
550                 await twitterApi.BlocksIds(cursor: -1L)
551                     .ConfigureAwait(false);
552
553                 mock.VerifyAll();
554             }
555         }
556
557         [Fact]
558         public async Task BlocksCreate_Test()
559         {
560             using (var twitterApi = new TwitterApi())
561             {
562                 var mock = new Mock<IApiConnection>();
563                 mock.Setup(x =>
564                     x.PostLazyAsync<TwitterUser>(
565                         new Uri("blocks/create.json", UriKind.Relative),
566                         new Dictionary<string, string> { { "screen_name", "twitterapi" } })
567                 )
568                 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
569
570                 twitterApi.apiConnection = mock.Object;
571
572                 await twitterApi.BlocksCreate(screenName: "twitterapi")
573                     .IgnoreResponse()
574                     .ConfigureAwait(false);
575
576                 mock.VerifyAll();
577             }
578         }
579
580         [Fact]
581         public async Task BlocksDestroy_Test()
582         {
583             using (var twitterApi = new TwitterApi())
584             {
585                 var mock = new Mock<IApiConnection>();
586                 mock.Setup(x =>
587                     x.PostLazyAsync<TwitterUser>(
588                         new Uri("blocks/destroy.json", UriKind.Relative),
589                         new Dictionary<string, string> { { "screen_name", "twitterapi" } })
590                 )
591                 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
592
593                 twitterApi.apiConnection = mock.Object;
594
595                 await twitterApi.BlocksDestroy(screenName: "twitterapi")
596                     .IgnoreResponse()
597                     .ConfigureAwait(false);
598
599                 mock.VerifyAll();
600             }
601         }
602
603         [Fact]
604         public async Task AccountUpdateProfile_Test()
605         {
606             using (var twitterApi = new TwitterApi())
607             {
608                 var mock = new Mock<IApiConnection>();
609                 mock.Setup(x =>
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" },
615                             { "name", "Name" },
616                             { "url", "http://example.com/" },
617                             { "location", "Location" },
618                             { "description", "&lt;script&gt;alert(1)&lt;/script&gt;" },
619                         })
620                 )
621                 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
622
623                 twitterApi.apiConnection = mock.Object;
624
625                 await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
626                     .IgnoreResponse()
627                     .ConfigureAwait(false);
628
629                 mock.VerifyAll();
630             }
631         }
632
633         [Fact]
634         public async Task AccountUpdateProfileImage_Test()
635         {
636             using (var twitterApi = new TwitterApi())
637             using (var image = TestUtils.CreateDummyImage())
638             using (var media = new MemoryImageMediaItem(image))
639             {
640                 var mock = new Mock<IApiConnection>();
641                 mock.Setup(x =>
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" },
647                         },
648                         new Dictionary<string, IMediaItem> { { "image", media } })
649                 )
650                 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
651
652                 twitterApi.apiConnection = mock.Object;
653
654                 await twitterApi.AccountUpdateProfileImage(media)
655                     .IgnoreResponse()
656                     .ConfigureAwait(false);
657
658                 mock.VerifyAll();
659             }
660         }
661
662         [Fact]
663         public async Task Configuration_Test()
664         {
665             using (var twitterApi = new TwitterApi())
666             {
667                 var mock = new Mock<IApiConnection>();
668                 mock.Setup(x =>
669                     x.GetAsync<TwitterConfiguration>(
670                         new Uri("help/configuration.json", UriKind.Relative),
671                         null,
672                         "/help/configuration")
673                 )
674                 .ReturnsAsync(new TwitterConfiguration());
675
676                 twitterApi.apiConnection = mock.Object;
677
678                 await twitterApi.Configuration()
679                     .ConfigureAwait(false);
680
681                 mock.VerifyAll();
682             }
683         }
684
685         [Fact]
686         public async Task MediaUpload_Test()
687         {
688             using (var twitterApi = new TwitterApi())
689             using (var image = TestUtils.CreateDummyImage())
690             using (var media = new MemoryImageMediaItem(image))
691             {
692                 var mock = new Mock<IApiConnection>();
693                 mock.Setup(x =>
694                     x.PostLazyAsync<TwitterUploadMediaResult>(
695                         new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
696                         null,
697                         new Dictionary<string, IMediaItem> { { "media", media } })
698                 )
699                 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
700
701                 twitterApi.apiConnection = mock.Object;
702
703                 await twitterApi.MediaUpload(media)
704                     .IgnoreResponse()
705                     .ConfigureAwait(false);
706
707                 mock.VerifyAll();
708             }
709         }
710     }
711 }