From 747f3e171c752a18148c1d115679ba2b9710d260 Mon Sep 17 00:00:00 2001 From: margaale Date: Sun, 17 Dec 2017 15:31:42 -0300 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 | 2 + .../UsenetDownloadStationFixture.cs | 3 + .../NzbDrone.Core.Test.csproj | 1 + .../DownloadStation/DownloadStationTask.cs | 13 +++-- 7 files changed, 121 insertions(+), 6 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 4305f2e02..40b6d7191 100644 --- a/src/NzbDrone.Common/NzbDrone.Common.csproj +++ b/src/NzbDrone.Common/NzbDrone.Common.csproj @@ -212,6 +212,7 @@ + diff --git a/src/NzbDrone.Common/Serializer/UnderscoreStringEnumConverter.cs b/src/NzbDrone.Common/Serializer/UnderscoreStringEnumConverter.cs new file mode 100644 index 000000000..9022c029f --- /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..0ad41bbfd --- /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 4142ddc65..fb3eb9962 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/TorrentDownloadStationFixture.cs @@ -605,8 +605,10 @@ 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)] public void GetItems_should_return_item_as_downloadItemStatus(DownloadStationTaskStatus apiStatus, DownloadItemStatus expectedItemStatus) { diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs index 6d0a0f0e9..f1d199b35 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DownloadStationTests/UsenetDownloadStationFixture.cs @@ -414,7 +414,10 @@ 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)] public void GetItems_should_return_item_as_downloadItemStatus(DownloadStationTaskStatus apiStatus, DownloadItemStatus expectedItemStatus) { diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index a88ef4945..f2b759c8d 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -176,6 +176,7 @@ + diff --git a/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTask.cs b/src/NzbDrone.Core/Download/Clients/DownloadStation/DownloadStationTask.cs index a22cc7296..5b4a61253 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 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