diff --git a/src/Lidarr.Http/ClientSchema/SchemaBuilder.cs b/src/Lidarr.Http/ClientSchema/SchemaBuilder.cs index 592681f65..b65f77110 100644 --- a/src/Lidarr.Http/ClientSchema/SchemaBuilder.cs +++ b/src/Lidarr.Http/ClientSchema/SchemaBuilder.cs @@ -209,7 +209,11 @@ namespace Lidarr.Http.ClientSchema { return fieldValue => { - if (fieldValue.GetType() == typeof(JArray)) + if (fieldValue == null) + { + return Enumerable.Empty(); + } + else if (fieldValue.GetType() == typeof(JArray)) { return ((JArray)fieldValue).Select(s => s.Value()); } @@ -223,7 +227,11 @@ namespace Lidarr.Http.ClientSchema { return fieldValue => { - if (fieldValue.GetType() == typeof(JArray)) + if (fieldValue == null) + { + return Enumerable.Empty(); + } + else if (fieldValue.GetType() == typeof(JArray)) { return ((JArray)fieldValue).Select(s => s.Value()); } diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabCategoryFieldOptionsConverter.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabCategoryFieldOptionsConverter.cs index 1e87f4550..922b08659 100644 --- a/src/NzbDrone.Core/Indexers/Newznab/NewznabCategoryFieldOptionsConverter.cs +++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabCategoryFieldOptionsConverter.cs @@ -10,7 +10,10 @@ namespace NzbDrone.Core.Indexers.Newznab public static List GetFieldSelectOptions(List categories) { // Ignore categories not relevant for Lidarr - var ignoreCategories = new[] { 0, 1000, 2000, 4000, 5000, 6000, 7000 }; + var ignoreCategories = new[] { 1000, 2000, 4000, 5000, 6000, 7000 }; + + // And maybe relevant for specific users + var unimportantCategories = new[] { 0 }; var result = new List(); @@ -32,13 +35,8 @@ namespace NzbDrone.Core.Indexers.Newznab }); } - foreach (var category in categories) + foreach (var category in categories.Where(cat => !ignoreCategories.Contains(cat.Id)).OrderBy(cat => unimportantCategories.Contains(cat.Id)).ThenBy(cat => cat.Id)) { - if (ignoreCategories.Contains(category.Id)) - { - continue; - } - result.Add(new FieldSelectOption { Value = category.Id, @@ -48,7 +46,7 @@ namespace NzbDrone.Core.Indexers.Newznab if (category.Subcategories != null) { - foreach (var subcat in category.Subcategories) + foreach (var subcat in category.Subcategories.OrderBy(cat => cat.Id)) { result.Add(new FieldSelectOption { @@ -61,8 +59,6 @@ namespace NzbDrone.Core.Indexers.Newznab } } - result.Sort((l, r) => l.Value.CompareTo(r.Value)); - return result; } } diff --git a/src/NzbDrone.Integration.Test/ApiTests/IndexerFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/IndexerFixture.cs index 4acf089a4..bf55ea58b 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/IndexerFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/IndexerFixture.cs @@ -1,5 +1,8 @@ -using System.Linq; +using System.Linq; using FluentAssertions; +using Lidarr.Api.V1.Indexers; +using Lidarr.Http.ClientSchema; +using Newtonsoft.Json.Linq; using NUnit.Framework; using NzbDrone.Core.ThingiProvider; @@ -18,5 +21,172 @@ namespace NzbDrone.Integration.Test.ApiTests indexers.Should().NotContain(c => string.IsNullOrWhiteSpace(c.Name)); indexers.Where(c => c.ConfigContract == typeof(NullConfig).Name).Should().OnlyContain(c => c.EnableRss); } + + private IndexerResource GetNewznabSchemav1(string name = null) + { + var schema = Indexers.Schema().First(v => v.Implementation == "Newznab"); + + schema.Name = name; + schema.EnableRss = false; + schema.EnableAutomaticSearch = false; + schema.EnableInteractiveSearch = false; + + return schema; + } + + private Field GetCategoriesField(IndexerResource resource) + { + var field = resource.Fields.First(v => v.Name == "categories"); + + return field; + } + + [Test] + public void v2_categories_should_be_array() + { + var schema = GetNewznabSchemav1(); + + var categoriesField = GetCategoriesField(schema); + + categoriesField.Value.Should().BeOfType(); + } + + [Test] + public void v3_categories_should_be_array() + { + var schema = GetNewznabSchemav1(); + + var categoriesField = GetCategoriesField(schema); + + categoriesField.Value.Should().BeOfType(); + } + + [Test] + public void v2_categories_should_accept_null() + { + var schema = GetNewznabSchemav1("Testv2null"); + + var categoriesField = GetCategoriesField(schema); + + categoriesField.Value = null; + + var result = Indexers.Post(schema); + + var resultArray = GetCategoriesField(result).Value; + resultArray.Should().BeOfType(); + resultArray.As().Should().BeEmpty(); + } + + [Test] + public void v2_categories_should_accept_emptystring() + { + var schema = GetNewznabSchemav1("Testv2emptystring"); + + var categoriesField = GetCategoriesField(schema); + + categoriesField.Value = ""; + + var result = Indexers.Post(schema); + + var resultArray = GetCategoriesField(result).Value; + resultArray.Should().BeOfType(); + resultArray.As().Should().BeEmpty(); + } + + [Test] + public void v2_categories_should_accept_string() + { + var schema = GetNewznabSchemav1("Testv2string"); + + var categoriesField = GetCategoriesField(schema); + + categoriesField.Value = "1000,1010"; + + var result = Indexers.Post(schema); + + var resultArray = GetCategoriesField(result).Value; + resultArray.Should().BeOfType(); + resultArray.As().ToObject().Should().BeEquivalentTo(new[] { 1000, 1010 }); + } + + [Test] + public void v2_categories_should_accept_array() + { + var schema = GetNewznabSchemav1("Testv2array"); + + var categoriesField = GetCategoriesField(schema); + + categoriesField.Value = new object[] { 1000, 1010 }; + + var result = Indexers.Post(schema); + + var resultArray = GetCategoriesField(result).Value; + resultArray.Should().BeOfType(); + resultArray.As().ToObject().Should().BeEquivalentTo(new[] { 1000, 1010 }); + } + + [Test] + public void v3_categories_should_accept_null() + { + var schema = GetNewznabSchemav1("Testv3null"); + + var categoriesField = GetCategoriesField(schema); + + categoriesField.Value = null; + + var result = Indexers.Post(schema); + + var resultArray = GetCategoriesField(result).Value; + resultArray.Should().BeOfType(); + resultArray.As().Should().BeEmpty(); + } + + [Test] + public void v3_categories_should_accept_emptystring() + { + var schema = GetNewznabSchemav1("Testv3emptystring"); + + var categoriesField = GetCategoriesField(schema); + + categoriesField.Value = ""; + + var result = Indexers.Post(schema); + + var resultArray = GetCategoriesField(result).Value; + resultArray.Should().BeOfType(); + resultArray.As().Should().BeEmpty(); + } + + [Test] + public void v3_categories_should_accept_string() + { + var schema = GetNewznabSchemav1("Testv3string"); + + var categoriesField = GetCategoriesField(schema); + + categoriesField.Value = "1000,1010"; + + var result = Indexers.Post(schema); + + var resultArray = GetCategoriesField(result).Value; + resultArray.Should().BeOfType(); + resultArray.As().ToObject().Should().BeEquivalentTo(new[] { 1000, 1010 }); + } + + [Test] + public void v3_categories_should_accept_array() + { + var schema = GetNewznabSchemav1("Testv3array"); + + var categoriesField = GetCategoriesField(schema); + + categoriesField.Value = new object[] { 1000, 1010 }; + + var result = Indexers.Post(schema); + + var resultArray = GetCategoriesField(result).Value; + resultArray.Should().BeOfType(); + resultArray.As().ToObject().Should().BeEquivalentTo(new[] { 1000, 1010 }); + } } } diff --git a/src/NzbDrone.Integration.Test/Client/IndexerClient.cs b/src/NzbDrone.Integration.Test/Client/IndexerClient.cs index 9e56dd21a..75fd8349e 100644 --- a/src/NzbDrone.Integration.Test/Client/IndexerClient.cs +++ b/src/NzbDrone.Integration.Test/Client/IndexerClient.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Lidarr.Api.V1.Indexers; using RestSharp; @@ -9,5 +10,11 @@ namespace NzbDrone.Integration.Test.Client : base(restClient, apiKey) { } + + public List Schema() + { + var request = BuildRequest("/schema"); + return Get>(request); + } } }