this.MyCommonSetup();
}
- public void MyCommonSetup()
+ private void MyCommonSetup()
{
var mockAssembly = new Mock<_Assembly>();
mockAssembly.Setup(m => m.GetName()).Returns(new AssemblyName("OpenTween"));
new Dictionary<string, string> {
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
{ "count", "200" },
{ "max_id", "900" },
{ "since_id", "100" },
},
"/statuses/home_timeline")
)
- .ReturnsAsync(new TwitterStatus[0]);
+ .ReturnsAsync(Array.Empty<TwitterStatus>());
twitterApi.apiConnection = mock.Object;
new Dictionary<string, string> {
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
{ "count", "200" },
{ "max_id", "900" },
{ "since_id", "100" },
},
"/statuses/mentions_timeline")
)
- .ReturnsAsync(new TwitterStatus[0]);
+ .ReturnsAsync(Array.Empty<TwitterStatus>());
twitterApi.apiConnection = mock.Object;
{ "include_rts", "true" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
{ "count", "200" },
{ "max_id", "900" },
{ "since_id", "100" },
},
"/statuses/user_timeline")
)
- .ReturnsAsync(new TwitterStatus[0]);
+ .ReturnsAsync(Array.Empty<TwitterStatus>());
twitterApi.apiConnection = mock.Object;
{ "id", "100" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
},
"/statuses/show/:id")
)
{ "status", "hogehoge" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
{ "in_reply_to_status_id", "100" },
{ "media_ids", "10,20" },
+ { "auto_populate_reply_metadata", "true" },
+ { "exclude_reply_user_ids", "100,200" },
+ { "attachment_url", "https://twitter.com/twitterapi/status/22634515958" },
})
)
.ReturnsAsync(LazyJson.Create(new TwitterStatus()));
twitterApi.apiConnection = mock.Object;
- await twitterApi.StatusesUpdate("hogehoge", replyToId: 100L, mediaIds: new[] { 10L, 20L })
+ await twitterApi.StatusesUpdate("hogehoge", replyToId: 100L, mediaIds: new[] { 10L, 20L },
+ autoPopulateReplyMetadata: true, excludeReplyUserIds: new[] { 100L, 200L },
+ attachmentUrl: "https://twitter.com/twitterapi/status/22634515958")
+ .IgnoreResponse()
+ .ConfigureAwait(false);
+
+ mock.VerifyAll();
+ }
+ }
+
+ [Fact]
+ public async Task StatusesUpdate_ExcludeReplyUserIdsEmptyTest()
+ {
+ using (var twitterApi = new TwitterApi())
+ {
+ var mock = new Mock<IApiConnection>();
+ mock.Setup(x =>
+ x.PostLazyAsync<TwitterStatus>(
+ new Uri("statuses/update.json", UriKind.Relative),
+ new Dictionary<string, string> {
+ { "status", "hogehoge" },
+ { "include_entities", "true" },
+ { "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
+ // exclude_reply_user_ids は空の場合には送信されない
+ })
+ )
+ .ReturnsAsync(LazyJson.Create(new TwitterStatus()));
+
+ twitterApi.apiConnection = mock.Object;
+
+ await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: Array.Empty<long>())
.IgnoreResponse()
.ConfigureAwait(false);
{ "id", "100" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
})
)
.ReturnsAsync(LazyJson.Create(new TwitterStatus()));
{ "result_type", "recent" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
{ "lang", "en" },
{ "count", "200" },
{ "max_id", "900" },
{ "list_id", "12345" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
{ "count", "200" },
{ "max_id", "900" },
{ "since_id", "100" },
},
"/lists/statuses")
)
- .ReturnsAsync(new TwitterStatus[0]);
+ .ReturnsAsync(Array.Empty<TwitterStatus>());
twitterApi.apiConnection = mock.Object;
{ "list_id", "12345" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
{ "cursor", "-1" },
},
"/lists/members")
{ "screen_name", "twitterapi" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
},
"/lists/members/show")
)
{ "screen_name", "twitterapi" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
})
)
.ReturnsAsync(LazyJson.Create(new TwitterUser()));
{ "screen_name", "twitterapi" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
})
)
.ReturnsAsync(LazyJson.Create(new TwitterUser()));
}
[Fact]
- public async Task DirectMessagesRecv_Test()
+ public async Task DirectMessagesEventsList_Test()
{
using (var twitterApi = new TwitterApi())
{
var mock = new Mock<IApiConnection>();
mock.Setup(x =>
- x.GetAsync<TwitterDirectMessage[]>(
- new Uri("direct_messages.json", UriKind.Relative),
+ x.GetAsync<TwitterMessageEventList>(
+ new Uri("direct_messages/events/list.json", UriKind.Relative),
new Dictionary<string, string> {
- { "full_text", "true" },
- { "include_entities", "true" },
- { "include_ext_alt_text", "true" },
- { "count", "200" },
- { "max_id", "900" },
- { "since_id", "100" },
+ { "count", "50" },
+ { "cursor", "12345abcdefg" },
},
- "/direct_messages")
+ "/direct_messages/events/list")
)
- .ReturnsAsync(new TwitterDirectMessage[0]);
+ .ReturnsAsync(new TwitterMessageEventList());
twitterApi.apiConnection = mock.Object;
- await twitterApi.DirectMessagesRecv(count: 200, maxId: 900L, sinceId: 100L)
+ await twitterApi.DirectMessagesEventsList(count: 50, cursor: "12345abcdefg")
.ConfigureAwait(false);
mock.VerifyAll();
}
[Fact]
- public async Task DirectMessagesSent_Test()
+ public async Task DirectMessagesEventsNew_Test()
{
using (var twitterApi = new TwitterApi())
{
var mock = new Mock<IApiConnection>();
mock.Setup(x =>
- x.GetAsync<TwitterDirectMessage[]>(
- new Uri("direct_messages/sent.json", UriKind.Relative),
- new Dictionary<string, string> {
- { "full_text", "true" },
- { "include_entities", "true" },
- { "include_ext_alt_text", "true" },
- { "count", "200" },
- { "max_id", "900" },
- { "since_id", "100" },
- },
- "/direct_messages/sent")
+ x.PostJsonAsync<TwitterMessageEventSingle>(
+ new Uri("direct_messages/events/new.json", UriKind.Relative),
+ @"{
+ ""event"": {
+ ""type"": ""message_create"",
+ ""message_create"": {
+ ""target"": {
+ ""recipient_id"": ""12345""
+ },
+ ""message_data"": {
+ ""text"": ""hogehoge"",
+ ""attachment"": {
+ ""type"": ""media"",
+ ""media"": {
+ ""id"": ""67890""
+ }
+ }
+ }
+ }
+ }
+}")
)
- .ReturnsAsync(new TwitterDirectMessage[0]);
+ .ReturnsAsync(LazyJson.Create(new TwitterMessageEventSingle()));
twitterApi.apiConnection = mock.Object;
- await twitterApi.DirectMessagesSent(count: 200, maxId: 900L, sinceId: 100L)
+ await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge", mediaId: 67890L)
.ConfigureAwait(false);
mock.VerifyAll();
}
[Fact]
- public async Task DirectMessagesNew_Test()
+ public async Task DirectMessagesEventsDestroy_Test()
{
using (var twitterApi = new TwitterApi())
{
var mock = new Mock<IApiConnection>();
mock.Setup(x =>
- x.PostLazyAsync<TwitterDirectMessage>(
- new Uri("direct_messages/new.json", UriKind.Relative),
- new Dictionary<string, string> {
- { "text", "hogehoge" },
- { "screen_name", "opentween" },
- })
+ x.DeleteAsync(
+ new Uri("direct_messages/events/destroy.json?id=100", UriKind.Relative))
)
- .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage()));
+ .Returns(Task.CompletedTask);
twitterApi.apiConnection = mock.Object;
- await twitterApi.DirectMessagesNew("hogehoge", "opentween")
- .IgnoreResponse()
+ await twitterApi.DirectMessagesEventsDestroy(eventId: "100")
.ConfigureAwait(false);
mock.VerifyAll();
}
[Fact]
- public async Task DirectMessagesDestroy_Test()
+ public async Task UsersShow_Test()
{
using (var twitterApi = new TwitterApi())
{
var mock = new Mock<IApiConnection>();
mock.Setup(x =>
- x.PostLazyAsync<TwitterDirectMessage>(
- new Uri("direct_messages/destroy.json", UriKind.Relative),
- new Dictionary<string, string> { { "id", "100" } })
+ x.GetAsync<TwitterUser>(
+ new Uri("users/show.json", UriKind.Relative),
+ new Dictionary<string, string> {
+ { "screen_name", "twitterapi" },
+ { "include_entities", "true" },
+ { "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
+ },
+ "/users/show/:id")
)
- .ReturnsAsync(LazyJson.Create(new TwitterDirectMessage { Id = 100L }));
+ .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
twitterApi.apiConnection = mock.Object;
- await twitterApi.DirectMessagesDestroy(statusId: 100L)
- .IgnoreResponse()
+ await twitterApi.UsersShow(screenName: "twitterapi")
.ConfigureAwait(false);
mock.VerifyAll();
}
[Fact]
- public async Task UsersShow_Test()
+ public async Task UsersLookup_Test()
{
using (var twitterApi = new TwitterApi())
{
var mock = new Mock<IApiConnection>();
mock.Setup(x =>
- x.GetAsync<TwitterUser>(
- new Uri("users/show.json", UriKind.Relative),
+ x.GetAsync<TwitterUser[]>(
+ new Uri("users/lookup.json", UriKind.Relative),
new Dictionary<string, string> {
- { "screen_name", "twitterapi" },
+ { "user_id", "11111,22222" },
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
},
- "/users/show/:id")
+ "/users/lookup")
)
- .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" });
+ .ReturnsAsync(Array.Empty<TwitterUser>());
twitterApi.apiConnection = mock.Object;
- await twitterApi.UsersShow(screenName: "twitterapi")
+ await twitterApi.UsersLookup(userIds: new[] { "11111", "22222" })
.ConfigureAwait(false);
mock.VerifyAll();
mock.Setup(x =>
x.PostLazyAsync<TwitterUser>(
new Uri("users/report_spam.json", UriKind.Relative),
- new Dictionary<string, string> { { "screen_name", "twitterapi" } })
+ new Dictionary<string, string> {
+ { "screen_name", "twitterapi" },
+ { "tweet_mode", "extended" },
+ })
)
.ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" }));
new Dictionary<string, string> {
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
{ "count", "200" },
{ "max_id", "900" },
{ "since_id", "100" },
},
"/favorites/list")
)
- .ReturnsAsync(new TwitterStatus[0]);
+ .ReturnsAsync(Array.Empty<TwitterStatus>());
twitterApi.apiConnection = mock.Object;
mock.Setup(x =>
x.PostLazyAsync<TwitterStatus>(
new Uri("favorites/create.json", UriKind.Relative),
- new Dictionary<string, string> { { "id", "100" } })
+ new Dictionary<string, string> {
+ { "id", "100" },
+ { "tweet_mode", "extended" },
+ })
)
.ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
mock.Setup(x =>
x.PostLazyAsync<TwitterStatus>(
new Uri("favorites/destroy.json", UriKind.Relative),
- new Dictionary<string, string> { { "id", "100" } })
+ new Dictionary<string, string> {
+ { "id", "100" },
+ { "tweet_mode", "extended" },
+ })
)
.ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L }));
null,
"/friendships/no_retweets/ids")
)
- .ReturnsAsync(new long[0]);
+ .ReturnsAsync(Array.Empty<long>());
twitterApi.apiConnection = mock.Object;
mock.Setup(x =>
x.PostLazyAsync<TwitterUser>(
new Uri("blocks/create.json", UriKind.Relative),
- new Dictionary<string, string> { { "screen_name", "twitterapi" } })
+ new Dictionary<string, string> {
+ { "screen_name", "twitterapi" },
+ { "tweet_mode", "extended" },
+ })
)
.ReturnsAsync(LazyJson.Create(new TwitterUser()));
mock.Setup(x =>
x.PostLazyAsync<TwitterUser>(
new Uri("blocks/destroy.json", UriKind.Relative),
- new Dictionary<string, string> { { "screen_name", "twitterapi" } })
+ new Dictionary<string, string> {
+ { "screen_name", "twitterapi" },
+ { "tweet_mode", "extended" },
+ })
)
.ReturnsAsync(LazyJson.Create(new TwitterUser()));
new Dictionary<string, string> {
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
},
"/account/verify_credentials")
)
new Dictionary<string, string> {
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
{ "name", "Name" },
{ "url", "http://example.com/" },
{ "location", "Location" },
new Dictionary<string, string> {
{ "include_entities", "true" },
{ "include_ext_alt_text", "true" },
+ { "tweet_mode", "extended" },
},
new Dictionary<string, IMediaItem> { { "image", media } })
)
}
[Fact]
- public async Task MediaUpload_Test()
+ public async Task MediaUploadInit_Test()
+ {
+ using (var twitterApi = new TwitterApi())
+ {
+ var mock = new Mock<IApiConnection>();
+ mock.Setup(x =>
+ x.PostLazyAsync<TwitterUploadMediaInit>(
+ new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
+ new Dictionary<string, string> {
+ { "command", "INIT" },
+ { "total_bytes", "123456" },
+ { "media_type", "image/png" },
+ { "media_category", "dm_image" },
+ })
+ )
+ .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaInit()));
+
+ twitterApi.apiConnection = mock.Object;
+
+ await twitterApi.MediaUploadInit(totalBytes: 123456L, mediaType: "image/png", mediaCategory: "dm_image")
+ .IgnoreResponse()
+ .ConfigureAwait(false);
+
+ mock.VerifyAll();
+ }
+ }
+
+ [Fact]
+ public async Task MediaUploadAppend_Test()
{
using (var twitterApi = new TwitterApi())
using (var image = TestUtils.CreateDummyImage())
{
var mock = new Mock<IApiConnection>();
mock.Setup(x =>
- x.PostLazyAsync<TwitterUploadMediaResult>(
+ x.PostAsync(
new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
- null,
+ new Dictionary<string, string> {
+ { "command", "APPEND" },
+ { "media_id", "11111" },
+ { "segment_index", "1" },
+ },
new Dictionary<string, IMediaItem> { { "media", media } })
)
+ .Returns(Task.CompletedTask);
+
+ twitterApi.apiConnection = mock.Object;
+
+ await twitterApi.MediaUploadAppend(mediaId: 11111L, segmentIndex: 1, media: media)
+ .ConfigureAwait(false);
+
+ mock.VerifyAll();
+ }
+ }
+
+ [Fact]
+ public async Task MediaUploadFinalize_Test()
+ {
+ using (var twitterApi = new TwitterApi())
+ {
+ var mock = new Mock<IApiConnection>();
+ mock.Setup(x =>
+ x.PostLazyAsync<TwitterUploadMediaResult>(
+ new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
+ new Dictionary<string, string> {
+ { "command", "FINALIZE" },
+ { "media_id", "11111" },
+ })
+ )
.ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult()));
twitterApi.apiConnection = mock.Object;
- await twitterApi.MediaUpload(media)
+ await twitterApi.MediaUploadFinalize(mediaId: 11111L)
.IgnoreResponse()
.ConfigureAwait(false);
}
[Fact]
+ public async Task MediaUploadStatus_Test()
+ {
+ using (var twitterApi = new TwitterApi())
+ {
+ var mock = new Mock<IApiConnection>();
+ mock.Setup(x =>
+ x.GetAsync<TwitterUploadMediaResult>(
+ new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute),
+ new Dictionary<string, string> {
+ { "command", "STATUS" },
+ { "media_id", "11111" },
+ },
+ null)
+ )
+ .ReturnsAsync(new TwitterUploadMediaResult());
+
+ twitterApi.apiConnection = mock.Object;
+
+ await twitterApi.MediaUploadStatus(mediaId: 11111L)
+ .ConfigureAwait(false);
+
+ mock.VerifyAll();
+ }
+ }
+
+ [Fact]
public async Task MediaMetadataCreate_Test()
{
using (var twitterApi = new TwitterApi())
new Uri("https://upload.twitter.com/1.1/media/metadata/create.json", UriKind.Absolute),
"{\"media_id\": \"12345\", \"alt_text\": {\"text\": \"hogehoge\"}}")
)
- .Returns(Task.FromResult(0));
+ .Returns(Task.CompletedTask);
twitterApi.apiConnection = mock.Object;
twitterApi.apiConnection = mock.Object;
- var stream = await twitterApi.UserStreams(replies: "all", track: "OpenTween")
- .ConfigureAwait(false);
-
- stream.Dispose();
+ var observable = twitterApi.UserStreams(replies: "all", track: "OpenTween");
+ await observable.ForEachAsync(x => { });
mock.VerifyAll();
}
}
-
- [Theory]
- [InlineData("", "")]
- [InlineData("123ABCabc", "123ABCabc")]
- [InlineData(@"\", @"\\")]
- [InlineData("\"", "\\\"")]
- [InlineData("\n", @"\u000A")]
- [InlineData("\U0001D11E", @"\uD834\uDD1E")]
- public void EscapeJsonString_Test(string targetText, string expectedText)
- {
- Assert.Equal(expectedText, TwitterApi.EscapeJsonString(targetText));
- }
}
}