OSDN Git Service

ツイートに添付する画像のchunked uploadに対応
[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.IO;
25 using System.Linq;
26 using System.Net.Http;
27 using System.Reflection;
28 using System.Runtime.InteropServices;
29 using System.Text;
30 using System.Threading.Tasks;
31 using Moq;
32 using OpenTween.Api.DataModel;
33 using OpenTween.Connection;
34 using Xunit;
35
36 namespace OpenTween.Api
37 {
38     public class TwitterApiTest
39     {
40         public TwitterApiTest()
41         {
42             this.MyCommonSetup();
43         }
44
45         private void MyCommonSetup()
46         {
47             var mockAssembly = new Mock<_Assembly>();
48             mockAssembly.Setup(m => m.GetName()).Returns(new AssemblyName("OpenTween"));
49
50             MyCommon.EntryAssembly = mockAssembly.Object;
51         }
52
53         [Fact]
54         public void Initialize_Test()
55         {
56             using (var twitterApi = new TwitterApi())
57             {
58                 Assert.Null(twitterApi.apiConnection);
59
60                 twitterApi.Initialize("*** AccessToken ***", "*** AccessSecret ***", userId: 100L, screenName: "hogehoge");
61
62                 Assert.IsType<TwitterApiConnection>(twitterApi.apiConnection);
63
64                 var apiConnection = (TwitterApiConnection)twitterApi.apiConnection;
65                 Assert.Equal("*** AccessToken ***", apiConnection.AccessToken);
66                 Assert.Equal("*** AccessSecret ***", apiConnection.AccessSecret);
67
68                 Assert.Equal(100L, twitterApi.CurrentUserId);
69                 Assert.Equal("hogehoge", twitterApi.CurrentScreenName);
70
71                 // 複数回 Initialize を実行した場合は新たに TwitterApiConnection が生成される
72                 twitterApi.Initialize("*** AccessToken2 ***", "*** AccessSecret2 ***", userId: 200L, screenName: "foobar");
73
74                 var oldApiConnection = apiConnection;
75                 Assert.True(oldApiConnection.IsDisposed);
76
77                 Assert.IsType<TwitterApiConnection>(twitterApi.apiConnection);
78
79                 apiConnection = (TwitterApiConnection)twitterApi.apiConnection;
80                 Assert.Equal("*** AccessToken2 ***", apiConnection.AccessToken);
81                 Assert.Equal("*** AccessSecret2 ***", apiConnection.AccessSecret);
82
83                 Assert.Equal(200L, twitterApi.CurrentUserId);
84                 Assert.Equal("foobar", twitterApi.CurrentScreenName);
85             }
86         }
87
88         [Fact]
89         public async Task StatusesHomeTimeline_Test()
90         {
91             using (var twitterApi = new TwitterApi())
92             {
93                 var mock = new Mock<IApiConnection>();
94                 mock.Setup(x =>
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" },
101                             { "count", "200" },
102                             { "max_id", "900" },
103                             { "since_id", "100" },
104                         },
105                         "/statuses/home_timeline")
106                 )
107                 .ReturnsAsync(new TwitterStatus[0]);
108
109                 twitterApi.apiConnection = mock.Object;
110
111                 await twitterApi.StatusesHomeTimeline(200, maxId: 900L, sinceId: 100L)
112                     .ConfigureAwait(false);
113
114                 mock.VerifyAll();
115             }
116         }
117
118         [Fact]
119         public async Task StatusesMentionsTimeline_Test()
120         {
121             using (var twitterApi = new TwitterApi())
122             {
123                 var mock = new Mock<IApiConnection>();
124                 mock.Setup(x =>
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" },
131                             { "count", "200" },
132                             { "max_id", "900" },
133                             { "since_id", "100" },
134                         },
135                         "/statuses/mentions_timeline")
136                 )
137                 .ReturnsAsync(new TwitterStatus[0]);
138
139                 twitterApi.apiConnection = mock.Object;
140
141                 await twitterApi.StatusesMentionsTimeline(200, maxId: 900L, sinceId: 100L)
142                     .ConfigureAwait(false);
143
144                 mock.VerifyAll();
145             }
146         }
147
148         [Fact]
149         public async Task StatusesUserTimeline_Test()
150         {
151             using (var twitterApi = new TwitterApi())
152             {
153                 var mock = new Mock<IApiConnection>();
154                 mock.Setup(x =>
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" },
163                             { "count", "200" },
164                             { "max_id", "900" },
165                             { "since_id", "100" },
166                         },
167                         "/statuses/user_timeline")
168                 )
169                 .ReturnsAsync(new TwitterStatus[0]);
170
171                 twitterApi.apiConnection = mock.Object;
172
173                 await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: 900L, sinceId: 100L)
174                     .ConfigureAwait(false);
175
176                 mock.VerifyAll();
177             }
178         }
179
180         [Fact]
181         public async Task StatusesShow_Test()
182         {
183             using (var twitterApi = new TwitterApi())
184             {
185                 var mock = new Mock<IApiConnection>();
186                 mock.Setup(x =>
187                     x.GetAsync<TwitterStatus>(
188                         new Uri("statuses/show.json", UriKind.Relative),
189                         new Dictionary<string, string> {
190                             { "id", "100" },
191                             { "include_entities", "true" },
192                             { "include_ext_alt_text", "true" },
193                             { "tweet_mode", "extended" },
194                         },
195                         "/statuses/show/:id")
196                 )
197                 .ReturnsAsync(new TwitterStatus { Id = 100L });
198
199                 twitterApi.apiConnection = mock.Object;
200
201                 await twitterApi.StatusesShow(statusId: 100L)
202                     .ConfigureAwait(false);
203
204                 mock.VerifyAll();
205             }
206         }
207
208         [Fact]
209         public async Task StatusesUpdate_Test()
210         {
211             using (var twitterApi = new TwitterApi())
212             {
213                 var mock = new Mock<IApiConnection>();
214                 mock.Setup(x =>
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" },
227                         })
228                 )
229                 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
230
231                 twitterApi.apiConnection = mock.Object;
232
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")
236                     .IgnoreResponse()
237                     .ConfigureAwait(false);
238
239                 mock.VerifyAll();
240             }
241         }
242
243         [Fact]
244         public async Task StatusesUpdate_ExcludeReplyUserIdsEmptyTest()
245         {
246             using (var twitterApi = new TwitterApi())
247             {
248                 var mock = new Mock<IApiConnection>();
249                 mock.Setup(x =>
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 は空の場合には送信されない
258                         })
259                 )
260                 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
261
262                 twitterApi.apiConnection = mock.Object;
263
264                 await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: new long[0])
265                     .IgnoreResponse()
266                     .ConfigureAwait(false);
267
268                 mock.VerifyAll();
269             }
270         }
271
272         [Fact]
273         public async Task StatusesDestroy_Test()
274         {
275             using (var twitterApi = new TwitterApi())
276             {
277                 var mock = new Mock<IApiConnection>();
278                 mock.Setup(x =>
279                     x.PostLazyAsync<TwitterStatus>(
280                         new Uri("statuses/destroy.json", UriKind.Relative),
281                         new Dictionary<string, string> { { "id", "100" } })
282                 )
283                 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
284
285                 twitterApi.apiConnection = mock.Object;
286
287                 await twitterApi.StatusesDestroy(statusId: 100L)
288                     .IgnoreResponse()
289                     .ConfigureAwait(false);
290
291                 mock.VerifyAll();
292             }
293         }
294
295         [Fact]
296         public async Task StatusesRetweet_Test()
297         {
298             using (var twitterApi = new TwitterApi())
299             {
300                 var mock = new Mock<IApiConnection>();
301                 mock.Setup(x =>
302                     x.PostLazyAsync<TwitterStatus>(
303                         new Uri("statuses/retweet.json", UriKind.Relative),
304                         new Dictionary<string, string> {
305                             { "id", "100" },
306                             { "include_entities", "true" },
307                             { "include_ext_alt_text", "true" },
308                             { "tweet_mode", "extended" },
309                         })
310                 )
311                 .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
312
313                 twitterApi.apiConnection = mock.Object;
314
315                 await twitterApi.StatusesRetweet(100L)
316                     .IgnoreResponse()
317                     .ConfigureAwait(false);
318
319                 mock.VerifyAll();
320             }
321         }
322
323         [Fact]
324         public async Task SearchTweets_Test()
325         {
326             using (var twitterApi = new TwitterApi())
327             {
328                 var mock = new Mock<IApiConnection>();
329                 mock.Setup(x =>
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" },
338                             { "lang", "en" },
339                             { "count", "200" },
340                             { "max_id", "900" },
341                             { "since_id", "100" },
342                         },
343                         "/search/tweets")
344                 )
345                 .ReturnsAsync(new TwitterSearchResult());
346
347                 twitterApi.apiConnection = mock.Object;
348
349                 await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: 900L, sinceId: 100L)
350                     .ConfigureAwait(false);
351
352                 mock.VerifyAll();
353             }
354         }
355
356         [Fact]
357         public async Task ListsOwnerships_Test()
358         {
359             using (var twitterApi = new TwitterApi())
360             {
361                 var mock = new Mock<IApiConnection>();
362                 mock.Setup(x =>
363                     x.GetAsync<TwitterLists>(
364                         new Uri("lists/ownerships.json", UriKind.Relative),
365                         new Dictionary<string, string> {
366                             { "screen_name", "twitterapi" },
367                             { "cursor", "-1" },
368                             { "count", "100" },
369                         },
370                         "/lists/ownerships")
371                 )
372                 .ReturnsAsync(new TwitterLists());
373
374                 twitterApi.apiConnection = mock.Object;
375
376                 await twitterApi.ListsOwnerships("twitterapi", cursor: -1L, count: 100)
377                     .ConfigureAwait(false);
378
379                 mock.VerifyAll();
380             }
381         }
382
383         [Fact]
384         public async Task ListsSubscriptions_Test()
385         {
386             using (var twitterApi = new TwitterApi())
387             {
388                 var mock = new Mock<IApiConnection>();
389                 mock.Setup(x =>
390                     x.GetAsync<TwitterLists>(
391                         new Uri("lists/subscriptions.json", UriKind.Relative),
392                         new Dictionary<string, string> {
393                             { "screen_name", "twitterapi" },
394                             { "cursor", "-1" },
395                             { "count", "100" },
396                         },
397                         "/lists/subscriptions")
398                 )
399                 .ReturnsAsync(new TwitterLists());
400
401                 twitterApi.apiConnection = mock.Object;
402
403                 await twitterApi.ListsSubscriptions("twitterapi", cursor: -1L, count: 100)
404                     .ConfigureAwait(false);
405
406                 mock.VerifyAll();
407             }
408         }
409
410         [Fact]
411         public async Task ListsMemberships_Test()
412         {
413             using (var twitterApi = new TwitterApi())
414             {
415                 var mock = new Mock<IApiConnection>();
416                 mock.Setup(x =>
417                     x.GetAsync<TwitterLists>(
418                         new Uri("lists/memberships.json", UriKind.Relative),
419                         new Dictionary<string, string> {
420                             { "screen_name", "twitterapi" },
421                             { "cursor", "-1" },
422                             { "count", "100" },
423                             { "filter_to_owned_lists", "true" },
424                         },
425                         "/lists/memberships")
426                 )
427                 .ReturnsAsync(new TwitterLists());
428
429                 twitterApi.apiConnection = mock.Object;
430
431                 await twitterApi.ListsMemberships("twitterapi", cursor: -1L, count: 100, filterToOwnedLists: true)
432                     .ConfigureAwait(false);
433
434                 mock.VerifyAll();
435             }
436         }
437
438         [Fact]
439         public async Task ListsCreate_Test()
440         {
441             using (var twitterApi = new TwitterApi())
442             {
443                 var mock = new Mock<IApiConnection>();
444                 mock.Setup(x =>
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" },
451                         })
452                 )
453                 .ReturnsAsync(LazyJson.Create(new TwitterList()));
454
455                 twitterApi.apiConnection = mock.Object;
456
457                 await twitterApi.ListsCreate("hogehoge", description: "aaaa", @private: true)
458                     .IgnoreResponse()
459                     .ConfigureAwait(false);
460
461                 mock.VerifyAll();
462             }
463         }
464
465         [Fact]
466         public async Task ListsUpdate_Test()
467         {
468             using (var twitterApi = new TwitterApi())
469             {
470                 var mock = new Mock<IApiConnection>();
471                 mock.Setup(x =>
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" },
479                         })
480                 )
481                 .ReturnsAsync(LazyJson.Create(new TwitterList()));
482
483                 twitterApi.apiConnection = mock.Object;
484
485                 await twitterApi.ListsUpdate(12345L, name: "hogehoge", description: "aaaa", @private: true)
486                     .IgnoreResponse()
487                     .ConfigureAwait(false);
488
489                 mock.VerifyAll();
490             }
491         }
492
493         [Fact]
494         public async Task ListsDestroy_Test()
495         {
496             using (var twitterApi = new TwitterApi())
497             {
498                 var mock = new Mock<IApiConnection>();
499                 mock.Setup(x =>
500                     x.PostLazyAsync<TwitterList>(
501                         new Uri("lists/destroy.json", UriKind.Relative),
502                         new Dictionary<string, string> {
503                             { "list_id", "12345" },
504                         })
505                 )
506                 .ReturnsAsync(LazyJson.Create(new TwitterList()));
507
508                 twitterApi.apiConnection = mock.Object;
509
510                 await twitterApi.ListsDestroy(12345L)
511                     .IgnoreResponse()
512                     .ConfigureAwait(false);
513
514                 mock.VerifyAll();
515             }
516         }
517
518         [Fact]
519         public async Task ListsStatuses_Test()
520         {
521             using (var twitterApi = new TwitterApi())
522             {
523                 var mock = new Mock<IApiConnection>();
524                 mock.Setup(x =>
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" },
532                             { "count", "200" },
533                             { "max_id", "900" },
534                             { "since_id", "100" },
535                             { "include_rts", "true" },
536                         },
537                         "/lists/statuses")
538                 )
539                 .ReturnsAsync(new TwitterStatus[0]);
540
541                 twitterApi.apiConnection = mock.Object;
542
543                 await twitterApi.ListsStatuses(12345L, count: 200, maxId: 900L, sinceId: 100L, includeRTs: true)
544                     .ConfigureAwait(false);
545
546                 mock.VerifyAll();
547             }
548         }
549
550         [Fact]
551         public async Task ListsMembers_Test()
552         {
553             using (var twitterApi = new TwitterApi())
554             {
555                 var mock = new Mock<IApiConnection>();
556                 mock.Setup(x =>
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" },
564                             { "cursor", "-1" },
565                         },
566                         "/lists/members")
567                 )
568                 .ReturnsAsync(new TwitterUsers());
569
570                 twitterApi.apiConnection = mock.Object;
571
572                 await twitterApi.ListsMembers(12345L, cursor: -1)
573                     .ConfigureAwait(false);
574
575                 mock.VerifyAll();
576             }
577         }
578
579         [Fact]
580         public async Task ListsMembersShow_Test()
581         {
582             using (var twitterApi = new TwitterApi())
583             {
584                 var mock = new Mock<IApiConnection>();
585                 mock.Setup(x =>
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" },
594                         },
595                         "/lists/members/show")
596                 )
597                 .ReturnsAsync(new TwitterUser());
598
599                 twitterApi.apiConnection = mock.Object;
600
601                 await twitterApi.ListsMembersShow(12345L, "twitterapi")
602                     .ConfigureAwait(false);
603
604                 mock.VerifyAll();
605             }
606         }
607
608         [Fact]
609         public async Task ListsMembersCreate_Test()
610         {
611             using (var twitterApi = new TwitterApi())
612             {
613                 var mock = new Mock<IApiConnection>();
614                 mock.Setup(x =>
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" },
623                         })
624                 )
625                 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
626
627                 twitterApi.apiConnection = mock.Object;
628
629                 await twitterApi.ListsMembersCreate(12345L, "twitterapi")
630                     .IgnoreResponse()
631                     .ConfigureAwait(false);
632
633                 mock.VerifyAll();
634             }
635         }
636
637         [Fact]
638         public async Task ListsMembersDestroy_Test()
639         {
640             using (var twitterApi = new TwitterApi())
641             {
642                 var mock = new Mock<IApiConnection>();
643                 mock.Setup(x =>
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" },
652                         })
653                 )
654                 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
655
656                 twitterApi.apiConnection = mock.Object;
657
658                 await twitterApi.ListsMembersDestroy(12345L, "twitterapi")
659                     .IgnoreResponse()
660                     .ConfigureAwait(false);
661
662                 mock.VerifyAll();
663             }
664         }
665
666         [Fact]
667         public async Task DirectMessagesRecv_Test()
668         {
669             using (var twitterApi = new TwitterApi())
670             {
671                 var mock = new Mock<IApiConnection>();
672                 mock.Setup(x =>
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" },
679                             { "count", "200" },
680                             { "max_id", "900" },
681                             { "since_id", "100" },
682                         },
683                         "/direct_messages")
684                 )
685                 .ReturnsAsync(new TwitterDirectMessage[0]);
686
687                 twitterApi.apiConnection = mock.Object;
688
689                 await twitterApi.DirectMessagesRecv(count: 200, maxId: 900L, sinceId: 100L)
690                     .ConfigureAwait(false);
691
692                 mock.VerifyAll();
693             }
694         }
695
696         [Fact]
697         public async Task DirectMessagesSent_Test()
698         {
699             using (var twitterApi = new TwitterApi())
700             {
701                 var mock = new Mock<IApiConnection>();
702                 mock.Setup(x =>
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" },
709                             { "count", "200" },
710                             { "max_id", "900" },
711                             { "since_id", "100" },
712                         },
713                         "/direct_messages/sent")
714                 )
715                 .ReturnsAsync(new TwitterDirectMessage[0]);
716
717                 twitterApi.apiConnection = mock.Object;
718
719                 await twitterApi.DirectMessagesSent(count: 200, maxId: 900L, sinceId: 100L)
720                     .ConfigureAwait(false);
721
722                 mock.VerifyAll();
723             }
724         }
725
726         [Fact]
727         public async Task DirectMessagesDestroy_Test()
728         {
729             using (var twitterApi = new TwitterApi())
730             {
731                 var mock = new Mock<IApiConnection>();
732                 mock.Setup(x =>
733                     x.PostLazyAsync<TwitterDirectMessage>(
734                         new Uri("direct_messages/destroy.json", UriKind.Relative),
735                         new Dictionary<string, string> { { "id", "100" } })
736                 )
737                 .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage { Id = 100L }));
738
739                 twitterApi.apiConnection = mock.Object;
740
741                 await twitterApi.DirectMessagesDestroy(statusId: 100L)
742                     .IgnoreResponse()
743                     .ConfigureAwait(false);
744
745                 mock.VerifyAll();
746             }
747         }
748
749         [Fact]
750         public async Task DirectMessagesEventsNew_Test()
751         {
752             using (var twitterApi = new TwitterApi())
753             {
754                 var mock = new Mock<IApiConnection>();
755                 mock.Setup(x =>
756                     x.PostJsonAsync(
757                         new Uri("direct_messages/events/new.json", UriKind.Relative),
758                         @"{
759   ""event"": {
760     ""type"": ""message_create"",
761     ""message_create"": {
762       ""target"": {
763         ""recipient_id"": ""12345""
764       },
765       ""message_data"": {
766         ""text"": ""hogehoge""
767       }
768     }
769   }
770 }")
771                 )
772                 .Returns(Task.FromResult(0));
773
774                 twitterApi.apiConnection = mock.Object;
775
776                 await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge")
777                     .ConfigureAwait(false);
778
779                 mock.VerifyAll();
780             }
781         }
782
783         [Fact]
784         public async Task UsersShow_Test()
785         {
786             using (var twitterApi = new TwitterApi())
787             {
788                 var mock = new Mock<IApiConnection>();
789                 mock.Setup(x =>
790                     x.GetAsync<TwitterUser>(
791                         new Uri("users/show.json", UriKind.Relative),
792                         new Dictionary<string, string> {
793                             { "screen_name", "twitterapi" },
794                             { "include_entities", "true" },
795                             { "include_ext_alt_text", "true" },
796                             { "tweet_mode", "extended" },
797                         },
798                         "/users/show/:id")
799                 )
800                 .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
801
802                 twitterApi.apiConnection = mock.Object;
803
804                 await twitterApi.UsersShow(screenName: "twitterapi")
805                     .ConfigureAwait(false);
806
807                 mock.VerifyAll();
808             }
809         }
810
811         [Fact]
812         public async Task UsersReportSpam_Test()
813         {
814             using (var twitterApi = new TwitterApi())
815             {
816                 var mock = new Mock<IApiConnection>();
817                 mock.Setup(x =>
818                     x.PostLazyAsync<TwitterUser>(
819                         new Uri("users/report_spam.json", UriKind.Relative),
820                         new Dictionary<string, string> {
821                             { "screen_name", "twitterapi" },
822                             { "tweet_mode", "extended" },
823                         })
824                 )
825                 .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
826
827                 twitterApi.apiConnection = mock.Object;
828
829                 await twitterApi.UsersReportSpam(screenName: "twitterapi")
830                     .IgnoreResponse()
831                     .ConfigureAwait(false);
832
833                 mock.VerifyAll();
834             }
835         }
836
837         [Fact]
838         public async Task FavoritesList_Test()
839         {
840             using (var twitterApi = new TwitterApi())
841             {
842                 var mock = new Mock<IApiConnection>();
843                 mock.Setup(x =>
844                     x.GetAsync<TwitterStatus[]>(
845                         new Uri("favorites/list.json", UriKind.Relative),
846                         new Dictionary<string, string> {
847                             { "include_entities", "true" },
848                             { "include_ext_alt_text", "true" },
849                             { "tweet_mode", "extended" },
850                             { "count", "200" },
851                             { "max_id", "900" },
852                             { "since_id", "100" },
853                         },
854                         "/favorites/list")
855                 )
856                 .ReturnsAsync(new TwitterStatus[0]);
857
858                 twitterApi.apiConnection = mock.Object;
859
860                 await twitterApi.FavoritesList(200, maxId: 900L, sinceId: 100L)
861                     .ConfigureAwait(false);
862
863                 mock.VerifyAll();
864             }
865         }
866
867         [Fact]
868         public async Task FavoritesCreate_Test()
869         {
870             using (var twitterApi = new TwitterApi())
871             {
872                 var mock = new Mock<IApiConnection>();
873                 mock.Setup(x =>
874                     x.PostLazyAsync<TwitterStatus>(
875                         new Uri("favorites/create.json", UriKind.Relative),
876                         new Dictionary<string, string> {
877                             { "id", "100" },
878                             { "tweet_mode", "extended" },
879                         })
880                 )
881                 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
882
883                 twitterApi.apiConnection = mock.Object;
884
885                 await twitterApi.FavoritesCreate(statusId: 100L)
886                     .IgnoreResponse()
887                     .ConfigureAwait(false);
888
889                 mock.VerifyAll();
890             }
891         }
892
893         [Fact]
894         public async Task FavoritesDestroy_Test()
895         {
896             using (var twitterApi = new TwitterApi())
897             {
898                 var mock = new Mock<IApiConnection>();
899                 mock.Setup(x =>
900                     x.PostLazyAsync<TwitterStatus>(
901                         new Uri("favorites/destroy.json", UriKind.Relative),
902                         new Dictionary<string, string> {
903                             { "id", "100" },
904                             { "tweet_mode", "extended" },
905                         })
906                 )
907                 .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
908
909                 twitterApi.apiConnection = mock.Object;
910
911                 await twitterApi.FavoritesDestroy(statusId: 100L)
912                     .IgnoreResponse()
913                     .ConfigureAwait(false);
914
915                 mock.VerifyAll();
916             }
917         }
918
919         [Fact]
920         public async Task FriendshipsShow_Test()
921         {
922             using (var twitterApi = new TwitterApi())
923             {
924                 var mock = new Mock<IApiConnection>();
925                 mock.Setup(x =>
926                     x.GetAsync<TwitterFriendship>(
927                         new Uri("friendships/show.json", UriKind.Relative),
928                         new Dictionary<string, string> { { "source_screen_name", "twitter" }, { "target_screen_name", "twitterapi" } },
929                         "/friendships/show")
930                 )
931                 .ReturnsAsync(new TwitterFriendship());
932
933                 twitterApi.apiConnection = mock.Object;
934
935                 await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi")
936                     .ConfigureAwait(false);
937
938                 mock.VerifyAll();
939             }
940         }
941
942         [Fact]
943         public async Task FriendshipsCreate_Test()
944         {
945             using (var twitterApi = new TwitterApi())
946             {
947                 var mock = new Mock<IApiConnection>();
948                 mock.Setup(x =>
949                     x.PostLazyAsync<TwitterFriendship>(
950                         new Uri("friendships/create.json", UriKind.Relative),
951                         new Dictionary<string, string> { { "screen_name", "twitterapi" } })
952                 )
953                 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
954
955                 twitterApi.apiConnection = mock.Object;
956
957                 await twitterApi.FriendshipsCreate(screenName: "twitterapi")
958                     .IgnoreResponse()
959                     .ConfigureAwait(false);
960
961                 mock.VerifyAll();
962             }
963         }
964
965         [Fact]
966         public async Task FriendshipsDestroy_Test()
967         {
968             using (var twitterApi = new TwitterApi())
969             {
970                 var mock = new Mock<IApiConnection>();
971                 mock.Setup(x =>
972                     x.PostLazyAsync<TwitterFriendship>(
973                         new Uri("friendships/destroy.json", UriKind.Relative),
974                         new Dictionary<string, string> { { "screen_name", "twitterapi" } })
975                 )
976                 .ReturnsAsync(LazyJson.Create(new TwitterFriendship()));
977
978                 twitterApi.apiConnection = mock.Object;
979
980                 await twitterApi.FriendshipsDestroy(screenName: "twitterapi")
981                     .IgnoreResponse()
982                     .ConfigureAwait(false);
983
984                 mock.VerifyAll();
985             }
986         }
987
988         [Fact]
989         public async Task NoRetweetIds_Test()
990         {
991             using (var twitterApi = new TwitterApi())
992             {
993                 var mock = new Mock<IApiConnection>();
994                 mock.Setup(x =>
995                     x.GetAsync<long[]>(
996                         new Uri("friendships/no_retweets/ids.json", UriKind.Relative),
997                         null,
998                         "/friendships/no_retweets/ids")
999                 )
1000                 .ReturnsAsync(new long[0]);
1001
1002                 twitterApi.apiConnection = mock.Object;
1003
1004                 await twitterApi.NoRetweetIds()
1005                     .ConfigureAwait(false);
1006
1007                 mock.VerifyAll();
1008             }
1009         }
1010
1011         [Fact]
1012         public async Task FollowersIds_Test()
1013         {
1014             using (var twitterApi = new TwitterApi())
1015             {
1016                 var mock = new Mock<IApiConnection>();
1017                 mock.Setup(x =>
1018                     x.GetAsync<TwitterIds>(
1019                         new Uri("followers/ids.json", UriKind.Relative),
1020                         new Dictionary<string, string> { { "cursor", "-1" } },
1021                         "/followers/ids")
1022                 )
1023                 .ReturnsAsync(new TwitterIds());
1024
1025                 twitterApi.apiConnection = mock.Object;
1026
1027                 await twitterApi.FollowersIds(cursor: -1L)
1028                     .ConfigureAwait(false);
1029
1030                 mock.VerifyAll();
1031             }
1032         }
1033
1034         [Fact]
1035         public async Task MutesUsersIds_Test()
1036         {
1037             using (var twitterApi = new TwitterApi())
1038             {
1039                 var mock = new Mock<IApiConnection>();
1040                 mock.Setup(x =>
1041                     x.GetAsync<TwitterIds>(
1042                         new Uri("mutes/users/ids.json", UriKind.Relative),
1043                         new Dictionary<string, string> { { "cursor", "-1" } },
1044                         "/mutes/users/ids")
1045                 )
1046                 .ReturnsAsync(new TwitterIds());
1047
1048                 twitterApi.apiConnection = mock.Object;
1049
1050                 await twitterApi.MutesUsersIds(cursor: -1L)
1051                     .ConfigureAwait(false);
1052
1053                 mock.VerifyAll();
1054             }
1055         }
1056
1057         [Fact]
1058         public async Task BlocksIds_Test()
1059         {
1060             using (var twitterApi = new TwitterApi())
1061             {
1062                 var mock = new Mock<IApiConnection>();
1063                 mock.Setup(x =>
1064                     x.GetAsync<TwitterIds>(
1065                         new Uri("blocks/ids.json", UriKind.Relative),
1066                         new Dictionary<string, string> { { "cursor", "-1" } },
1067                         "/blocks/ids")
1068                 )
1069                 .ReturnsAsync(new TwitterIds());
1070
1071                 twitterApi.apiConnection = mock.Object;
1072
1073                 await twitterApi.BlocksIds(cursor: -1L)
1074                     .ConfigureAwait(false);
1075
1076                 mock.VerifyAll();
1077             }
1078         }
1079
1080         [Fact]
1081         public async Task BlocksCreate_Test()
1082         {
1083             using (var twitterApi = new TwitterApi())
1084             {
1085                 var mock = new Mock<IApiConnection>();
1086                 mock.Setup(x =>
1087                     x.PostLazyAsync<TwitterUser>(
1088                         new Uri("blocks/create.json", UriKind.Relative),
1089                         new Dictionary<string, string> {
1090                             { "screen_name", "twitterapi" },
1091                             { "tweet_mode", "extended" },
1092                         })
1093                 )
1094                 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1095
1096                 twitterApi.apiConnection = mock.Object;
1097
1098                 await twitterApi.BlocksCreate(screenName: "twitterapi")
1099                     .IgnoreResponse()
1100                     .ConfigureAwait(false);
1101
1102                 mock.VerifyAll();
1103             }
1104         }
1105
1106         [Fact]
1107         public async Task BlocksDestroy_Test()
1108         {
1109             using (var twitterApi = new TwitterApi())
1110             {
1111                 var mock = new Mock<IApiConnection>();
1112                 mock.Setup(x =>
1113                     x.PostLazyAsync<TwitterUser>(
1114                         new Uri("blocks/destroy.json", UriKind.Relative),
1115                         new Dictionary<string, string> {
1116                             { "screen_name", "twitterapi" },
1117                             { "tweet_mode", "extended" },
1118                         })
1119                 )
1120                 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1121
1122                 twitterApi.apiConnection = mock.Object;
1123
1124                 await twitterApi.BlocksDestroy(screenName: "twitterapi")
1125                     .IgnoreResponse()
1126                     .ConfigureAwait(false);
1127
1128                 mock.VerifyAll();
1129             }
1130         }
1131
1132         [Fact]
1133         public async Task AccountVerifyCredentials_Test()
1134         {
1135             using (var twitterApi = new TwitterApi())
1136             {
1137                 var mock = new Mock<IApiConnection>();
1138                 mock.Setup(x =>
1139                     x.GetAsync<TwitterUser>(
1140                         new Uri("account/verify_credentials.json", UriKind.Relative),
1141                         new Dictionary<string, string> {
1142                             { "include_entities", "true" },
1143                             { "include_ext_alt_text", "true" },
1144                             { "tweet_mode", "extended" },
1145                         },
1146                         "/account/verify_credentials")
1147                 )
1148                 .ReturnsAsync(new TwitterUser {
1149                     Id = 100L,
1150                     ScreenName = "opentween",
1151                 });
1152
1153                 twitterApi.apiConnection = mock.Object;
1154
1155                 await twitterApi.AccountVerifyCredentials()
1156                     .ConfigureAwait(false);
1157
1158                 Assert.Equal(100L, twitterApi.CurrentUserId);
1159                 Assert.Equal("opentween", twitterApi.CurrentScreenName);
1160
1161                 mock.VerifyAll();
1162             }
1163         }
1164
1165         [Fact]
1166         public async Task AccountUpdateProfile_Test()
1167         {
1168             using (var twitterApi = new TwitterApi())
1169             {
1170                 var mock = new Mock<IApiConnection>();
1171                 mock.Setup(x =>
1172                     x.PostLazyAsync<TwitterUser>(
1173                         new Uri("account/update_profile.json", UriKind.Relative),
1174                         new Dictionary<string, string> {
1175                             { "include_entities", "true" },
1176                             { "include_ext_alt_text", "true" },
1177                             { "tweet_mode", "extended" },
1178                             { "name", "Name" },
1179                             { "url", "http://example.com/" },
1180                             { "location", "Location" },
1181                             { "description", "&lt;script&gt;alert(1)&lt;/script&gt;" },
1182                         })
1183                 )
1184                 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1185
1186                 twitterApi.apiConnection = mock.Object;
1187
1188                 await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "<script>alert(1)</script>")
1189                     .IgnoreResponse()
1190                     .ConfigureAwait(false);
1191
1192                 mock.VerifyAll();
1193             }
1194         }
1195
1196         [Fact]
1197         public async Task AccountUpdateProfileImage_Test()
1198         {
1199             using (var twitterApi = new TwitterApi())
1200             using (var image = TestUtils.CreateDummyImage())
1201             using (var media = new MemoryImageMediaItem(image))
1202             {
1203                 var mock = new Mock<IApiConnection>();
1204                 mock.Setup(x =>
1205                     x.PostLazyAsync<TwitterUser>(
1206                         new Uri("account/update_profile_image.json", UriKind.Relative),
1207                         new Dictionary<string, string> {
1208                             { "include_entities", "true" },
1209                             { "include_ext_alt_text", "true" },
1210                             { "tweet_mode", "extended" },
1211                         },
1212                         new Dictionary<string, IMediaItem> { { "image", media } })
1213                 )
1214                 .ReturnsAsync(LazyJson.Create(new TwitterUser()));
1215
1216                 twitterApi.apiConnection = mock.Object;
1217
1218                 await twitterApi.AccountUpdateProfileImage(media)
1219                     .IgnoreResponse()
1220                     .ConfigureAwait(false);
1221
1222                 mock.VerifyAll();
1223             }
1224         }
1225
1226         [Fact]
1227         public async Task ApplicationRateLimitStatus_Test()
1228         {
1229             using (var twitterApi = new TwitterApi())
1230             {
1231                 var mock = new Mock<IApiConnection>();
1232                 mock.Setup(x =>
1233                     x.GetAsync<TwitterRateLimits>(
1234                         new Uri("application/rate_limit_status.json", UriKind.Relative),
1235                         null,
1236                         "/application/rate_limit_status")
1237                 )
1238                 .ReturnsAsync(new TwitterRateLimits());
1239
1240                 twitterApi.apiConnection = mock.Object;
1241
1242                 await twitterApi.ApplicationRateLimitStatus()
1243                     .ConfigureAwait(false);
1244
1245                 mock.VerifyAll();
1246             }
1247         }
1248
1249         [Fact]
1250         public async Task Configuration_Test()
1251         {
1252             using (var twitterApi = new TwitterApi())
1253             {
1254                 var mock = new Mock<IApiConnection>();
1255                 mock.Setup(x =>
1256                     x.GetAsync<TwitterConfiguration>(
1257                         new Uri("help/configuration.json", UriKind.Relative),
1258                         null,
1259                         "/help/configuration")
1260                 )
1261                 .ReturnsAsync(new TwitterConfiguration());
1262
1263                 twitterApi.apiConnection = mock.Object;
1264
1265                 await twitterApi.Configuration()
1266                     .ConfigureAwait(false);
1267
1268                 mock.VerifyAll();
1269             }
1270         }
1271
1272         [Fact]
1273         public async Task MediaUploadInit_Test()
1274         {
1275             using (var twitterApi = new TwitterApi())
1276             {
1277                 var mock = new Mock<IApiConnection>();
1278                 mock.Setup(x =>
1279                     x.PostLazyAsync<TwitterUploadMediaInit>(
1280                         new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1281                         new Dictionary<string, string> {
1282                             { "command", "INIT" },
1283                             { "total_bytes", "123456" },
1284                             { "media_type", "image/png" },
1285                         })
1286                 )
1287                 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaInit()));
1288
1289                 twitterApi.apiConnection = mock.Object;
1290
1291                 await twitterApi.MediaUploadInit(totalBytes: 123456L, mediaType: "image/png")
1292                     .IgnoreResponse()
1293                     .ConfigureAwait(false);
1294
1295                 mock.VerifyAll();
1296             }
1297         }
1298
1299         [Fact]
1300         public async Task MediaUploadAppend_Test()
1301         {
1302             using (var twitterApi = new TwitterApi())
1303             using (var image = TestUtils.CreateDummyImage())
1304             using (var media = new MemoryImageMediaItem(image))
1305             {
1306                 var mock = new Mock<IApiConnection>();
1307                 mock.Setup(x =>
1308                     x.PostAsync(
1309                         new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1310                         new Dictionary<string, string> {
1311                             { "command", "APPEND" },
1312                             { "media_id", "11111" },
1313                             { "segment_index", "1" },
1314                         },
1315                         new Dictionary<string, IMediaItem> { { "media", media } })
1316                 )
1317                 .Returns(Task.FromResult(0));
1318
1319                 twitterApi.apiConnection = mock.Object;
1320
1321                 await twitterApi.MediaUploadAppend(mediaId: 11111L, segmentIndex: 1, media: media)
1322                     .ConfigureAwait(false);
1323
1324                 mock.VerifyAll();
1325             }
1326         }
1327
1328         [Fact]
1329         public async Task MediaUploadFinalize_Test()
1330         {
1331             using (var twitterApi = new TwitterApi())
1332             {
1333                 var mock = new Mock<IApiConnection>();
1334                 mock.Setup(x =>
1335                     x.PostLazyAsync<TwitterUploadMediaResult>(
1336                         new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1337                         new Dictionary<string, string> {
1338                             { "command", "FINALIZE" },
1339                             { "media_id", "11111" },
1340                         })
1341                 )
1342                 .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
1343
1344                 twitterApi.apiConnection = mock.Object;
1345
1346                 await twitterApi.MediaUploadFinalize(mediaId: 11111L)
1347                     .IgnoreResponse()
1348                     .ConfigureAwait(false);
1349
1350                 mock.VerifyAll();
1351             }
1352         }
1353
1354         [Fact]
1355         public async Task MediaUploadStatus_Test()
1356         {
1357             using (var twitterApi = new TwitterApi())
1358             {
1359                 var mock = new Mock<IApiConnection>();
1360                 mock.Setup(x =>
1361                     x.GetAsync<TwitterUploadMediaResult>(
1362                         new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
1363                         new Dictionary<string, string> {
1364                             { "command", "STATUS" },
1365                             { "media_id", "11111" },
1366                         },
1367                         null)
1368                 )
1369                 .ReturnsAsync(new TwitterUploadMediaResult());
1370
1371                 twitterApi.apiConnection = mock.Object;
1372
1373                 await twitterApi.MediaUploadStatus(mediaId: 11111L)
1374                     .ConfigureAwait(false);
1375
1376                 mock.VerifyAll();
1377             }
1378         }
1379
1380         [Fact]
1381         public async Task MediaMetadataCreate_Test()
1382         {
1383             using (var twitterApi = new TwitterApi())
1384             {
1385                 var mock = new Mock<IApiConnection>();
1386                 mock.Setup(x =>
1387                     x.PostJsonAsync(
1388                         new Uri("https://upload.twitter.com/1.1/media/metadata/create.json", UriKind.Absolute),
1389                         "{\"media_id\": \"12345\", \"alt_text\": {\"text\": \"hogehoge\"}}")
1390                 )
1391                 .Returns(Task.FromResult(0));
1392
1393                 twitterApi.apiConnection = mock.Object;
1394
1395                 await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge")
1396                     .ConfigureAwait(false);
1397
1398                 mock.VerifyAll();
1399             }
1400         }
1401
1402         [Fact]
1403         public async Task UserStreams_Test()
1404         {
1405             using (var twitterApi = new TwitterApi())
1406             {
1407                 var mock = new Mock<IApiConnection>();
1408                 mock.Setup(x =>
1409                     x.GetStreamingStreamAsync(
1410                         new Uri("https://userstream.twitter.com/1.1/user.json", UriKind.Absolute),
1411                         new Dictionary<string, string> {
1412                             { "replies", "all" },
1413                             { "track", "OpenTween" },
1414                         })
1415                 )
1416                 .ReturnsAsync(new MemoryStream());
1417
1418                 twitterApi.apiConnection = mock.Object;
1419
1420                 var stream = await twitterApi.UserStreams(replies: "all", track: "OpenTween")
1421                     .ConfigureAwait(false);
1422
1423                 stream.Dispose();
1424
1425                 mock.VerifyAll();
1426             }
1427         }
1428
1429         [Theory]
1430         [InlineData("", "")]
1431         [InlineData("123ABCabc", "123ABCabc")]
1432         [InlineData(@"\", @"\\")]
1433         [InlineData("\"", "\\\"")]
1434         [InlineData("\n", @"\u000A")]
1435         [InlineData("\U0001D11E", @"\uD834\uDD1E")]
1436         public void EscapeJsonString_Test(string targetText, string expectedText)
1437         {
1438             Assert.Equal(expectedText, TwitterApi.EscapeJsonString(targetText));
1439         }
1440     }
1441 }