OSDN Git Service

OpenTween v1.4.2 リリース
[opentween/open-tween.git] / OpenTween.Tests / TweetThumbnailTest.cs
index 255c386..4654203 100644 (file)
@@ -1,19 +1,19 @@
 // OpenTween - Client of Twitter
 // Copyright (c) 2012 kim_upsilon (@kim_upsilon) <https://upsilo.net/~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. 
-// 
+// for more details.
+//
 // You should have received a copy of the GNU General Public License along
 // with this program. If not, see <http://www.gnu.org/licenses/>, or write to
 // the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
 
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
-using System.Text;
-using NUnit.Framework;
+using System.Net.Http;
 using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
 using System.Windows.Forms;
+using Moq;
+using OpenTween.Models;
 using OpenTween.Thumbnail;
+using OpenTween.Thumbnail.Services;
+using Xunit;
+using Xunit.Extensions;
 
 namespace OpenTween
 {
-    [TestFixture]
-    class TweetThumbnailTest
+    public class TweetThumbnailTest
     {
-        [Test]
+        class TestThumbnailService : IThumbnailService
+        {
+            private readonly Regex regex;
+            private readonly string replaceUrl;
+            private readonly string replaceTooltip;
+
+            public TestThumbnailService(string pattern, string replaceUrl, string replaceTooltip)
+            {
+                this.regex = new Regex(pattern);
+                this.replaceUrl = replaceUrl;
+                this.replaceTooltip = replaceTooltip;
+            }
+
+            public override async Task<ThumbnailInfo> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
+            {
+                var match = this.regex.Match(url);
+
+                if (!match.Success) return null;
+
+                if (url.StartsWith("http://slow.example.com/", StringComparison.Ordinal))
+                    await Task.Delay(1000, token).ConfigureAwait(false);
+
+                return new MockThumbnailInfo
+                {
+                    MediaPageUrl = url,
+                    ThumbnailImageUrl = match.Result(this.replaceUrl),
+                    TooltipText = this.replaceTooltip != null ? match.Result(this.replaceTooltip) : null,
+                };
+            }
+
+            class MockThumbnailInfo : ThumbnailInfo
+            {
+                public override Task<MemoryImage> LoadThumbnailImageAsync(HttpClient http, CancellationToken cancellationToken)
+                {
+                    return Task.FromResult(TestUtils.CreateDummyImage());
+                }
+            }
+        }
+
+        public TweetThumbnailTest()
+        {
+            this.ThumbnailGeneratorSetup();
+            this.MyCommonSetup();
+        }
+
+        private void ThumbnailGeneratorSetup()
+        {
+            ThumbnailGenerator.Services.Clear();
+            ThumbnailGenerator.Services.AddRange(new[]
+            {
+                new TestThumbnailService(@"^https?://foo.example.com/(.+)$", @"http://img.example.com/${1}.png", null),
+                new TestThumbnailService(@"^https?://bar.example.com/(.+)$", @"http://img.example.com/${1}.png", @"${1}"),
+                new TestThumbnailService(@"^https?://slow.example.com/(.+)$", @"http://img.example.com/${1}.png", null),
+            });
+        }
+
+        private void MyCommonSetup()
+        {
+            var mockAssembly = new Mock<_Assembly>();
+            mockAssembly.Setup(m => m.GetName()).Returns(new AssemblyName("OpenTween"));
+
+            MyCommon.EntryAssembly = mockAssembly.Object;
+        }
+
+        [Fact]
         public void CreatePictureBoxTest()
         {
             using (var thumbBox = new TweetThumbnail())
@@ -41,68 +113,228 @@ namespace OpenTween
                 var method = typeof(TweetThumbnail).GetMethod("CreatePictureBox", BindingFlags.Instance | BindingFlags.NonPublic);
                 var picbox = method.Invoke(thumbBox, new[] { "pictureBox1" }) as PictureBox;
 
-                Assert.That(picbox, Is.Not.Null);
-                Assert.That(picbox.Name, Is.EqualTo("pictureBox1"));
-                Assert.That(picbox.SizeMode, Is.EqualTo(PictureBoxSizeMode.Zoom));
-                Assert.That(picbox.WaitOnLoad, Is.False);
-                Assert.That(picbox.Dock, Is.EqualTo(DockStyle.Fill));
-                Assert.That(picbox.Visible, Is.False);
+                Assert.NotNull(picbox);
+                Assert.Equal("pictureBox1", picbox.Name);
+                Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode);
+                Assert.False(picbox.WaitOnLoad);
+                Assert.Equal(DockStyle.Fill, picbox.Dock);
 
                 picbox.Dispose();
             }
         }
 
-        class TestTweetThumbnail : TweetThumbnail
+        [Fact]
+        public async Task CancelAsyncTest()
         {
-            protected override List<ThumbnailInfo> GetThumbailInfo(PostClass post)
+            var post = new PostClass
             {
-                return new List<ThumbnailInfo>
+                TextFromApi = "てすと http://slow.example.com/abcd",
+                Media = new List<MediaInfo>
                 {
-                    new ThumbnailInfo
-                    {
-                        ImageUrl = "http://example.com/abcd",
-                        ThumbnailUrl = "dot.gif", // 1x1の黒画像
-                        TooltipText = "ほげほげ",
-                    },
-                };
-            }
-        }
+                    new MediaInfo("http://slow.example.com/abcd"),
+                },
+            };
 
-        [Test]
-        [Ignore("Travis CI 上で実行時に何故か実行時間制限を超えることがあるため")]
-        public void CancelAsyncTest()
-        {
-            using (var thumbbox = new TestTweetThumbnail())
+            using (var thumbbox = new TweetThumbnail())
+            using (var tokenSource = new CancellationTokenSource())
             {
-                var post = new PostClass();
-                var task = thumbbox.ShowThumbnailAsync(post);
+                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
+                var task = thumbbox.ShowThumbnailAsync(post, tokenSource.Token);
 
-                thumbbox.CancelAsync();
+                tokenSource.Cancel();
 
-                Assert.That(task.IsCanceled, Is.True);
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await task);
+                Assert.True(task.IsCanceled);
             }
         }
 
-        [Test]
-        public void SetThumbnailCountTest(
-            [Values(0, 1, 2)] int count)
+        [Theory]
+        [InlineData(0)]
+        [InlineData(1)]
+        [InlineData(2)]
+        public void SetThumbnailCountTest(int count)
         {
             using (var thumbbox = new TweetThumbnail())
             {
                 var method = typeof(TweetThumbnail).GetMethod("SetThumbnailCount", BindingFlags.Instance | BindingFlags.NonPublic);
                 method.Invoke(thumbbox, new[] { (object)count });
 
-                Assert.That(thumbbox.pictureBox.Count, Is.EqualTo(count));
+                Assert.Equal(count, thumbbox.pictureBox.Count);
 
                 var num = 0;
                 foreach (var picbox in thumbbox.pictureBox)
                 {
-                    Assert.That(picbox.Name, Is.EqualTo("pictureBox" + num));
+                    Assert.Equal("pictureBox" + num, picbox.Name);
                     num++;
                 }
 
-                Assert.That(thumbbox.scrollBar.Minimum, Is.EqualTo(0));
-                Assert.That(thumbbox.scrollBar.Maximum, Is.EqualTo(count));
+                Assert.Equal(thumbbox.pictureBox, thumbbox.panelPictureBox.Controls.Cast<OTPictureBox>());
+
+                Assert.Equal(0, thumbbox.scrollBar.Minimum);
+
+                if (count == 0)
+                    Assert.Equal(0, thumbbox.scrollBar.Maximum);
+                else
+                    Assert.Equal(count - 1, thumbbox.scrollBar.Maximum);
+            }
+        }
+
+        [Fact]
+        public async Task ShowThumbnailAsyncTest()
+        {
+            var post = new PostClass
+            {
+                TextFromApi = "てすと http://foo.example.com/abcd",
+                Media = new List<MediaInfo>
+                {
+                    new MediaInfo("http://foo.example.com/abcd"),
+                },
+            };
+
+            using (var thumbbox = new TweetThumbnail())
+            {
+                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
+                await thumbbox.ShowThumbnailAsync(post);
+
+                Assert.Equal(0, thumbbox.scrollBar.Maximum);
+                Assert.False(thumbbox.scrollBar.Enabled);
+
+                Assert.Single(thumbbox.pictureBox);
+                Assert.NotNull(thumbbox.pictureBox[0].Image);
+
+                Assert.IsAssignableFrom<ThumbnailInfo>(thumbbox.pictureBox[0].Tag);
+                var thumbinfo = (ThumbnailInfo)thumbbox.pictureBox[0].Tag;
+
+                Assert.Equal("http://foo.example.com/abcd", thumbinfo.MediaPageUrl);
+                Assert.Equal("http://img.example.com/abcd.png", thumbinfo.ThumbnailImageUrl);
+
+                Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.pictureBox[0]));
+            }
+        }
+
+        [Fact]
+        public async Task ShowThumbnailAsyncTest2()
+        {
+            var post = new PostClass
+            {
+                TextFromApi = "てすと http://foo.example.com/abcd http://bar.example.com/efgh",
+                Media = new List<MediaInfo>
+                {
+                    new MediaInfo("http://foo.example.com/abcd"),
+                    new MediaInfo("http://bar.example.com/efgh"),
+                },
+            };
+
+            using (var thumbbox = new TweetThumbnail())
+            {
+                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
+                await thumbbox.ShowThumbnailAsync(post);
+
+                Assert.Equal(1, thumbbox.scrollBar.Maximum);
+                Assert.True(thumbbox.scrollBar.Enabled);
+
+                Assert.Equal(2, thumbbox.pictureBox.Count);
+                Assert.NotNull(thumbbox.pictureBox[0].Image);
+                Assert.NotNull(thumbbox.pictureBox[1].Image);
+
+                Assert.IsAssignableFrom<ThumbnailInfo>(thumbbox.pictureBox[0].Tag);
+                var thumbinfo = (ThumbnailInfo)thumbbox.pictureBox[0].Tag;
+
+                Assert.Equal("http://foo.example.com/abcd", thumbinfo.MediaPageUrl);
+                Assert.Equal("http://img.example.com/abcd.png", thumbinfo.ThumbnailImageUrl);
+
+                Assert.IsAssignableFrom<ThumbnailInfo>(thumbbox.pictureBox[1].Tag);
+                thumbinfo = (ThumbnailInfo)thumbbox.pictureBox[1].Tag;
+
+                Assert.Equal("http://bar.example.com/efgh", thumbinfo.MediaPageUrl);
+                Assert.Equal("http://img.example.com/efgh.png", thumbinfo.ThumbnailImageUrl);
+
+                Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.pictureBox[0]));
+                Assert.Equal("efgh", thumbbox.toolTip.GetToolTip(thumbbox.pictureBox[1]));
+            }
+        }
+
+        [Fact]
+        public async Task ThumbnailLoadingEventTest()
+        {
+            using (var thumbbox = new TweetThumbnail())
+            {
+                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
+
+                var post = new PostClass
+                {
+                    TextFromApi = "てすと",
+                    Media = new List<MediaInfo>
+                    {
+                    },
+                };
+                await TestUtils.NotRaisesAsync<EventArgs>(
+                    x => thumbbox.ThumbnailLoading += x,
+                    x => thumbbox.ThumbnailLoading -= x,
+                    () => thumbbox.ShowThumbnailAsync(post)
+                );
+
+                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
+
+                var post2 = new PostClass
+                {
+                    TextFromApi = "てすと http://foo.example.com/abcd",
+                    Media = new List<MediaInfo>
+                    {
+                        new MediaInfo("http://foo.example.com/abcd"),
+                    },
+                };
+
+                await Assert.RaisesAsync<EventArgs>(
+                    x => thumbbox.ThumbnailLoading += x,
+                    x => thumbbox.ThumbnailLoading -= x,
+                    () => thumbbox.ShowThumbnailAsync(post2)
+                );
+            }
+        }
+
+        [Fact]
+        public async Task ScrollTest()
+        {
+            var post = new PostClass
+            {
+                TextFromApi = "てすと http://foo.example.com/abcd http://foo.example.com/efgh",
+                Media = new List<MediaInfo>
+                {
+                    new MediaInfo("http://foo.example.com/abcd"),
+                    new MediaInfo("http://foo.example.com/efgh"),
+                },
+            };
+
+            using (var thumbbox = new TweetThumbnail())
+            {
+                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
+                await thumbbox.ShowThumbnailAsync(post);
+
+                Assert.Equal(0, thumbbox.scrollBar.Minimum);
+                Assert.Equal(1, thumbbox.scrollBar.Maximum);
+
+                thumbbox.scrollBar.Value = 0;
+
+                thumbbox.ScrollDown();
+                Assert.Equal(1, thumbbox.scrollBar.Value);
+                Assert.False(thumbbox.pictureBox[0].Visible);
+                Assert.True(thumbbox.pictureBox[1].Visible);
+
+                thumbbox.ScrollDown();
+                Assert.Equal(1, thumbbox.scrollBar.Value);
+                Assert.False(thumbbox.pictureBox[0].Visible);
+                Assert.True(thumbbox.pictureBox[1].Visible);
+
+                thumbbox.ScrollUp();
+                Assert.Equal(0, thumbbox.scrollBar.Value);
+                Assert.True(thumbbox.pictureBox[0].Visible);
+                Assert.False(thumbbox.pictureBox[1].Visible);
+
+                thumbbox.ScrollUp();
+                Assert.Equal(0, thumbbox.scrollBar.Value);
+                Assert.True(thumbbox.pictureBox[0].Visible);
+                Assert.False(thumbbox.pictureBox[1].Visible);
             }
         }
     }