OSDN Git Service

式形式のメソッドを使用する (IDE0021, IDE0022, IDE0025, IDE0053)
[opentween/open-tween.git] / OpenTween.Tests / TweetThumbnailTest.cs
1 // OpenTween - Client of Twitter
2 // Copyright (c) 2012 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.RegularExpressions;
30 using System.Threading;
31 using System.Threading.Tasks;
32 using System.Windows.Forms;
33 using Moq;
34 using OpenTween.Models;
35 using OpenTween.Thumbnail;
36 using OpenTween.Thumbnail.Services;
37 using Xunit;
38 using Xunit.Extensions;
39
40 namespace OpenTween
41 {
42     public class TweetThumbnailTest
43     {
44         class TestThumbnailService : IThumbnailService
45         {
46             private readonly Regex regex;
47             private readonly string replaceUrl;
48             private readonly string replaceTooltip;
49
50             public TestThumbnailService(string pattern, string replaceUrl, string replaceTooltip)
51             {
52                 this.regex = new Regex(pattern);
53                 this.replaceUrl = replaceUrl;
54                 this.replaceTooltip = replaceTooltip;
55             }
56
57             public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
58             {
59                 var match = this.regex.Match(url);
60
61                 if (!match.Success) return null;
62
63                 if (url.StartsWith("http://slow.example.com/", StringComparison.Ordinal))
64                     await Task.Delay(1000, token).ConfigureAwait(false);
65
66                 return new MockThumbnailInfo
67                 {
68                     MediaPageUrl = url,
69                     ThumbnailImageUrl = match.Result(this.replaceUrl),
70                     TooltipText = this.replaceTooltip != null ? match.Result(this.replaceTooltip) : null,
71                 };
72             }
73
74             class MockThumbnailInfo : ThumbnailInfo
75             {
76                 public override Task<MemoryImage> LoadThumbnailImageAsync(HttpClient http, CancellationToken cancellationToken)
77                     => Task.FromResult(TestUtils.CreateDummyImage());
78             }
79         }
80
81         public TweetThumbnailTest()
82         {
83             this.ThumbnailGeneratorSetup();
84             this.MyCommonSetup();
85         }
86
87         private void ThumbnailGeneratorSetup()
88         {
89             ThumbnailGenerator.Services.Clear();
90             ThumbnailGenerator.Services.AddRange(new[]
91             {
92                 new TestThumbnailService(@"^https?://foo.example.com/(.+)$", @"http://img.example.com/${1}.png", null),
93                 new TestThumbnailService(@"^https?://bar.example.com/(.+)$", @"http://img.example.com/${1}.png", @"${1}"),
94                 new TestThumbnailService(@"^https?://slow.example.com/(.+)$", @"http://img.example.com/${1}.png", null),
95             });
96         }
97
98         private void MyCommonSetup()
99         {
100             var mockAssembly = new Mock<_Assembly>();
101             mockAssembly.Setup(m => m.GetName()).Returns(new AssemblyName("OpenTween"));
102
103             MyCommon.EntryAssembly = mockAssembly.Object;
104         }
105
106         [Fact]
107         public void CreatePictureBoxTest()
108         {
109             using (var thumbBox = new TweetThumbnail())
110             {
111                 var method = typeof(TweetThumbnail).GetMethod("CreatePictureBox", BindingFlags.Instance | BindingFlags.NonPublic);
112                 var picbox = method.Invoke(thumbBox, new[] { "pictureBox1" }) as PictureBox;
113
114                 Assert.NotNull(picbox);
115                 Assert.Equal("pictureBox1", picbox.Name);
116                 Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode);
117                 Assert.False(picbox.WaitOnLoad);
118                 Assert.Equal(DockStyle.Fill, picbox.Dock);
119
120                 picbox.Dispose();
121             }
122         }
123
124         [Fact]
125         public async Task CancelAsyncTest()
126         {
127             var post = new PostClass
128             {
129                 TextFromApi = "てすと http://slow.example.com/abcd",
130                 Media = new List<MediaInfo>
131                 {
132                     new MediaInfo("http://slow.example.com/abcd"),
133                 },
134             };
135
136             using (var thumbbox = new TweetThumbnail())
137             using (var tokenSource = new CancellationTokenSource())
138             {
139                 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
140                 var task = thumbbox.ShowThumbnailAsync(post, tokenSource.Token);
141
142                 tokenSource.Cancel();
143
144                 await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await task);
145                 Assert.True(task.IsCanceled);
146             }
147         }
148
149         [Theory]
150         [InlineData(0)]
151         [InlineData(1)]
152         [InlineData(2)]
153         public void SetThumbnailCountTest(int count)
154         {
155             using (var thumbbox = new TweetThumbnail())
156             {
157                 var method = typeof(TweetThumbnail).GetMethod("SetThumbnailCount", BindingFlags.Instance | BindingFlags.NonPublic);
158                 method.Invoke(thumbbox, new[] { (object)count });
159
160                 Assert.Equal(count, thumbbox.pictureBox.Count);
161
162                 var num = 0;
163                 foreach (var picbox in thumbbox.pictureBox)
164                 {
165                     Assert.Equal("pictureBox" + num, picbox.Name);
166                     num++;
167                 }
168
169                 Assert.Equal(thumbbox.pictureBox, thumbbox.panelPictureBox.Controls.Cast<OTPictureBox>());
170
171                 Assert.Equal(0, thumbbox.scrollBar.Minimum);
172
173                 if (count == 0)
174                     Assert.Equal(0, thumbbox.scrollBar.Maximum);
175                 else
176                     Assert.Equal(count - 1, thumbbox.scrollBar.Maximum);
177             }
178         }
179
180         [Fact]
181         public async Task ShowThumbnailAsyncTest()
182         {
183             var post = new PostClass
184             {
185                 TextFromApi = "てすと http://foo.example.com/abcd",
186                 Media = new List<MediaInfo>
187                 {
188                     new MediaInfo("http://foo.example.com/abcd"),
189                 },
190             };
191
192             using (var thumbbox = new TweetThumbnail())
193             {
194                 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
195                 await thumbbox.ShowThumbnailAsync(post);
196
197                 Assert.Equal(0, thumbbox.scrollBar.Maximum);
198                 Assert.False(thumbbox.scrollBar.Enabled);
199
200                 Assert.Single(thumbbox.pictureBox);
201                 Assert.NotNull(thumbbox.pictureBox[0].Image);
202
203                 Assert.IsAssignableFrom<ThumbnailInfo>(thumbbox.pictureBox[0].Tag);
204                 var thumbinfo = (ThumbnailInfo)thumbbox.pictureBox[0].Tag;
205
206                 Assert.Equal("http://foo.example.com/abcd", thumbinfo.MediaPageUrl);
207                 Assert.Equal("http://img.example.com/abcd.png", thumbinfo.ThumbnailImageUrl);
208
209                 Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.pictureBox[0]));
210             }
211         }
212
213         [Fact]
214         public async Task ShowThumbnailAsyncTest2()
215         {
216             var post = new PostClass
217             {
218                 TextFromApi = "てすと http://foo.example.com/abcd http://bar.example.com/efgh",
219                 Media = new List<MediaInfo>
220                 {
221                     new MediaInfo("http://foo.example.com/abcd"),
222                     new MediaInfo("http://bar.example.com/efgh"),
223                 },
224             };
225
226             using (var thumbbox = new TweetThumbnail())
227             {
228                 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
229                 await thumbbox.ShowThumbnailAsync(post);
230
231                 Assert.Equal(1, thumbbox.scrollBar.Maximum);
232                 Assert.True(thumbbox.scrollBar.Enabled);
233
234                 Assert.Equal(2, thumbbox.pictureBox.Count);
235                 Assert.NotNull(thumbbox.pictureBox[0].Image);
236                 Assert.NotNull(thumbbox.pictureBox[1].Image);
237
238                 Assert.IsAssignableFrom<ThumbnailInfo>(thumbbox.pictureBox[0].Tag);
239                 var thumbinfo = (ThumbnailInfo)thumbbox.pictureBox[0].Tag;
240
241                 Assert.Equal("http://foo.example.com/abcd", thumbinfo.MediaPageUrl);
242                 Assert.Equal("http://img.example.com/abcd.png", thumbinfo.ThumbnailImageUrl);
243
244                 Assert.IsAssignableFrom<ThumbnailInfo>(thumbbox.pictureBox[1].Tag);
245                 thumbinfo = (ThumbnailInfo)thumbbox.pictureBox[1].Tag;
246
247                 Assert.Equal("http://bar.example.com/efgh", thumbinfo.MediaPageUrl);
248                 Assert.Equal("http://img.example.com/efgh.png", thumbinfo.ThumbnailImageUrl);
249
250                 Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.pictureBox[0]));
251                 Assert.Equal("efgh", thumbbox.toolTip.GetToolTip(thumbbox.pictureBox[1]));
252             }
253         }
254
255         [Fact]
256         public async Task ThumbnailLoadingEventTest()
257         {
258             using (var thumbbox = new TweetThumbnail())
259             {
260                 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
261
262                 var post = new PostClass
263                 {
264                     TextFromApi = "てすと",
265                     Media = new List<MediaInfo>
266                     {
267                     },
268                 };
269                 await TestUtils.NotRaisesAsync<EventArgs>(
270                     x => thumbbox.ThumbnailLoading += x,
271                     x => thumbbox.ThumbnailLoading -= x,
272                     () => thumbbox.ShowThumbnailAsync(post)
273                 );
274
275                 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
276
277                 var post2 = new PostClass
278                 {
279                     TextFromApi = "てすと http://foo.example.com/abcd",
280                     Media = new List<MediaInfo>
281                     {
282                         new MediaInfo("http://foo.example.com/abcd"),
283                     },
284                 };
285
286                 await Assert.RaisesAsync<EventArgs>(
287                     x => thumbbox.ThumbnailLoading += x,
288                     x => thumbbox.ThumbnailLoading -= x,
289                     () => thumbbox.ShowThumbnailAsync(post2)
290                 );
291             }
292         }
293
294         [Fact]
295         public async Task ScrollTest()
296         {
297             var post = new PostClass
298             {
299                 TextFromApi = "てすと http://foo.example.com/abcd http://foo.example.com/efgh",
300                 Media = new List<MediaInfo>
301                 {
302                     new MediaInfo("http://foo.example.com/abcd"),
303                     new MediaInfo("http://foo.example.com/efgh"),
304                 },
305             };
306
307             using (var thumbbox = new TweetThumbnail())
308             {
309                 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
310                 await thumbbox.ShowThumbnailAsync(post);
311
312                 Assert.Equal(0, thumbbox.scrollBar.Minimum);
313                 Assert.Equal(1, thumbbox.scrollBar.Maximum);
314
315                 thumbbox.scrollBar.Value = 0;
316
317                 thumbbox.ScrollDown();
318                 Assert.Equal(1, thumbbox.scrollBar.Value);
319                 Assert.False(thumbbox.pictureBox[0].Visible);
320                 Assert.True(thumbbox.pictureBox[1].Visible);
321
322                 thumbbox.ScrollDown();
323                 Assert.Equal(1, thumbbox.scrollBar.Value);
324                 Assert.False(thumbbox.pictureBox[0].Visible);
325                 Assert.True(thumbbox.pictureBox[1].Visible);
326
327                 thumbbox.ScrollUp();
328                 Assert.Equal(0, thumbbox.scrollBar.Value);
329                 Assert.True(thumbbox.pictureBox[0].Visible);
330                 Assert.False(thumbbox.pictureBox[1].Visible);
331
332                 thumbbox.ScrollUp();
333                 Assert.Equal(0, thumbbox.scrollBar.Value);
334                 Assert.True(thumbbox.pictureBox[0].Visible);
335                 Assert.False(thumbbox.pictureBox[1].Visible);
336             }
337         }
338     }
339 }