From: Kimura Youichi Date: Fri, 8 Dec 2023 19:43:44 +0000 (+0900) Subject: ton.twitter.com のサムネイル画像の取得に新しいIApiConnectionを使用する X-Git-Tag: OpenTween_v3.10.0^2~10^2 X-Git-Url: http://git.osdn.net/view?p=opentween%2Fopen-tween.git;a=commitdiff_plain;h=c3e2600c9804f0b24072341508a10aabc3cdbcd4 ton.twitter.com のサムネイル画像の取得に新しいIApiConnectionを使用する --- diff --git a/OpenTween.Tests/Thumbnail/Services/TonTwitterComTest.cs b/OpenTween.Tests/Thumbnail/Services/TonTwitterComTest.cs new file mode 100644 index 00000000..235c9c82 --- /dev/null +++ b/OpenTween.Tests/Thumbnail/Services/TonTwitterComTest.cs @@ -0,0 +1,135 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2023 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Moq; +using OpenTween.Connection; +using Xunit; + +namespace OpenTween.Thumbnail.Services +{ + public class TonTwitterComTest + { + [Fact] + public async Task GetThumbnailInfoAsync_Test() + { + var mock = new Mock(); + TonTwitterCom.GetApiConnection = () => mock.Object; + + var service = new TonTwitterCom(); + var thumb = await service.GetThumbnailInfoAsync( + "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg", + new(), + CancellationToken.None + ); + + Assert.NotNull(thumb!); + Assert.Equal( + "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg:large", + thumb.MediaPageUrl + ); + Assert.Equal( + "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg:large", + thumb.FullSizeImageUrl + ); + Assert.Equal( + "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg", + thumb.ThumbnailImageUrl + ); + + TonTwitterCom.GetApiConnection = null; + } + + [Fact] + public async Task GetThumbnailInfoAsync_ApiConnectionIsNotSetTest() + { + TonTwitterCom.GetApiConnection = null; + + var service = new TonTwitterCom(); + var thumb = await service.GetThumbnailInfoAsync( + "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg", + new(), + CancellationToken.None + ); + + Assert.Null(thumb); + } + + [Fact] + public async Task GetThumbnailInfoAsync_NotMatchedTest() + { + var mock = new Mock(); + TonTwitterCom.GetApiConnection = () => mock.Object; + + var service = new TonTwitterCom(); + var thumb = await service.GetThumbnailInfoAsync( + "https://example.com/abcdef.jpg", + new(), + CancellationToken.None + ); + + Assert.Null(thumb); + + TonTwitterCom.GetApiConnection = null; + } + + [Fact] + public async Task LoadThumbnailImageAsync_Test() + { + using var image = TestUtils.CreateDummyImage(); + using var responseMessage = new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new ByteArrayContent(image.Stream.ToArray()), + }; + using var response = new ApiResponse(responseMessage); + + var mock = new Mock(); + mock.Setup( + x => x.SendAsync(It.IsAny()) + ) + .Callback(x => + { + var request = Assert.IsType(x); + Assert.Equal( + new("https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg"), + request.RequestUri + ); + }) + .ReturnsAsync(response); + + var apiConnection = mock.Object; + var thumb = new TonTwitterCom.Thumbnail(apiConnection) + { + MediaPageUrl = "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg:large", + FullSizeImageUrl = "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg:large", + ThumbnailImageUrl = "https://ton.twitter.com/1.1/ton/data/dm/123456/123456/abcdef.jpg", + }; + + var result = await thumb.LoadThumbnailImageAsync(CancellationToken.None); + Assert.Equal(image, result); + + mock.VerifyAll(); + } + } +} diff --git a/OpenTween/Thumbnail/Services/TonTwitterCom.cs b/OpenTween/Thumbnail/Services/TonTwitterCom.cs index b4284485..4e55b97f 100644 --- a/OpenTween/Thumbnail/Services/TonTwitterCom.cs +++ b/OpenTween/Thumbnail/Services/TonTwitterCom.cs @@ -40,7 +40,7 @@ namespace OpenTween.Thumbnail.Services /// public class TonTwitterCom : IThumbnailService { - internal static Func? GetApiConnection; + internal static Func? GetApiConnection; public override Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { @@ -53,8 +53,9 @@ namespace OpenTween.Thumbnail.Services return null; var largeUrl = url + ":large"; + var apiConnection = GetApiConnection(); - return new TonTwitterCom.Thumbnail + return new TonTwitterCom.Thumbnail(apiConnection) { MediaPageUrl = largeUrl, ThumbnailImageUrl = url, @@ -67,22 +68,31 @@ namespace OpenTween.Thumbnail.Services public class Thumbnail : ThumbnailInfo { + private readonly IApiConnection apiConnection; + + public Thumbnail(IApiConnection apiConnection) + => this.apiConnection = apiConnection; + public override Task LoadThumbnailImageAsync(HttpClient http, CancellationToken cancellationToken) { - return Task.Run( - async () => + return Task.Run(async () => + { + var request = new GetRequest { - var apiConnection = TonTwitterCom.GetApiConnection!(); + RequestUri = new(this.ThumbnailImageUrl), + }; + + using var response = await this.apiConnection.SendAsync(request) + .ConfigureAwait(false); - using var imageStream = await apiConnection.GetStreamAsync(new Uri(this.ThumbnailImageUrl), null) - .ConfigureAwait(false); + var imageBytes = await response.ReadAsBytes() + .ConfigureAwait(false); - cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); - return await MemoryImage.CopyFromStreamAsync(imageStream) - .ConfigureAwait(false); - }, - cancellationToken); + return MemoryImage.CopyFromBytes(imageBytes); + }, + cancellationToken); } } }