}
[Fact]
+ public async Task MediaMetadataCreate_Test()
+ {
+ using (var twitterApi = new TwitterApi())
+ {
+ var mock = new Mock<IApiConnection>();
+ mock.Setup(x =>
+ x.PostJsonAsync(
+ 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));
+
+ twitterApi.apiConnection = mock.Object;
+
+ await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge")
+ .ConfigureAwait(false);
+
+ mock.VerifyAll();
+ }
+ }
+
+ [Fact]
public async Task UserStreams_Test()
{
using (var twitterApi = new TwitterApi())
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));
+ }
}
}
Assert.Equal(0, mockHandler.QueueCount);
}
}
+
+ [Fact]
+ public async Task PostJsonAsync_Test()
+ {
+ using (var mockHandler = new HttpMessageHandlerMock())
+ using (var http = new HttpClient(mockHandler))
+ using (var apiConnection = new TwitterApiConnection("", ""))
+ {
+ apiConnection.http = http;
+
+ mockHandler.Enqueue(async x =>
+ {
+ Assert.Equal(HttpMethod.Post, x.Method);
+ Assert.Equal("https://api.twitter.com/1.1/hoge/tetete.json",
+ x.RequestUri.AbsoluteUri);
+
+ Assert.Equal("application/json; charset=utf-8", x.Content.Headers.ContentType.ToString());
+
+ var body = await x.Content.ReadAsStringAsync()
+ .ConfigureAwait(false);
+
+ Assert.Equal("{\"aaaa\": 1111}", body);
+
+ return new HttpResponseMessage(HttpStatusCode.OK)
+ {
+ Content = new StringContent("\"hogehoge\""),
+ };
+ });
+
+ var endpoint = new Uri("hoge/tetete.json", UriKind.Relative);
+
+ await apiConnection.PostJsonAsync(endpoint, "{\"aaaa\": 1111}")
+ .ConfigureAwait(false);
+
+ Assert.Equal(0, mockHandler.QueueCount);
+ }
+ }
}
}
return this.apiConnection.PostLazyAsync<TwitterUploadMediaResult>(endpoint, null, paramMedia);
}
+ public Task MediaMetadataCreate(long mediaId, string altText)
+ {
+ var endpoint = new Uri("https://upload.twitter.com/1.1/media/metadata/create.json");
+
+ var escapedAltText = EscapeJsonString(altText);
+ var json = $@"{{""media_id"": ""{mediaId}"", ""alt_text"": {{""text"": ""{escapedAltText}""}}}}";
+
+ return this.apiConnection.PostJsonAsync(endpoint, json);
+ }
+
public Task<Stream> UserStreams(string replies = null, string track = null)
{
var endpoint = new Uri("https://userstream.twitter.com/1.1/user.json");
{
this.apiConnection?.Dispose();
}
+
+ /// <summary>JSON に出力する文字列を ECMA-404 に従ってエスケープする</summary>
+ public static string EscapeJsonString(string rawText)
+ {
+ var builder = new StringBuilder(rawText.Length + 20);
+
+ foreach (var c in rawText)
+ {
+ if (c <= 0x1F || char.IsSurrogate(c))
+ builder.AppendFormat(@"\u{0:X4}", (int)c);
+ else if (c == '\\' || c == '\"')
+ builder.Append('\\').Append(c);
+ else
+ builder.Append(c);
+ }
+
+ return builder.ToString();
+ }
}
}
Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string> param);
Task<LazyJson<T>> PostLazyAsync<T>(Uri uri, IDictionary<string, string> param, IDictionary<string, IMediaItem> media);
+
+ Task PostJsonAsync(Uri uri, string json);
}
}
}
}
+ public async Task PostJsonAsync(Uri uri, string json)
+ {
+ var requestUri = new Uri(RestApiBase, uri);
+ var request = new HttpRequestMessage(HttpMethod.Post, requestUri);
+
+ using (var postContent = new StringContent(json, Encoding.UTF8, "application/json"))
+ {
+ request.Content = postContent;
+
+ try
+ {
+ using (var response = await this.http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead)
+ .ConfigureAwait(false))
+ {
+ await this.CheckStatusCode(response)
+ .ConfigureAwait(false);
+ }
+ }
+ catch (HttpRequestException ex)
+ {
+ throw TwitterApiException.CreateFromException(ex);
+ }
+ catch (OperationCanceledException ex)
+ {
+ throw TwitterApiException.CreateFromException(ex);
+ }
+ }
+ }
+
protected async Task CheckStatusCode(HttpResponseMessage response)
{
var statusCode = response.StatusCode;