From 96c59e2b2b1b26a877a9c8a24eb4fe2310dabf2b Mon Sep 17 00:00:00 2001 From: Qstick Date: Sun, 14 Jan 2018 14:34:08 -0500 Subject: [PATCH] Fixed: Handling of unknown status types in DownloadStation --- src/NzbDrone.Common/NzbDrone.Common.csproj | 1 + .../UnderscoreStringEnumConverter.cs | 58 +++++++++++++++++++ ...dStationsTaskStatusJsonConverterFixture.cs | 49 ++++++++++++++++ .../TorrentDownloadStationFixture.cs | 3 + .../UsenetDownloadStationFixture.cs | 4 ++ .../NzbDrone.Core.Test.csproj | 1 + .../DownloadStation/DownloadStationTask.cs | 11 ++-- .../DownloadStation/TorrentDownloadStation.cs | 2 + .../DownloadStation/UsenetDownloadStation.cs | 2 + 9 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 src/NzbDrone.Common/Serializer/UnderscoreStringEnumConverter.cs create mode 100644 src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/DownloadStationsTaskStatusJsonConverterFixture.cs diff --git a/src/NzbDrone.Common/NzbDrone.Common.csproj b/src/NzbDrone.Common/NzbDrone.Common.csproj index 9f424c291..9ba73c800 100644 --- a/src/NzbDrone.Common/NzbDrone.Common.csproj +++ b/src/NzbDrone.Common/NzbDrone.Common.csproj @@ -216,6 +216,7 @@ + diff --git a/src/NzbDrone.Common/Serializer/UnderscoreStringEnumConverter.cs b/src/NzbDrone.Common/Serializer/UnderscoreStringEnumConverter.cs new file mode 100644 index 000000000..49ca2e207 --- /dev/null +++ b/src/NzbDrone.Common/Serializer/UnderscoreStringEnumConverter.cs @@ -0,0 +1,58 @@ +using System; +using System.Text; +using Newtonsoft.Json; + +namespace NzbDrone.Common.Serializer +{ + public class UnderscoreStringEnumConverter : JsonConverter + { + public object UnknownValue { get; set; } + + public UnderscoreStringEnumConverter(object unknownValue) + { + UnknownValue = unknownValue; + } + + public override bool CanConvert(Type objectType) + { + return objectType.IsEnum; + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var enumString = reader.Value.ToString().Replace("_", string.Empty); + + try + { + return Enum.Parse(objectType, enumString, true); + } + catch + { + if (UnknownValue == null) + { + throw; + } + + return UnknownValue; + } + } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var enumText = value.ToString(); + var builder = new StringBuilder(enumText.Length + 4); + builder.Append(char.ToLower(enumText[0])); + for (int i = 1; i < enumText.Length; i++) + { + if (char.IsUpper(enumText[i])) + { + builder.Append('_'); + } + builder.Append(char.ToLower(enumText[i])); + } + enumText = builder.ToString(); + + writer.WriteValue(enumText); + } + } +} diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/DownloadStationsTaskStatusJsonConverterFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/DownloadStationsTaskStatusJsonConverterFixture.cs new file mode 100644 index 000000000..0437126df --- /dev/null +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/DownloadStationsTaskStatusJsonConverterFixture.cs @@ -0,0 +1,49 @@ +using FluentAssertions; +using Newtonsoft.Json; +using NUnit.Framework; +using NzbDrone.Core.Download.Clients.DownloadStation; + +namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests +{ + [TestFixture] + public class DownloadStationsTaskStatusJsonConverterFixture + { + [TestCase("captcha_needed", DownloadStationTaskStatus.CaptchaNeeded)] + [TestCase("filehosting_waiting", DownloadStationTaskStatus.FilehostingWaiting)] + [TestCase("hash_checking", DownloadStationTaskStatus.HashChecking)] + [TestCase("error", DownloadStationTaskStatus.Error)] + [TestCase("downloading", DownloadStationTaskStatus.Downloading)] + public void should_parse_enum_correctly(string value, DownloadStationTaskStatus expected) + { + var task = "{\"Status\": \"" + value + "\"}"; + + var item = JsonConvert.DeserializeObject(task); + + item.Status.Should().Be(expected); + } + + [TestCase("captcha_needed", DownloadStationTaskStatus.CaptchaNeeded)] + [TestCase("filehosting_waiting", DownloadStationTaskStatus.FilehostingWaiting)] + [TestCase("hash_checking", DownloadStationTaskStatus.HashChecking)] + [TestCase("error", DownloadStationTaskStatus.Error)] + [TestCase("downloading", DownloadStationTaskStatus.Downloading)] + public void should_serialize_enum_correctly(string expected, DownloadStationTaskStatus value) + { + var task = new DownloadStationTask { Status = value }; + + var item = JsonConvert.SerializeObject(task); + + item.Should().Contain(expected); + } + + [Test] + public void should_return_unknown_if_unknown_enum_value() + { + var task = "{\"Status\": \"some_unknown_value\"}"; + + var item = JsonConvert.DeserializeObject(task); + + item.Status.Should().Be(DownloadStationTaskStatus.Unknown); + } + } +} diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs index 5ec0739a1..fbec5b2d6 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs @@ -604,9 +604,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests [TestCase(DownloadStationTaskStatus.Finished, DownloadItemStatus.Completed)] [TestCase(DownloadStationTaskStatus.Finishing, DownloadItemStatus.Downloading)] [TestCase(DownloadStationTaskStatus.HashChecking, DownloadItemStatus.Downloading)] + [TestCase(DownloadStationTaskStatus.CaptchaNeeded, DownloadItemStatus.Downloading)] [TestCase(DownloadStationTaskStatus.Paused, DownloadItemStatus.Paused)] [TestCase(DownloadStationTaskStatus.Seeding, DownloadItemStatus.Completed)] + [TestCase(DownloadStationTaskStatus.FilehostingWaiting, DownloadItemStatus.Queued)] [TestCase(DownloadStationTaskStatus.Waiting, DownloadItemStatus.Queued)] + [TestCase(DownloadStationTaskStatus.Unknown, DownloadItemStatus.Queued)] public void GetItems_should_return_item_as_downloadItemStatus(DownloadStationTaskStatus apiStatus, DownloadItemStatus expectedItemStatus) { GivenSerialNumber(); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs index abf497b49..badba80e6 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs @@ -414,8 +414,12 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.DownloadStationTests [TestCase(DownloadStationTaskStatus.Finished, DownloadItemStatus.Completed)] [TestCase(DownloadStationTaskStatus.Finishing, DownloadItemStatus.Downloading)] [TestCase(DownloadStationTaskStatus.HashChecking, DownloadItemStatus.Downloading)] + [TestCase(DownloadStationTaskStatus.CaptchaNeeded, DownloadItemStatus.Downloading)] [TestCase(DownloadStationTaskStatus.Paused, DownloadItemStatus.Paused)] + [TestCase(DownloadStationTaskStatus.Seeding, DownloadItemStatus.Completed)] + [TestCase(DownloadStationTaskStatus.FilehostingWaiting, DownloadItemStatus.Queued)] [TestCase(DownloadStationTaskStatus.Waiting, DownloadItemStatus.Queued)] + [TestCase(DownloadStationTaskStatus.Unknown, DownloadItemStatus.Queued)] public void GetItems_should_return_item_as_downloadItemStatus(DownloadStationTaskStatus apiStatus, DownloadItemStatus expectedItemStatus) { GivenSerialNumber(); diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index e242a085a..23c3cb702 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -147,6 +147,7 @@ + diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTask.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTask.cs index a22cc7296..6957f3e92 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTask.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTask.cs @@ -1,7 +1,6 @@ -using System; using System.Collections.Generic; using Newtonsoft.Json; -using Newtonsoft.Json.Converters; +using NzbDrone.Common.Serializer; namespace NzbDrone.Core.Download.Clients.DownloadStation { @@ -23,7 +22,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation [JsonProperty(PropertyName = "status_extra")] public Dictionary StatusExtra { get; set; } - [JsonConverter(typeof(StringEnumConverter))] + [JsonConverter(typeof(UnderscoreStringEnumConverter), DownloadStationTaskStatus.Unknown)] public DownloadStationTaskStatus Status { get; set; } public DownloadStationTaskAdditional Additional { get; set; } @@ -41,6 +40,7 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation public enum DownloadStationTaskStatus { + Unknown, Waiting, Downloading, Paused, @@ -48,9 +48,10 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation Finished, HashChecking, Seeding, - FileHostingWaiting, + FilehostingWaiting, Extracting, - Error + Error, + CaptchaNeeded } public enum DownloadStationPriority diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs index 0d2ca3d01..cf217cb09 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/TorrentDownloadStation.cs @@ -227,7 +227,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation { switch (torrent.Status) { + case DownloadStationTaskStatus.Unknown: case DownloadStationTaskStatus.Waiting: + case DownloadStationTaskStatus.FilehostingWaiting: return torrent.Size == 0 || GetRemainingSize(torrent) > 0 ? DownloadItemStatus.Queued : DownloadItemStatus.Completed; case DownloadStationTaskStatus.Paused: return DownloadItemStatus.Paused; diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs index 31d6c0f71..e92741bed 100644 --- a/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs +++ b/src/NzbDrone.Core/Download/Clients/DownloadStation/UsenetDownloadStation.cs @@ -315,7 +315,9 @@ namespace NzbDrone.Core.Download.Clients.DownloadStation { switch (task.Status) { + case DownloadStationTaskStatus.Unknown: case DownloadStationTaskStatus.Waiting: + case DownloadStationTaskStatus.FilehostingWaiting: return task.Size == 0 || GetRemainingSize(task) > 0 ? DownloadItemStatus.Queued : DownloadItemStatus.Completed; case DownloadStationTaskStatus.Paused: return DownloadItemStatus.Paused;