OSDN Git Service

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