OSDN Git Service

イベントのテストにAssert.Raisesを使用する
[opentween/open-tween.git] / OpenTween.Tests / Api / TwitterApiStatusTest.cs
index 508a3ab..9121133 100644 (file)
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net.Http;
 using System.Text;
-using NUnit.Framework;
+using System.Xml;
+using OpenTween.Api.DataModel;
+using Xunit;
+using Xunit.Extensions;
 
 namespace OpenTween.Api
 {
-    [TestFixture]
-    class TwitterApiStatusTest
+    public class TwitterApiStatusTest
     {
-        [Test]
+        [Fact]
         public void ResetTest()
         {
             var apiStatus = new TwitterApiStatus();
 
-            apiStatus.AccessLimit = new ApiLimit(150, 100, new DateTime(2013, 1, 1, 0, 0, 0));
+            apiStatus.AccessLimit["/statuses/home_timeline"] = new ApiLimit(150, 100, new DateTime(2013, 1, 1, 0, 0, 0));
             apiStatus.MediaUploadLimit = new ApiLimit(150, 100, new DateTime(2013, 1, 1, 0, 0, 0));
             apiStatus.AccessLevel = TwitterApiAccessLevel.ReadWriteAndDirectMessage;
 
             apiStatus.Reset();
 
-            Assert.That(apiStatus.AccessLimit, Is.Null);
-            Assert.That(apiStatus.MediaUploadLimit, Is.Null);
-            Assert.That(apiStatus.AccessLevel, Is.EqualTo(TwitterApiAccessLevel.Anonymous));
+            Assert.Null(apiStatus.AccessLimit["/statuses/home_timeline"]);
+            Assert.Null(apiStatus.MediaUploadLimit);
+            Assert.Equal(TwitterApiAccessLevel.Anonymous, apiStatus.AccessLevel);
         }
 
-        public static object[] ParseRateLimit_TestCase =
+        public static IEnumerable<object[]> ParseRateLimit_TestCase
         {
-            new object[] {
-                new Dictionary<string, string> {
-                    {"X-RateLimit-Limit", "150"},
-                    {"X-RateLimit-Remaining", "100"},
-                    {"X-RateLimit-Reset", "1356998400"},
-                },
-                new ApiLimit(150, 100, new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime()),
-            },
-            new object[] {
-                new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
-                    {"x-ratelimit-limit", "150"},
-                    {"x-ratelimit-remaining", "100"},
-                    {"x-ratelimit-reset", "1356998400"},
-                },
-                new ApiLimit(150, 100, new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime()),
-            },
-            new object[] {
-                new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
-                    {"X-RateLimit-Limit", "150"},
-                    {"X-RateLimit-Remaining", "100"},
-                    {"X-RateLimit-Reset", "hogehoge"},
-                },
-                null,
-            },
-            new object[] {
-                new Dictionary<string, string> {
-                    {"X-RateLimit-Limit", "150"},
-                    {"X-RateLimit-Remaining", "100"},
-                },
-                null,
-            },
-        };
-        [TestCaseSource("ParseRateLimit_TestCase")]
-        public void ParseRateLimitTest(IDictionary<string, string> header, ApiLimit expect)
+            get
+            {
+                yield return new object[] {
+                    new Dictionary<string, string> {
+                        ["X-RateLimit-Limit"] = "150",
+                        ["X-RateLimit-Remaining"] = "100",
+                        ["X-RateLimit-Reset"] = "1356998400",
+                    },
+                    new ApiLimit(150, 100, new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime()),
+                };
+                yield return new object[] {
+                    new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
+                        ["x-ratelimit-limit"] = "150",
+                        ["x-ratelimit-remaining"] = "100",
+                        ["x-ratelimit-reset"] = "1356998400",
+                    },
+                    new ApiLimit(150, 100, new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime()),
+                };
+                yield return new object[] {
+                    new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
+                        ["X-RateLimit-Limit"] = "150",
+                        ["X-RateLimit-Remaining"] = "100",
+                        ["X-RateLimit-Reset"] = "hogehoge",
+                    },
+                    null,
+                };
+                yield return new object[] {
+                    new Dictionary<string, string> {
+                        ["X-RateLimit-Limit"] = "150",
+                        ["X-RateLimit-Remaining"] = "100",
+                    },
+                    null,
+                };
+            }
+        }
+
+        [Theory]
+        [MemberData("ParseRateLimit_TestCase")]
+        public void ParseRateLimitTest(IDictionary<string, string> header, ApiLimit expected)
         {
-            var limit = TwitterApiStatus.ParseRateLimit(header);
-            Assert.That(limit, Is.EqualTo(expect));
+            var limit = TwitterApiStatus.ParseRateLimit(header, "X-RateLimit-");
+            Assert.Equal(expected, limit);
         }
 
-        public static object[] ParseMediaRateLimit_TestCase =
+        public static IEnumerable<object[]> ParseMediaRateLimit_TestCase
         {
-            new object[] {
-                new Dictionary<string, string> {
-                    {"X-MediaRateLimit-Limit", "30"},
-                    {"X-MediaRateLimit-Remaining", "20"},
-                    {"X-MediaRateLimit-Reset", "1234567890"},
-                },
-                new ApiLimit(30, 20, new DateTime(2009, 2, 13, 23, 31, 30, DateTimeKind.Utc).ToLocalTime()),
-            },
-            new object[] {
-                new Dictionary<string, string> {
-                    {"X-MediaRateLimit-Limit", "30"},
-                    {"X-MediaRateLimit-Remaining", "20"},
-                    {"X-MediaRateLimit-Reset", "hogehoge"},
-                },
-                null,
-            },
-            new object[] {
-                new Dictionary<string, string> {
-                    {"X-MediaRateLimit-Limit", "30"},
-                    {"X-MediaRateLimit-Remaining", "20"},
-                },
-                null,
-            },
-        };
-        [TestCaseSource("ParseMediaRateLimit_TestCase")]
-        public void ParseMediaRateLimitTest(IDictionary<string, string> header, ApiLimit expect)
+            get
+            {
+                yield return new object[] {
+                    new Dictionary<string, string> {
+                        ["X-MediaRateLimit-Limit"] = "30",
+                        ["X-MediaRateLimit-Remaining"] = "20",
+                        ["X-MediaRateLimit-Reset"] = "1234567890",
+                    },
+                    new ApiLimit(30, 20, new DateTime(2009, 2, 13, 23, 31, 30, DateTimeKind.Utc).ToLocalTime()),
+                };
+                yield return new object[] {
+                    new Dictionary<string, string> {
+                        ["X-MediaRateLimit-Limit"] = "30",
+                        ["X-MediaRateLimit-Remaining"] = "20",
+                        ["X-MediaRateLimit-Reset"] = "hogehoge",
+                    },
+                    null,
+                };
+                yield return new object[] {
+                    new Dictionary<string, string> {
+                        ["X-MediaRateLimit-Limit"] = "30",
+                        ["X-MediaRateLimit-Remaining"] = "20",
+                    },
+                    null,
+                };
+            }
+        }
+
+        [Theory]
+        [MemberData("ParseMediaRateLimit_TestCase")]
+        public void ParseMediaRateLimitTest(IDictionary<string, string> header, ApiLimit expected)
         {
-            var limit = TwitterApiStatus.ParseMediaRateLimit(header);
-            Assert.That(limit, Is.EqualTo(expect));
+            var limit = TwitterApiStatus.ParseRateLimit(header, "X-MediaRateLimit-");
+            Assert.Equal(expected, limit);
         }
 
-        public static object[] ParseAccessLevel_TestCase =
+        public static IEnumerable<object[]> ParseAccessLevel_TestCase
         {
-            new object[] {
-                new Dictionary<string, string> { {"X-Access-Level", "read"} },
-                TwitterApiAccessLevel.Read,
-            },
-            new object[] {
-                new Dictionary<string, string> { {"X-Access-Level", "read-write"} },
-                TwitterApiAccessLevel.ReadWrite,
-            },
-            new object[] {
-                new Dictionary<string, string> { {"X-Access-Level", "read-write-directmessages"} },
-                TwitterApiAccessLevel.ReadWriteAndDirectMessage,
-            },
-            new object[] {
-                new Dictionary<string, string> { {"X-Access-Level", ""} }, // 何故かたまに出てくるやつ
-                null,
-            },
-            new object[] {
-                new Dictionary<string, string> { },
-                null,
-            },
-        };
-        [TestCaseSource("ParseAccessLevel_TestCase")]
-        public void ParseAccessLevelTest(IDictionary<string, string> header, TwitterApiAccessLevel? expect)
+            get
+            {
+                yield return new object[] {
+                    new Dictionary<string, string> { {"X-Access-Level", "read"} },
+                    TwitterApiAccessLevel.Read,
+                };
+                yield return new object[] {
+                    new Dictionary<string, string> { {"X-Access-Level", "read-write"} },
+                    TwitterApiAccessLevel.ReadWrite,
+                };
+                yield return new object[] {
+                    new Dictionary<string, string> { {"X-Access-Level", "read-write-directmessages"} },
+                    TwitterApiAccessLevel.ReadWriteAndDirectMessage,
+                };
+                yield return new object[] {
+                    new Dictionary<string, string> { {"X-Access-Level", ""} }, // 何故かたまに出てくるやつ
+                    null,
+                };
+                yield return new object[] {
+                    new Dictionary<string, string> { },
+                    null,
+                };
+            }
+        }
+
+        [Theory]
+        [MemberData("ParseAccessLevel_TestCase")]
+        public void ParseAccessLevelTest(IDictionary<string, string> header, TwitterApiAccessLevel? expected)
         {
-            var accessLevel = TwitterApiStatus.ParseAccessLevel(header);
-            Assert.That(accessLevel, Is.EqualTo(expect));
+            var accessLevel = TwitterApiStatus.ParseAccessLevel(header, "X-Access-Level");
+            Assert.Equal(expected, accessLevel);
         }
 
-        [Test]
-        public void UpdateFromHeaderTest()
+        [Fact]
+        public void UpdateFromHeader_DictionaryTest()
         {
             var status = new TwitterApiStatus();
 
-            var eventCalled = false;
-            status.AccessLimitUpdated += (s, e) => eventCalled = true;
-
             var header = new Dictionary<string, string>
             {
-                {"X-RateLimit-Limit", "150"},
-                {"X-RateLimit-Remaining", "100"},
-                {"X-RateLimit-Reset", "1356998400"},
-                {"X-MediaRateLimit-Limit", "30"},
-                {"X-MediaRateLimit-Remaining", "20"},
-                {"X-MediaRateLimit-Reset", "1357084800"},
-                {"X-Access-Level", "read-write-directmessages"},
+                ["X-Rate-Limit-Limit"] = "150",
+                ["X-Rate-Limit-Remaining"] = "100",
+                ["X-Rate-Limit-Reset"] = "1356998400",
+                ["X-MediaRateLimit-Limit"] = "30",
+                ["X-MediaRateLimit-Remaining"] = "20",
+                ["X-MediaRateLimit-Reset"] = "1357084800",
+                ["X-Access-Level"] = "read-write-directmessages",
             };
 
-            status.UpdateFromHeader(header);
+            Assert.Raises<TwitterApiStatus.AccessLimitUpdatedEventArgs>(
+                x => status.AccessLimitUpdated += x,
+                x => status.AccessLimitUpdated -= x,
+                () => status.UpdateFromHeader(header, "/statuses/home_timeline")
+            );
 
-            var rateLimit = status.AccessLimit;
-            Assert.That(rateLimit.AccessLimitCount, Is.EqualTo(150));
-            Assert.That(rateLimit.AccessLimitRemain, Is.EqualTo(100));
-            Assert.That(rateLimit.AccessLimitResetDate, Is.EqualTo(new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime()));
+            var rateLimit = status.AccessLimit["/statuses/home_timeline"];
+            Assert.Equal(150, rateLimit.AccessLimitCount);
+            Assert.Equal(100, rateLimit.AccessLimitRemain);
+            Assert.Equal(new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime(), rateLimit.AccessLimitResetDate);
 
             var mediaLimit = status.MediaUploadLimit;
-            Assert.That(mediaLimit.AccessLimitCount, Is.EqualTo(30));
-            Assert.That(mediaLimit.AccessLimitRemain, Is.EqualTo(20));
-            Assert.That(mediaLimit.AccessLimitResetDate, Is.EqualTo(new DateTime(2013, 1, 2, 0, 0, 0, DateTimeKind.Utc).ToLocalTime()));
-
-            Assert.That(status.AccessLevel, Is.EqualTo(TwitterApiAccessLevel.ReadWriteAndDirectMessage));
+            Assert.Equal(30, mediaLimit.AccessLimitCount);
+            Assert.Equal(20, mediaLimit.AccessLimitRemain);
+            Assert.Equal(new DateTime(2013, 1, 2, 0, 0, 0, DateTimeKind.Utc).ToLocalTime(), mediaLimit.AccessLimitResetDate);
 
-            Assert.That(eventCalled, Is.True);
+            Assert.Equal(TwitterApiAccessLevel.ReadWriteAndDirectMessage, status.AccessLevel);
         }
 
-        [Test]
-        public void UpdateFromApiTest()
+        [Fact]
+        public void UpdateFromHeader_HttpClientTest()
         {
             var status = new TwitterApiStatus();
 
-            var eventCalled = false;
-            status.AccessLimitUpdated += (s, e) => eventCalled = true;
-
-            var apiResponse = new TwitterDataModel.RateLimitStatus
+            var response = new HttpResponseMessage
             {
-                HourlyLimit = 150,
-                RemainingHits = 100,
-                ResetTime = "Tue Jan 01 00:00:00 +0000 2013",
-                ResetTimeInSeconds = 1356998400,
-                Photos = new TwitterDataModel.MediaRateLimitStatus
+                Headers =
                 {
-                    DailyLimit = 30,
-                    RemainingHits = 20,
-                    ResetTime = "Wed Jan 02 00:00:00 +0000 2013",
-                    RestTimeInSeconds = 1357084800,
+                    { "x-rate-limit-limit", "150" },
+                    { "x-rate-limit-remaining", "100" },
+                    { "x-rate-limit-reset", "1356998400" },
+                    { "x-mediaratelimit-limit", "30" },
+                    { "x-mediaratelimit-remaining", "20" },
+                    { "x-mediaratelimit-reset", "1357084800" },
+                    { "x-access-level", "read-write-directmessages" },
                 },
             };
 
-            status.UpdateFromApi(apiResponse);
+            Assert.Raises<TwitterApiStatus.AccessLimitUpdatedEventArgs>(
+                x => status.AccessLimitUpdated += x,
+                x => status.AccessLimitUpdated -= x,
+                () => status.UpdateFromHeader(response.Headers, "/statuses/home_timeline")
+            );
 
-            var rateLimit = status.AccessLimit;
-            Assert.That(rateLimit.AccessLimitCount, Is.EqualTo(150));
-            Assert.That(rateLimit.AccessLimitRemain, Is.EqualTo(100));
-            Assert.That(rateLimit.AccessLimitResetDate, Is.EqualTo(new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime()));
+            var rateLimit = status.AccessLimit["/statuses/home_timeline"];
+            Assert.Equal(150, rateLimit.AccessLimitCount);
+            Assert.Equal(100, rateLimit.AccessLimitRemain);
+            Assert.Equal(new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime(), rateLimit.AccessLimitResetDate);
 
             var mediaLimit = status.MediaUploadLimit;
-            Assert.That(mediaLimit.AccessLimitCount, Is.EqualTo(30));
-            Assert.That(mediaLimit.AccessLimitRemain, Is.EqualTo(20));
-            Assert.That(mediaLimit.AccessLimitResetDate, Is.EqualTo(new DateTime(2013, 1, 2, 0, 0, 0, DateTimeKind.Utc).ToLocalTime()));
-
-            Assert.That(eventCalled, Is.True);
-        }
-
-        [Test]
-        public void UpdateFromApiTest2()
-        {
-            var status = new TwitterApiStatus();
-
-            var eventCalled = false;
-            status.AccessLimitUpdated += (s, e) => eventCalled = true;
-
-            var apiResponse = new TwitterDataModel.RateLimitStatus
-            {
-                HourlyLimit = 150,
-                RemainingHits = 100,
-                ResetTime = "Tue Jan 01 00:00:00 +0000 2013",
-                ResetTimeInSeconds = 1356998400,
-                Photos = null,
-            };
-
-            status.UpdateFromApi(apiResponse);
-
-            var rateLimit = status.AccessLimit;
-            Assert.That(rateLimit.AccessLimitCount, Is.EqualTo(150));
-            Assert.That(rateLimit.AccessLimitRemain, Is.EqualTo(100));
-            Assert.That(rateLimit.AccessLimitResetDate, Is.EqualTo(new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime()));
+            Assert.Equal(30, mediaLimit.AccessLimitCount);
+            Assert.Equal(20, mediaLimit.AccessLimitRemain);
+            Assert.Equal(new DateTime(2013, 1, 2, 0, 0, 0, DateTimeKind.Utc).ToLocalTime(), mediaLimit.AccessLimitResetDate);
 
-            Assert.That(status.MediaUploadLimit, Is.Null);
-
-            Assert.That(eventCalled, Is.True);
+            Assert.Equal(TwitterApiAccessLevel.ReadWriteAndDirectMessage, status.AccessLevel);
         }
 
-        [Test]
-        public void UpdateFromApiTest3()
+        public void UpdateFromJsonTest()
         {
             var status = new TwitterApiStatus();
 
-            var eventCalled = false;
-            status.AccessLimitUpdated += (s, e) => eventCalled = true;
-
-            Assert.That(() => status.UpdateFromApi(null), Throws.TypeOf<ArgumentNullException>());
+            var json = "{\"resources\":{\"statuses\":{\"/statuses/home_timeline\":{\"limit\":150,\"remaining\":100,\"reset\":1356998400}}}}";
 
-            Assert.That(status.AccessLimit, Is.Null);
-            Assert.That(status.MediaUploadLimit, Is.Null);
+            Assert.Raises<TwitterApiStatus.AccessLimitUpdatedEventArgs>(
+                x => status.AccessLimitUpdated += x,
+                x => status.AccessLimitUpdated -= x,
+                () => status.UpdateFromJson(TwitterRateLimits.ParseJson(json))
+            );
 
-            Assert.That(eventCalled, Is.False);
+            var rateLimit = status.AccessLimit["/statuses/home_timeline"];
+            Assert.Equal(150, rateLimit.AccessLimitCount);
+            Assert.Equal(100, rateLimit.AccessLimitRemain);
+            Assert.Equal(new DateTime(2013, 1, 1, 0, 0, 0, DateTimeKind.Utc).ToLocalTime(), rateLimit.AccessLimitResetDate);
         }
 
-        [Test]
+        [Fact]
         public void AccessLimitUpdatedTest()
         {
             var apiStatus = new TwitterApiStatus();
 
-            var eventCount = 0;
-            apiStatus.AccessLimitUpdated += (s, e) => eventCount++;
-
-            Assert.That(eventCount, Is.EqualTo(0));
-
-            apiStatus.AccessLimit = new ApiLimit(150, 100, new DateTime(2013, 1, 1, 0, 0, 0));
-            Assert.That(eventCount, Is.EqualTo(1));
-
-            apiStatus.Reset();
-            Assert.That(eventCount, Is.EqualTo(2));
+            Assert.Raises<TwitterApiStatus.AccessLimitUpdatedEventArgs>(
+                x => apiStatus.AccessLimitUpdated += x,
+                x => apiStatus.AccessLimitUpdated -= x,
+                () => apiStatus.AccessLimit["/statuses/home_timeline"] = new ApiLimit(150, 100, new DateTime(2013, 1, 1, 0, 0, 0))
+            );
+
+            Assert.Raises<TwitterApiStatus.AccessLimitUpdatedEventArgs>(
+                x => apiStatus.AccessLimitUpdated += x,
+                x => apiStatus.AccessLimitUpdated -= x,
+                () => apiStatus.Reset()
+            );
         }
     }
 }