OSDN Git Service

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