1 // OpenTween - Client of Twitter
2 // Copyright (c) 2012 kim_upsilon (@kim_upsilon) <https://upsilo.net/~upsilon/>
3 // All rights reserved.
5 // This file is part of OpenTween.
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)
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
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.
23 using System.Collections.Generic;
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;
34 using OpenTween.Models;
35 using OpenTween.Thumbnail;
36 using OpenTween.Thumbnail.Services;
38 using Xunit.Extensions;
42 public class TweetThumbnailTest
44 class TestThumbnailService : IThumbnailService
46 private readonly Regex regex;
47 private readonly string replaceUrl;
48 private readonly string replaceTooltip;
50 public TestThumbnailService(string pattern, string replaceUrl, string replaceTooltip)
52 this.regex = new Regex(pattern);
53 this.replaceUrl = replaceUrl;
54 this.replaceTooltip = replaceTooltip;
57 public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
59 var match = this.regex.Match(url);
61 if (!match.Success) return null;
63 if (url.StartsWith("http://slow.example.com/", StringComparison.Ordinal))
64 await Task.Delay(1000, token).ConfigureAwait(false);
66 return new MockThumbnailInfo
69 ThumbnailImageUrl = match.Result(this.replaceUrl),
70 TooltipText = this.replaceTooltip != null ? match.Result(this.replaceTooltip) : null,
74 class MockThumbnailInfo : ThumbnailInfo
76 public override Task<MemoryImage> LoadThumbnailImageAsync(HttpClient http, CancellationToken cancellationToken)
78 return Task.FromResult(TestUtils.CreateDummyImage());
83 public TweetThumbnailTest()
85 this.ThumbnailGeneratorSetup();
89 private void ThumbnailGeneratorSetup()
91 ThumbnailGenerator.Services.Clear();
92 ThumbnailGenerator.Services.AddRange(new[]
94 new TestThumbnailService(@"^https?://foo.example.com/(.+)$", @"http://img.example.com/${1}.png", null),
95 new TestThumbnailService(@"^https?://bar.example.com/(.+)$", @"http://img.example.com/${1}.png", @"${1}"),
96 new TestThumbnailService(@"^https?://slow.example.com/(.+)$", @"http://img.example.com/${1}.png", null),
100 private void MyCommonSetup()
102 var mockAssembly = new Mock<_Assembly>();
103 mockAssembly.Setup(m => m.GetName()).Returns(new AssemblyName("OpenTween"));
105 MyCommon.EntryAssembly = mockAssembly.Object;
109 public void CreatePictureBoxTest()
111 using (var thumbBox = new TweetThumbnail())
113 var method = typeof(TweetThumbnail).GetMethod("CreatePictureBox", BindingFlags.Instance | BindingFlags.NonPublic);
114 var picbox = method.Invoke(thumbBox, new[] { "pictureBox1" }) as PictureBox;
116 Assert.NotNull(picbox);
117 Assert.Equal("pictureBox1", picbox.Name);
118 Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode);
119 Assert.False(picbox.WaitOnLoad);
120 Assert.Equal(DockStyle.Fill, picbox.Dock);
127 public async Task CancelAsyncTest()
129 var post = new PostClass
131 TextFromApi = "てすと http://slow.example.com/abcd",
132 Media = new List<MediaInfo>
134 new MediaInfo("http://slow.example.com/abcd"),
138 using (var thumbbox = new TweetThumbnail())
139 using (var tokenSource = new CancellationTokenSource())
141 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
142 var task = thumbbox.ShowThumbnailAsync(post, tokenSource.Token);
144 tokenSource.Cancel();
146 await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await task);
147 Assert.True(task.IsCanceled);
155 public void SetThumbnailCountTest(int count)
157 using (var thumbbox = new TweetThumbnail())
159 var method = typeof(TweetThumbnail).GetMethod("SetThumbnailCount", BindingFlags.Instance | BindingFlags.NonPublic);
160 method.Invoke(thumbbox, new[] { (object)count });
162 Assert.Equal(count, thumbbox.pictureBox.Count);
165 foreach (var picbox in thumbbox.pictureBox)
167 Assert.Equal("pictureBox" + num, picbox.Name);
171 Assert.Equal(thumbbox.pictureBox, thumbbox.panelPictureBox.Controls.Cast<OTPictureBox>());
173 Assert.Equal(0, thumbbox.scrollBar.Minimum);
176 Assert.Equal(0, thumbbox.scrollBar.Maximum);
178 Assert.Equal(count - 1, thumbbox.scrollBar.Maximum);
183 public async Task ShowThumbnailAsyncTest()
185 var post = new PostClass
187 TextFromApi = "てすと http://foo.example.com/abcd",
188 Media = new List<MediaInfo>
190 new MediaInfo("http://foo.example.com/abcd"),
194 using (var thumbbox = new TweetThumbnail())
196 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
197 await thumbbox.ShowThumbnailAsync(post);
199 Assert.Equal(0, thumbbox.scrollBar.Maximum);
200 Assert.False(thumbbox.scrollBar.Enabled);
202 Assert.Equal(1, thumbbox.pictureBox.Count);
203 Assert.NotNull(thumbbox.pictureBox[0].Image);
205 Assert.IsAssignableFrom<ThumbnailInfo>(thumbbox.pictureBox[0].Tag);
206 var thumbinfo = (ThumbnailInfo)thumbbox.pictureBox[0].Tag;
208 Assert.Equal("http://foo.example.com/abcd", thumbinfo.MediaPageUrl);
209 Assert.Equal("http://img.example.com/abcd.png", thumbinfo.ThumbnailImageUrl);
211 Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.pictureBox[0]));
216 public async Task ShowThumbnailAsyncTest2()
218 var post = new PostClass
220 TextFromApi = "てすと http://foo.example.com/abcd http://bar.example.com/efgh",
221 Media = new List<MediaInfo>
223 new MediaInfo("http://foo.example.com/abcd"),
224 new MediaInfo("http://bar.example.com/efgh"),
228 using (var thumbbox = new TweetThumbnail())
230 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
231 await thumbbox.ShowThumbnailAsync(post);
233 Assert.Equal(1, thumbbox.scrollBar.Maximum);
234 Assert.True(thumbbox.scrollBar.Enabled);
236 Assert.Equal(2, thumbbox.pictureBox.Count);
237 Assert.NotNull(thumbbox.pictureBox[0].Image);
238 Assert.NotNull(thumbbox.pictureBox[1].Image);
240 Assert.IsAssignableFrom<ThumbnailInfo>(thumbbox.pictureBox[0].Tag);
241 var thumbinfo = (ThumbnailInfo)thumbbox.pictureBox[0].Tag;
243 Assert.Equal("http://foo.example.com/abcd", thumbinfo.MediaPageUrl);
244 Assert.Equal("http://img.example.com/abcd.png", thumbinfo.ThumbnailImageUrl);
246 Assert.IsAssignableFrom<ThumbnailInfo>(thumbbox.pictureBox[1].Tag);
247 thumbinfo = (ThumbnailInfo)thumbbox.pictureBox[1].Tag;
249 Assert.Equal("http://bar.example.com/efgh", thumbinfo.MediaPageUrl);
250 Assert.Equal("http://img.example.com/efgh.png", thumbinfo.ThumbnailImageUrl);
252 Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.pictureBox[0]));
253 Assert.Equal("efgh", thumbbox.toolTip.GetToolTip(thumbbox.pictureBox[1]));
258 public async Task ThumbnailLoadingEventTest()
260 using (var thumbbox = new TweetThumbnail())
262 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
264 var post = new PostClass
267 Media = new List<MediaInfo>
271 await TestUtils.NotRaisesAsync<EventArgs>(
272 x => thumbbox.ThumbnailLoading += x,
273 x => thumbbox.ThumbnailLoading -= x,
274 () => thumbbox.ShowThumbnailAsync(post)
277 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
279 var post2 = new PostClass
281 TextFromApi = "てすと http://foo.example.com/abcd",
282 Media = new List<MediaInfo>
284 new MediaInfo("http://foo.example.com/abcd"),
288 await Assert.RaisesAsync<EventArgs>(
289 x => thumbbox.ThumbnailLoading += x,
290 x => thumbbox.ThumbnailLoading -= x,
291 () => thumbbox.ShowThumbnailAsync(post2)
297 public async Task ScrollTest()
299 var post = new PostClass
301 TextFromApi = "てすと http://foo.example.com/abcd http://foo.example.com/efgh",
302 Media = new List<MediaInfo>
304 new MediaInfo("http://foo.example.com/abcd"),
305 new MediaInfo("http://foo.example.com/efgh"),
309 using (var thumbbox = new TweetThumbnail())
311 SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
312 await thumbbox.ShowThumbnailAsync(post);
314 Assert.Equal(0, thumbbox.scrollBar.Minimum);
315 Assert.Equal(1, thumbbox.scrollBar.Maximum);
317 thumbbox.scrollBar.Value = 0;
319 thumbbox.ScrollDown();
320 Assert.Equal(1, thumbbox.scrollBar.Value);
321 Assert.False(thumbbox.pictureBox[0].Visible);
322 Assert.True(thumbbox.pictureBox[1].Visible);
324 thumbbox.ScrollDown();
325 Assert.Equal(1, thumbbox.scrollBar.Value);
326 Assert.False(thumbbox.pictureBox[0].Visible);
327 Assert.True(thumbbox.pictureBox[1].Visible);
330 Assert.Equal(0, thumbbox.scrollBar.Value);
331 Assert.True(thumbbox.pictureBox[0].Visible);
332 Assert.False(thumbbox.pictureBox[1].Visible);
335 Assert.Equal(0, thumbbox.scrollBar.Value);
336 Assert.True(thumbbox.pictureBox[0].Visible);
337 Assert.False(thumbbox.pictureBox[1].Visible);