core: rewrite category code from scratch. resolves #8049 (#10031)

* Core: Categories are stored in a real tree
* Sorting: First Torznab categories sorted by Id and then custom cats sorted by Name
* Filtering: Results with child category are not removed when searching by parent category. Details in #8049
* Jacket UI: Add parent category when at least one child category exists
* Torznab (caps): Remove non existent children categories. Remove duplicated categories. Details in #10006
This commit is contained in:
Diego Heras
2020-11-01 12:07:24 +01:00
committed by GitHub
parent 4464d97e2f
commit 7a2e52659a
12 changed files with 360 additions and 153 deletions

View File

@@ -38,7 +38,7 @@ namespace Jackett.Test.Common.Indexers
Assert.False(caps.BookSearchAvailable);
Assert.False(caps.BookSearchTitleAvailable);
Assert.False(caps.BookSearchAuthorAvailable);
Assert.AreEqual(0, caps.Categories.GetTorznabCategories().Count);
Assert.AreEqual(0, caps.Categories.GetTorznabCategoryTree().Count);
}
[Test]
@@ -66,27 +66,25 @@ namespace Jackett.Test.Common.Indexers
var filteredResults = indexer._FilterResults(query, results).ToList();
Assert.AreEqual(4, filteredResults.Count);
// TODO: fix this, we should return MoviesSD and null
query = new TorznabQuery // with child category
{
Categories = new [] { TorznabCatType.MoviesSD.ID }
};
filteredResults = indexer._FilterResults(query, results).ToList();
Assert.AreEqual(2, filteredResults.Count);
Assert.AreEqual(TorznabCatType.MoviesSD.ID, filteredResults[0].Category.First());
Assert.AreEqual(null, filteredResults[1].Category);
query = new TorznabQuery // with parent category
{
Categories = new [] { TorznabCatType.Movies.ID }
};
filteredResults = indexer._FilterResults(query, results).ToList();
Assert.AreEqual(3, filteredResults.Count);
Assert.AreEqual(TorznabCatType.Movies.ID, filteredResults[0].Category.First());
Assert.AreEqual(TorznabCatType.MoviesSD.ID, filteredResults[1].Category.First());
Assert.AreEqual(null, filteredResults[2].Category);
// TODO: fix this, we should return Movies, MoviesSD and null
query = new TorznabQuery // with parent category
{
Categories = new [] { TorznabCatType.Movies.ID }
};
filteredResults = indexer._FilterResults(query, results).ToList();
Assert.AreEqual(2, filteredResults.Count);
Assert.AreEqual(TorznabCatType.Movies.ID, filteredResults[0].Category.First());
Assert.AreEqual(null, filteredResults[1].Category);
query = new TorznabQuery // with custom category
{
Categories = new [] { 100004 }
@@ -104,9 +102,17 @@ namespace Jackett.Test.Common.Indexers
// you can find more complex tests in TorznabCapabilitiesCategoriesTests.cs
indexer._AddCategoryMapping("11", TorznabCatType.MoviesSD, "MoviesSD");
Assert.AreEqual(2, indexer.TorznabCaps.Categories.GetTorznabCategories().Count);
var expected = new List<TorznabCategory>
{
TorznabCatType.Movies.CopyWithoutSubCategories(),
new TorznabCategory(100011, "MoviesSD")
};
expected[0].SubCategories.Add(TorznabCatType.MoviesSD.CopyWithoutSubCategories());
TestCategories.CompareCategoryTrees(expected, indexer.TorznabCaps.Categories.GetTorznabCategoryTree());
indexer._AddCategoryMapping(14, TorznabCatType.MoviesHD);
Assert.AreEqual(3, indexer.TorznabCaps.Categories.GetTorznabCategories().Count);
expected[0].SubCategories.Add(TorznabCatType.MoviesHD.CopyWithoutSubCategories());
TestCategories.CompareCategoryTrees(expected, indexer.TorznabCaps.Categories.GetTorznabCategoryTree());
}
[Test]
@@ -115,7 +121,7 @@ namespace Jackett.Test.Common.Indexers
var indexer = new TestWebIndexer();
indexer._AddMultiCategoryMapping(TorznabCatType.MoviesHD,19, 18);
Assert.AreEqual(1, indexer.TorznabCaps.Categories.GetTorznabCategories().Count);
Assert.AreEqual(1, indexer.TorznabCaps.Categories.GetTorznabCategoryTree().Count);
}
[Test]

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using Jackett.Common.Indexers;
using Jackett.Common.Models;
using Jackett.Test.TestHelpers;
using NUnit.Framework;
namespace Jackett.Test.Common.Indexers
@@ -48,7 +49,7 @@ namespace Jackett.Test.Common.Indexers
Assert.False(indexer.TorznabCaps.BookSearchAvailable);
Assert.False(indexer.TorznabCaps.BookSearchTitleAvailable);
Assert.False(indexer.TorznabCaps.BookSearchAuthorAvailable);
Assert.AreEqual(0, indexer.TorznabCaps.Categories.GetTorznabCategories().Count);
Assert.AreEqual(0, indexer.TorznabCaps.Categories.GetTorznabCategoryTree().Count);
definition = new IndexerDefinition // test categories (same as in C# indexer)
{
@@ -91,16 +92,20 @@ namespace Jackett.Test.Common.Indexers
};
indexer = new CardigannIndexer(null, null, null, null, definition);
// TODO: test duplicates
var cats = indexer.TorznabCaps.Categories.GetTorznabCategories();
Assert.AreEqual(7, cats.Count);
Assert.AreEqual(2000, cats[0].ID);
Assert.AreEqual(2030, cats[1].ID);
Assert.AreEqual(7030, cats[2].ID);
Assert.AreEqual(1040, cats[3].ID);
Assert.AreEqual(100044, cats[4].ID);
Assert.AreEqual(1030, cats[5].ID);
Assert.AreEqual(100045, cats[6].ID);
// test categories
var expected = new List<TorznabCategory>
{
TorznabCatType.Movies.CopyWithoutSubCategories(),
TorznabCatType.Books.CopyWithoutSubCategories(),
TorznabCatType.Console.CopyWithoutSubCategories(),
new TorznabCategory(100044, "Console/Xbox_c"),
new TorznabCategory(100045, "Console/Xbox_c2")
};
expected[0].SubCategories.Add(TorznabCatType.MoviesSD.CopyWithoutSubCategories());
expected[1].SubCategories.Add(TorznabCatType.BooksComics.CopyWithoutSubCategories());
expected[2].SubCategories.Add(TorznabCatType.ConsoleXBox.CopyWithoutSubCategories());
expected[2].SubCategories.Add(TorznabCatType.ConsoleWii.CopyWithoutSubCategories());
TestCategories.CompareCategoryTrees(expected, indexer.TorznabCaps.Categories.GetTorznabCategoryTree());
definition = new IndexerDefinition // test search modes
{

View File

@@ -37,14 +37,16 @@ namespace Jackett.Test.Common.Models.DTO
// test Jackett UI categories (internal JSON)
var dto = new Indexer(indexer);
var dtoCaps = dto.caps.ToList();
Assert.AreEqual(7, dtoCaps.Count);
Assert.AreEqual("100044", dtoCaps[0].ID);
Assert.AreEqual("100045", dtoCaps[1].ID);
Assert.AreEqual("1030", dtoCaps[2].ID);
Assert.AreEqual("1040", dtoCaps[3].ID);
Assert.AreEqual("2000", dtoCaps[4].ID);
Assert.AreEqual("2030", dtoCaps[5].ID);
Assert.AreEqual(9, dtoCaps.Count);
Assert.AreEqual("1000", dtoCaps[0].ID);
Assert.AreEqual("1030", dtoCaps[1].ID);
Assert.AreEqual("1040", dtoCaps[2].ID);
Assert.AreEqual("2000", dtoCaps[3].ID);
Assert.AreEqual("2030", dtoCaps[4].ID);
Assert.AreEqual("7000", dtoCaps[5].ID);
Assert.AreEqual("7030", dtoCaps[6].ID);
Assert.AreEqual("100044", dtoCaps[7].ID);
Assert.AreEqual("100040", dtoCaps[8].ID);
// movies categories enable potato search
Assert.True(dto.potatoenabled);

View File

@@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using Jackett.Common.Models;
using Jackett.Test.TestHelpers;
@@ -6,10 +7,6 @@ using Assert = NUnit.Framework.Assert;
namespace Jackett.Test.Common.Models
{
// TODO: add duplicates: different trackerCat but same newznabCat
// TODO: duplicates are not working well because we keep 2 internal lists with categories. One is de-duplicated
// and the other doesn't
[TestFixture]
public class TorznabCapabilitiesCategoriesTests
{
@@ -17,19 +14,10 @@ namespace Jackett.Test.Common.Models
public void TestConstructor()
{
var tcc = new TorznabCapabilitiesCategories();
Assert.IsEmpty(tcc.GetTorznabCategories());
Assert.IsEmpty(tcc.GetTorznabCategoryTree());
Assert.IsEmpty(tcc.GetTrackerCategories());
}
[Test]
public void TestGetTorznabCategories()
{
var tcc = CreateTestDataset();
var cats = tcc.GetTorznabCategories();
Assert.AreEqual(7, cats.Count);
Assert.AreEqual(2000, cats[0].ID);
}
[Test]
public void TestGetTrackerCategories()
{
@@ -39,44 +27,156 @@ namespace Jackett.Test.Common.Models
Assert.AreEqual("1", trackerCats[0]);
}
[Test]
public void TestGetTorznabCategoryTree()
{
var tcc = CreateTestDataset();
// unsorted tree
var cats = tcc.GetTorznabCategoryTree();
var expected = new List<TorznabCategory>
{
TorznabCatType.Movies.CopyWithoutSubCategories(),
TorznabCatType.Books.CopyWithoutSubCategories(),
TorznabCatType.Console.CopyWithoutSubCategories(),
new TorznabCategory(100044, "Console/Xbox_c"),
new TorznabCategory(100040, "Console/Xbox_c2")
};
expected[0].SubCategories.Add(TorznabCatType.MoviesSD.CopyWithoutSubCategories());
expected[1].SubCategories.Add(TorznabCatType.BooksComics.CopyWithoutSubCategories());
expected[2].SubCategories.Add(TorznabCatType.ConsoleXBox.CopyWithoutSubCategories());
expected[2].SubCategories.Add(TorznabCatType.ConsoleWii.CopyWithoutSubCategories());
TestCategories.CompareCategoryTrees(expected, cats);
// sorted tree
cats = tcc.GetTorznabCategoryTree(true);
expected = new List<TorznabCategory>
{
TorznabCatType.Console.CopyWithoutSubCategories(),
TorznabCatType.Movies.CopyWithoutSubCategories(),
TorznabCatType.Books.CopyWithoutSubCategories(),
new TorznabCategory(100044, "Console/Xbox_c"),
new TorznabCategory(100040, "Console/Xbox_c2")
};
expected[0].SubCategories.Add(TorznabCatType.ConsoleWii.CopyWithoutSubCategories());
expected[0].SubCategories.Add(TorznabCatType.ConsoleXBox.CopyWithoutSubCategories());
expected[1].SubCategories.Add(TorznabCatType.MoviesSD.CopyWithoutSubCategories());
expected[2].SubCategories.Add(TorznabCatType.BooksComics.CopyWithoutSubCategories());
TestCategories.CompareCategoryTrees(expected, cats);
}
[Test]
public void TestGetTorznabCategoryList()
{
var tcc = CreateTestDataset();
// unsorted list
var cats = tcc.GetTorznabCategoryList();
var expected = new List<TorznabCategory>
{
TorznabCatType.Movies.CopyWithoutSubCategories(),
TorznabCatType.MoviesSD.CopyWithoutSubCategories(),
TorznabCatType.Books.CopyWithoutSubCategories(),
TorznabCatType.BooksComics.CopyWithoutSubCategories(),
TorznabCatType.Console.CopyWithoutSubCategories(),
TorznabCatType.ConsoleXBox.CopyWithoutSubCategories(),
TorznabCatType.ConsoleWii.CopyWithoutSubCategories(),
new TorznabCategory(100044, "Console/Xbox_c"),
new TorznabCategory(100040, "Console/Xbox_c2")
};
TestCategories.CompareCategoryTrees(expected, cats);
// sorted list
cats = tcc.GetTorznabCategoryList(true);
expected = new List<TorznabCategory>
{
TorznabCatType.Console.CopyWithoutSubCategories(),
TorznabCatType.ConsoleWii.CopyWithoutSubCategories(),
TorznabCatType.ConsoleXBox.CopyWithoutSubCategories(),
TorznabCatType.Movies.CopyWithoutSubCategories(),
TorznabCatType.MoviesSD.CopyWithoutSubCategories(),
TorznabCatType.Books.CopyWithoutSubCategories(),
TorznabCatType.BooksComics.CopyWithoutSubCategories(),
new TorznabCategory(100044, "Console/Xbox_c"),
new TorznabCategory(100040, "Console/Xbox_c2")
};
TestCategories.CompareCategoryTrees(expected, cats);
}
[Test]
public void TestAddCategoryMapping()
{
var tcc = new TorznabCapabilitiesCategories();
var cats = tcc.GetTorznabCategories();
var cats = tcc.GetTorznabCategoryTree();
// add "int" category (parent category)
// + Movies
tcc.AddCategoryMapping("1", TorznabCatType.Movies);
Assert.AreEqual(1, cats.Count);
Assert.AreEqual(2000, cats[0].ID);
var expected = new List<TorznabCategory>
{
TorznabCatType.Movies.CopyWithoutSubCategories()
};
TestCategories.CompareCategoryTrees(expected, cats);
// add "string" category (child category)
// - Movies
// + MoviesSD
tcc.AddCategoryMapping("mov_sd", TorznabCatType.MoviesSD);
Assert.AreEqual(2, cats.Count);
Assert.AreEqual(2030, cats[1].ID);
expected[0].SubCategories.Add(TorznabCatType.MoviesSD.CopyWithoutSubCategories());
TestCategories.CompareCategoryTrees(expected, cats);
// add subcategory of books (child category)
// - Movies
// - MoviesSD
// + Books
// + BooksComics
tcc.AddCategoryMapping("33", TorznabCatType.BooksComics);
Assert.AreEqual(3, cats.Count);
Assert.AreEqual(7030, cats[2].ID);
expected.Add(TorznabCatType.Books.CopyWithoutSubCategories());
expected[1].SubCategories.Add(TorznabCatType.BooksComics.CopyWithoutSubCategories());
TestCategories.CompareCategoryTrees(expected, cats);
// add int category with description => custom category. it's converted into 2 different categories
// - Movies
// - MoviesSD
// - Books
// - BooksComics
// + Console
// + ConsoleXBox
// + Custom Cat "Console/Xbox_c"
tcc.AddCategoryMapping("44", TorznabCatType.ConsoleXBox, "Console/Xbox_c");
Assert.AreEqual(5, cats.Count);
Assert.AreEqual(1040, cats[3].ID);
Assert.AreEqual(100044, cats[4].ID);
expected.Add(TorznabCatType.Console.CopyWithoutSubCategories());
expected[2].SubCategories.Add(TorznabCatType.ConsoleXBox.CopyWithoutSubCategories());
expected.Add(new TorznabCategory(100044, "Console/Xbox_c"));
TestCategories.CompareCategoryTrees(expected, cats);
// TODO: we should add a way to add custom categories for string categories
// https://github.com/Sonarr/Sonarr/wiki/Implementing-a-Torznab-indexer#caps-endpoint
// add string category with description. it's converted into 1 category
// - Movies
// - MoviesSD
// - Books
// - BooksComics
// - Console
// - ConsoleXBox
// + ConsoleWii
// - Custom Cat "Console/Xbox_c"
tcc.AddCategoryMapping("con_wii", TorznabCatType.ConsoleWii, "Console/Wii_c");
Assert.AreEqual(6, cats.Count);
Assert.AreEqual(1030, cats[5].ID);
expected[2].SubCategories.Add(TorznabCatType.ConsoleWii.CopyWithoutSubCategories());
TestCategories.CompareCategoryTrees(expected, cats);
// add another int category with description that maps to ConsoleXbox (there are 2 tracker cats => 1 torznab cat)
// - Movies
// - MoviesSD
// - Books
// - BooksComics
// - Console
// - ConsoleXBox (this is not added again)
// - ConsoleWii
// - Custom Cat "Console/Xbox_c"
// + Custom Cat "Console/Xbox_c2"
tcc.AddCategoryMapping("45", TorznabCatType.ConsoleXBox, "Console/Xbox_c2");
Assert.AreEqual(7, cats.Count);
Assert.AreEqual(100045, cats[6].ID); // 1040 is duplicated and it is not added
expected.Add(new TorznabCategory(100045, "Console/Xbox_c2"));
TestCategories.CompareCategoryTrees(expected, cats);
}
[Test]
@@ -117,7 +217,7 @@ namespace Jackett.Test.Common.Models
trackerCats = tcc.MapTorznabCapsToTrackers(query);
Assert.AreEqual(2, trackerCats.Count);
Assert.AreEqual("44", trackerCats[0]);
Assert.AreEqual("45", trackerCats[1]);
Assert.AreEqual("40", trackerCats[1]);
query = new TorznabQuery // custom cat
{
@@ -155,10 +255,10 @@ namespace Jackett.Test.Common.Models
Assert.AreEqual(2, torznabCats.Count);
Assert.AreEqual(1040, torznabCats[0]);
Assert.AreEqual(100044, torznabCats[1]);
torznabCats = tcc.MapTrackerCatToNewznab("45").ToList();
torznabCats = tcc.MapTrackerCatToNewznab("40").ToList();
Assert.AreEqual(2, torznabCats.Count);
Assert.AreEqual(1040, torznabCats[0]);
Assert.AreEqual(100045, torznabCats[1]);
Assert.AreEqual(100040, torznabCats[1]);
// TODO: this is wrong, we are returning cat 109999 which doesn't exist
//torznabCats = tcc.MapTrackerCatToNewznab("9999").ToList(); // unknown cat
@@ -182,7 +282,7 @@ namespace Jackett.Test.Common.Models
torznabCats = tcc.MapTrackerCatDescToNewznab("Console/Xbox_c2").ToList();
Assert.AreEqual(2, torznabCats.Count);
Assert.AreEqual(1040, torznabCats[0]);
Assert.AreEqual(100045, torznabCats[1]);
Assert.AreEqual(100040, torznabCats[1]);
torznabCats = tcc.MapTrackerCatDescToNewznab("Console/Wii_c").ToList();
Assert.AreEqual(1, torznabCats.Count);
@@ -203,9 +303,8 @@ namespace Jackett.Test.Common.Models
Assert.True(tcc.SupportsCategories(new []{ TorznabCatType.Movies.ID })); // parent cat
Assert.True(tcc.SupportsCategories(new []{ TorznabCatType.MoviesSD.ID })); // child cat
Assert.True(tcc.SupportsCategories(new []{ TorznabCatType.Movies.ID, TorznabCatType.MoviesSD.ID })); // parent & child
Assert.True(tcc.SupportsCategories(new []{ 100044 })); // custom cat
// TODO: fix this
//Assert.False(tcc.SupportsCategories(new []{ TorznabCatType.Movies3D.ID })); // not supported child cat
Assert.True(tcc.SupportsCategories(new []{ 100040 })); // custom cat
Assert.False(tcc.SupportsCategories(new []{ TorznabCatType.Movies3D.ID })); // not supported child cat
Assert.False(tcc.SupportsCategories(new []{ 9999 })); // unknown cat
Assert.False(tcc.SupportsCategories(new int[]{})); // empty list
Assert.False(tcc.SupportsCategories(null)); // null
@@ -216,10 +315,36 @@ namespace Jackett.Test.Common.Models
{
var lhs = new TorznabCapabilitiesCategories();
var rhs = CreateTestDataset();
lhs.Concat(rhs);
Assert.AreEqual(5, lhs.GetTorznabCategories().Count); // removed custom cats
var expected = new List<TorznabCategory>
{
TorznabCatType.Movies.CopyWithoutSubCategories(),
TorznabCatType.Books.CopyWithoutSubCategories(),
TorznabCatType.Console.CopyWithoutSubCategories()
};
expected[0].SubCategories.Add(TorznabCatType.MoviesSD.CopyWithoutSubCategories());
expected[1].SubCategories.Add(TorznabCatType.BooksComics.CopyWithoutSubCategories());
expected[2].SubCategories.Add(TorznabCatType.ConsoleXBox.CopyWithoutSubCategories());
expected[2].SubCategories.Add(TorznabCatType.ConsoleWii.CopyWithoutSubCategories());
TestCategories.CompareCategoryTrees(expected, lhs.GetTorznabCategoryTree()); // removed custom cats
Assert.AreEqual(0, lhs.GetTrackerCategories().Count); // removed tracker mapping
lhs = CreateTestDataset();
rhs = CreateTestDataset();
lhs.Concat(rhs);
expected = new List<TorznabCategory>
{
TorznabCatType.Movies.CopyWithoutSubCategories(),
TorznabCatType.Books.CopyWithoutSubCategories(),
TorznabCatType.Console.CopyWithoutSubCategories(),
new TorznabCategory(100044, "Console/Xbox_c"),
new TorznabCategory(100040, "Console/Xbox_c2")
};
expected[0].SubCategories.Add(TorznabCatType.MoviesSD.CopyWithoutSubCategories());
expected[1].SubCategories.Add(TorznabCatType.BooksComics.CopyWithoutSubCategories());
expected[2].SubCategories.Add(TorznabCatType.ConsoleXBox.CopyWithoutSubCategories());
expected[2].SubCategories.Add(TorznabCatType.ConsoleWii.CopyWithoutSubCategories());
TestCategories.CompareCategoryTrees(expected, lhs.GetTorznabCategoryTree()); // check there are not duplicates
}
private static TorznabCapabilitiesCategories CreateTestDataset()

View File

@@ -42,7 +42,7 @@ namespace Jackett.Test.Common.Models
Assert.False(torznabCaps.BookSearchTitleAvailable);
Assert.False(torznabCaps.BookSearchAuthorAvailable);
Assert.IsEmpty(torznabCaps.Categories.GetTorznabCategories());
Assert.IsEmpty(torznabCaps.Categories.GetTorznabCategoryTree());
Assert.IsEmpty(torznabCaps.Categories.GetTrackerCategories());
}
@@ -405,40 +405,32 @@ namespace Jackett.Test.Common.Models
Assert.AreEqual("q,title,author", xDocumentSearching?.Element("book-search")?.Attribute("supportedParams")?.Value);
// test categories
torznabCaps = new TorznabCapabilities();
torznabCaps.Categories.AddCategoryMapping("c1", TorznabCatType.MoviesSD); // child category
torznabCaps = new TorznabCapabilities(); // child category
torznabCaps.Categories.AddCategoryMapping("c1", TorznabCatType.MoviesSD);
xDocument = torznabCaps.GetXDocument();
var xDocumentCategories = xDocument.Root?.Element("categories")?.Elements("category").ToList();
Assert.AreEqual(1, xDocumentCategories?.Count);
Assert.AreEqual(TorznabCatType.MoviesSD.ID.ToString(), xDocumentCategories?.First().Attribute("id")?.Value);
Assert.AreEqual(TorznabCatType.MoviesSD.Name, xDocumentCategories?.First().Attribute("name")?.Value);
Assert.AreEqual(TorznabCatType.Movies.ID.ToString(), xDocumentCategories?[0].Attribute("id")?.Value);
Assert.AreEqual(TorznabCatType.Movies.Name, xDocumentCategories?[0].Attribute("name")?.Value);
var xDocumentSubCategories = xDocumentCategories?[0]?.Elements("subcat").ToList();
Assert.AreEqual(1, xDocumentSubCategories?.Count);
Assert.AreEqual(TorznabCatType.MoviesSD.ID.ToString(), xDocumentSubCategories?[0].Attribute("id")?.Value);
Assert.AreEqual(TorznabCatType.MoviesSD.Name, xDocumentSubCategories?[0].Attribute("name")?.Value);
// TODO: child category is duplicated. should we add just parent and child without other subcats?
torznabCaps = new TorznabCapabilities();
torznabCaps.Categories.AddCategoryMapping("c1", TorznabCatType.Movies); // parent and child category
torznabCaps = new TorznabCapabilities(); // parent (with description generates a custom cat) and child category
torznabCaps.Categories.AddCategoryMapping("1", TorznabCatType.Movies, "Classic Movies");
torznabCaps.Categories.AddCategoryMapping("c2", TorznabCatType.MoviesSD);
xDocument = torznabCaps.GetXDocument();
xDocumentCategories = xDocument.Root?.Element("categories")?.Elements("category").ToList();
Assert.AreEqual(2, xDocumentCategories?.Count);
Assert.AreEqual(TorznabCatType.Movies.ID.ToString(), xDocumentCategories?.First().Attribute("id")?.Value);
Assert.AreEqual(TorznabCatType.Movies.Name, xDocumentCategories?.First().Attribute("name")?.Value);
Assert.AreEqual(TorznabCatType.MoviesSD.ID.ToString(), xDocumentCategories?[1].Attribute("id")?.Value);
Assert.AreEqual(TorznabCatType.MoviesSD.Name, xDocumentCategories?[1].Attribute("name")?.Value);
var xDocumentSubCategories = xDocumentCategories?.First()?.Elements("subcat").ToList();
Assert.AreEqual(9, xDocumentSubCategories?.Count);
Assert.AreEqual(TorznabCatType.MoviesForeign.ID.ToString(), xDocumentSubCategories?.First().Attribute("id")?.Value);
Assert.AreEqual(TorznabCatType.MoviesForeign.Name, xDocumentSubCategories?.First().Attribute("name")?.Value);
torznabCaps = new TorznabCapabilities();
torznabCaps.Categories.AddCategoryMapping("c1", new TorznabCategory(100001, "CustomCat")); // custom category
torznabCaps.Categories.AddCategoryMapping("c2", TorznabCatType.MoviesSD);
xDocument = torznabCaps.GetXDocument();
xDocumentCategories = xDocument.Root?.Element("categories")?.Elements("category").ToList();
Assert.AreEqual(2, xDocumentCategories?.Count);
Assert.AreEqual("100001", xDocumentCategories?[0].Attribute("id")?.Value); // custom cats are first in the list
Assert.AreEqual("CustomCat", xDocumentCategories?[0].Attribute("name")?.Value);
Assert.AreEqual(TorznabCatType.MoviesSD.ID.ToString(), xDocumentCategories?[1].Attribute("id")?.Value);
Assert.AreEqual(TorznabCatType.MoviesSD.Name, xDocumentCategories?[1].Attribute("name")?.Value);
Assert.AreEqual(TorznabCatType.Movies.ID.ToString(), xDocumentCategories?[0].Attribute("id")?.Value);
Assert.AreEqual(TorznabCatType.Movies.Name, xDocumentCategories?[0].Attribute("name")?.Value);
xDocumentSubCategories = xDocumentCategories?[0]?.Elements("subcat").ToList();
Assert.AreEqual(1, xDocumentSubCategories?.Count);
Assert.AreEqual(TorznabCatType.MoviesSD.ID.ToString(), xDocumentSubCategories?[0].Attribute("id")?.Value);
Assert.AreEqual(TorznabCatType.MoviesSD.Name, xDocumentSubCategories?[0].Attribute("name")?.Value);
Assert.AreEqual("100001", xDocumentCategories?[1].Attribute("id")?.Value); // custom cats are first in the list
Assert.AreEqual("Classic Movies", xDocumentCategories?[1].Attribute("name")?.Value);
}
[Test]
@@ -450,15 +442,17 @@ namespace Jackett.Test.Common.Models
// test Torznab caps (XML) => more in Common.Model.TorznabCapabilitiesTests
var xDocument = torznabCaps.GetXDocument();
var xDocumentCategories = xDocument.Root?.Element("categories")?.Elements("category").ToList();
Assert.AreEqual(7, xDocumentCategories?.Count);
Assert.AreEqual("100044", xDocumentCategories?[0].Attribute("id")?.Value);
Assert.AreEqual("100045", xDocumentCategories?[1].Attribute("id")?.Value);
Assert.AreEqual("1030", xDocumentCategories?[2].Attribute("id")?.Value);
Assert.AreEqual("1040", xDocumentCategories?[3].Attribute("id")?.Value);
Assert.AreEqual("2000", xDocumentCategories?[4].Attribute("id")?.Value); // Movies
Assert.AreEqual("2030", xDocumentCategories?[5].Attribute("id")?.Value);
Assert.AreEqual("7030", xDocumentCategories?[6].Attribute("id")?.Value);
Assert.AreEqual(9, xDocumentCategories?[4]?.Elements("subcat").ToList().Count); // Movies
Assert.AreEqual(5, xDocumentCategories?.Count);
Assert.AreEqual("1000", xDocumentCategories?[0].Attribute("id")?.Value);
Assert.AreEqual(2, xDocumentCategories?[0]?.Elements("subcat").ToList().Count);
Assert.AreEqual("2000", xDocumentCategories?[1].Attribute("id")?.Value);
Assert.AreEqual(1, xDocumentCategories?[1]?.Elements("subcat").ToList().Count);
Assert.AreEqual("7000", xDocumentCategories?[2].Attribute("id")?.Value);
Assert.AreEqual(1, xDocumentCategories?[2]?.Elements("subcat").ToList().Count);
Assert.AreEqual("100044", xDocumentCategories?[3].Attribute("id")?.Value);
Assert.AreEqual(0, xDocumentCategories?[3]?.Elements("subcat").ToList().Count);
Assert.AreEqual("100040", xDocumentCategories?[4].Attribute("id")?.Value);
Assert.AreEqual(0, xDocumentCategories?[4]?.Elements("subcat").ToList().Count);
}
[Test]
@@ -473,7 +467,7 @@ namespace Jackett.Test.Common.Models
Assert.IsEmpty(res.MovieSearchParams);
Assert.IsEmpty(res.MusicSearchParams);
Assert.IsEmpty(res.BookSearchParams);
Assert.IsEmpty(res.Categories.GetTorznabCategories());
Assert.IsEmpty(res.Categories.GetTorznabCategoryTree());
torznabCaps1 = new TorznabCapabilities
{
@@ -502,7 +496,7 @@ namespace Jackett.Test.Common.Models
Assert.True(res.MovieSearchParams.Count == 2);
Assert.True(res.MusicSearchParams.Count == 2);
Assert.True(res.BookSearchParams.Count == 2);
Assert.True(res.Categories.GetTorznabCategories().Count == 3); // only CustomCat2 is removed
Assert.True(res.Categories.GetTorznabCategoryTree().Count == 3); // only CustomCat2 is removed
}
}
}

View File

@@ -1,4 +1,6 @@
using System.Collections.Generic;
using Jackett.Common.Models;
using NUnit.Framework;
namespace Jackett.Test.TestHelpers
{
@@ -11,12 +13,24 @@ namespace Jackett.Test.TestHelpers
// - with and without description
// - parent and child categories
// - custom categories are not added automatically but they are created from other categories automatically
// - categories and subcategories are unsorted to test the sort when required
tcc.AddCategoryMapping("1", TorznabCatType.Movies);
tcc.AddCategoryMapping("mov_sd", TorznabCatType.MoviesSD);
tcc.AddCategoryMapping("33", TorznabCatType.BooksComics);
tcc.AddCategoryMapping("44", TorznabCatType.ConsoleXBox, "Console/Xbox_c");
tcc.AddCategoryMapping("con_wii", TorznabCatType.ConsoleWii, "Console/Wii_c");
tcc.AddCategoryMapping("45", TorznabCatType.ConsoleXBox, "Console/Xbox_c2");
tcc.AddCategoryMapping("40", TorznabCatType.ConsoleXBox, "Console/Xbox_c2");
}
public static void CompareCategoryTrees(List<TorznabCategory> tree1, List<TorznabCategory> tree2)
{
Assert.AreEqual(tree1.Count, tree2.Count);
for (var i = 0; i < tree1.Count; i++)
{
Assert.AreEqual(tree1[i].ID, tree2[i].ID);
Assert.AreEqual(tree1[i].Name, tree2[i].Name);
CompareCategoryTrees(tree1[i].SubCategories, tree2[i].SubCategories);
}
}
}
}