mirror of
https://github.com/Jackett/Jackett.git
synced 2025-09-17 17:34:09 +02:00
* 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:
@@ -266,9 +266,21 @@ namespace Jackett.Common.Indexers
|
||||
if (query.Categories.Length == 0)
|
||||
return results;
|
||||
|
||||
var filteredResults = results.Where(
|
||||
result => result.Category?.Any() != true || query.Categories.Intersect(result.Category).Any() ||
|
||||
TorznabCatType.QueryContainsParentCategory(query.Categories, result.Category));
|
||||
// TODO: move this code to TorznabCapabilitiesCategories and use indexer tree instead of general
|
||||
// expand parent categories from the query
|
||||
var expandedQueryCats = new List<int>();
|
||||
foreach (var queryCategory in query.Categories)
|
||||
{
|
||||
expandedQueryCats.Add(queryCategory);
|
||||
var parentCat = TorznabCatType.ParentCats.FirstOrDefault(c => c.ID == queryCategory);
|
||||
if (parentCat != null)
|
||||
expandedQueryCats.AddRange(parentCat.SubCategories.Select(c => c.ID));
|
||||
}
|
||||
|
||||
var filteredResults = results.Where(result =>
|
||||
result.Category?.Any() != true ||
|
||||
expandedQueryCats.Intersect(result.Category).Any()
|
||||
);
|
||||
|
||||
return filteredResults;
|
||||
}
|
||||
|
@@ -51,14 +51,11 @@ namespace Jackett.Common.Models.DTO
|
||||
site_link = indexer.SiteLink;
|
||||
language = indexer.Language;
|
||||
last_error = indexer.LastError;
|
||||
potatoenabled = indexer.TorznabCaps.Categories.GetTorznabCategories().Any(i => TorznabCatType.Movies.Contains(i));
|
||||
potatoenabled = indexer.TorznabCaps.Categories.GetTorznabCategoryTree().Any(i => TorznabCatType.Movies.Contains(i));
|
||||
|
||||
alternativesitelinks = indexer.AlternativeSiteLinks;
|
||||
|
||||
caps = indexer.TorznabCaps.Categories.GetTorznabCategories()
|
||||
.GroupBy(p => p.ID)
|
||||
.Select(g => g.First())
|
||||
.OrderBy(c => c.ID < 100000 ? "z" + c.ID.ToString() : c.Name)
|
||||
caps = indexer.TorznabCaps.Categories.GetTorznabCategoryList(true)
|
||||
.Select(c => new Capability
|
||||
{
|
||||
ID = c.ID.ToString(),
|
||||
|
@@ -250,7 +250,7 @@ namespace Jackett.Common.Models
|
||||
new XAttribute("available", MusicSearchAvailable ? "yes" : "no"),
|
||||
new XAttribute("supportedParams", SupportedMusicSearchParams())
|
||||
),
|
||||
// inconsistend but apparently already used by various newznab indexers (see #1896)
|
||||
// inconsistent but apparently already used by various newznab indexers (see #1896)
|
||||
new XElement("audio-search",
|
||||
new XAttribute("available", MusicSearchAvailable ? "yes" : "no"),
|
||||
new XAttribute("supportedParams", SupportedMusicSearchParams())
|
||||
@@ -261,7 +261,7 @@ namespace Jackett.Common.Models
|
||||
)
|
||||
),
|
||||
new XElement("categories",
|
||||
from c in Categories.GetTorznabCategories().OrderBy(x => x.ID < 100000 ? "z" + x.ID.ToString() : x.Name)
|
||||
from c in Categories.GetTorznabCategoryTree(true)
|
||||
select new XElement("category",
|
||||
new XAttribute("id", c.ID),
|
||||
new XAttribute("name", c.Name),
|
||||
|
@@ -6,21 +6,52 @@ namespace Jackett.Common.Models
|
||||
{
|
||||
public class TorznabCapabilitiesCategories
|
||||
{
|
||||
private readonly List<TorznabCategory> _categories = new List<TorznabCategory>();
|
||||
private readonly List<CategoryMapping> _categoryMapping = new List<CategoryMapping>();
|
||||
|
||||
public List<TorznabCategory> GetTorznabCategories() => _categories;
|
||||
private readonly List<TorznabCategory> _torznabCategoryTree = new List<TorznabCategory>();
|
||||
|
||||
public List<string> GetTrackerCategories() => _categoryMapping.Select(x => x.TrackerCategory).ToList();
|
||||
|
||||
public List<TorznabCategory> GetTorznabCategoryTree(bool sorted = false)
|
||||
{
|
||||
if (!sorted)
|
||||
return _torznabCategoryTree;
|
||||
|
||||
// we build a new tree, original is unsorted
|
||||
// first torznab categories ordered by id and then custom cats ordered by name
|
||||
var sortedTree = _torznabCategoryTree
|
||||
.Select(c =>
|
||||
{
|
||||
var sortedSubCats = c.SubCategories.OrderBy(x => x.ID);
|
||||
var newCat = new TorznabCategory(c.ID, c.Name);
|
||||
newCat.SubCategories.AddRange(sortedSubCats);
|
||||
return newCat;
|
||||
}).OrderBy(x => x.ID > 100000 ? "zzz" + x.Name : x.ID.ToString()).ToList();
|
||||
|
||||
return sortedTree;
|
||||
}
|
||||
|
||||
public List<TorznabCategory> GetTorznabCategoryList(bool sorted = false)
|
||||
{
|
||||
var tree = GetTorznabCategoryTree(sorted);
|
||||
|
||||
// create a flat list (without subcategories)
|
||||
var newFlatList = new List<TorznabCategory>();
|
||||
foreach (var cat in tree)
|
||||
{
|
||||
newFlatList.Add(cat.CopyWithoutSubCategories());
|
||||
newFlatList.AddRange(cat.SubCategories);
|
||||
}
|
||||
return newFlatList;
|
||||
}
|
||||
|
||||
public void AddCategoryMapping(string trackerCategory, TorznabCategory torznabCategory, string trackerCategoryDesc = null)
|
||||
{
|
||||
// add torznab cat
|
||||
_categoryMapping.Add(new CategoryMapping(trackerCategory, trackerCategoryDesc, torznabCategory.ID));
|
||||
AddTorznabCategoryTree(torznabCategory);
|
||||
|
||||
if (!_categories.Contains(torznabCategory))
|
||||
_categories.Add(torznabCategory);
|
||||
|
||||
// add 1:1 categories
|
||||
// TODO: fix this. it's only working for integer "trackerCategory"
|
||||
// create custom cats (1:1 categories)
|
||||
if (trackerCategoryDesc != null && trackerCategory != null)
|
||||
{
|
||||
//TODO convert to int.TryParse() to avoid using throw as flow control
|
||||
@@ -28,8 +59,7 @@ namespace Jackett.Common.Models
|
||||
{
|
||||
var trackerCategoryInt = int.Parse(trackerCategory);
|
||||
var customCat = new TorznabCategory(trackerCategoryInt + 100000, trackerCategoryDesc);
|
||||
if (!_categories.Contains(customCat))
|
||||
_categories.Add(customCat);
|
||||
AddTorznabCategoryTree(customCat);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
@@ -131,15 +161,54 @@ namespace Jackett.Common.Models
|
||||
{
|
||||
if (categories == null)
|
||||
return false;
|
||||
var subCategories = _categories.SelectMany(c => c.SubCategories);
|
||||
var allCategories = _categories.Concat(subCategories);
|
||||
var subCategories = _torznabCategoryTree.SelectMany(c => c.SubCategories);
|
||||
var allCategories = _torznabCategoryTree.Concat(subCategories);
|
||||
var supportsCategory = allCategories.Any(i => categories.Any(c => c == i.ID));
|
||||
return supportsCategory;
|
||||
}
|
||||
|
||||
public void Concat(TorznabCapabilitiesCategories rhs) =>
|
||||
public void Concat(TorznabCapabilitiesCategories rhs)
|
||||
{
|
||||
// exclude indexer specific categories (>= 100000)
|
||||
// we don't concat _categoryMapping because it makes no sense for the aggregate indexer
|
||||
_categories.AddRange(rhs._categories.Where(x => x.ID < 100000).Except(_categories));
|
||||
rhs.GetTorznabCategoryList().Where(x => x.ID < 100000).ToList().ForEach(AddTorznabCategoryTree);
|
||||
}
|
||||
|
||||
private void AddTorznabCategoryTree(TorznabCategory torznabCategory)
|
||||
{
|
||||
// build the category tree
|
||||
if (TorznabCatType.ParentCats.Contains(torznabCategory))
|
||||
{
|
||||
// parent cat
|
||||
if (!_torznabCategoryTree.Contains(torznabCategory))
|
||||
_torznabCategoryTree.Add(torznabCategory.CopyWithoutSubCategories());
|
||||
}
|
||||
else
|
||||
{
|
||||
// child or custom cat
|
||||
var parentCat = TorznabCatType.ParentCats.FirstOrDefault(c => c.Contains(torznabCategory));
|
||||
if (parentCat != null)
|
||||
{
|
||||
// child cat
|
||||
var nodeCat = _torznabCategoryTree.FirstOrDefault(c => c.Equals(parentCat));
|
||||
if (nodeCat != null)
|
||||
{
|
||||
// parent cat already exists
|
||||
if (!nodeCat.Contains(torznabCategory))
|
||||
nodeCat.SubCategories.Add(torznabCategory);
|
||||
}
|
||||
else
|
||||
{
|
||||
// create parent cat and add child
|
||||
nodeCat = parentCat.CopyWithoutSubCategories();
|
||||
nodeCat.SubCategories.Add(torznabCategory);
|
||||
_torznabCategoryTree.Add(nodeCat);
|
||||
}
|
||||
}
|
||||
else
|
||||
// custom cat
|
||||
_torznabCategoryTree.Add(torznabCategory);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -265,27 +265,8 @@ namespace Jackett.Common.Models
|
||||
Other.SubCategories.AddRange(new List<TorznabCategory> {OtherMisc, OtherHashed});
|
||||
}
|
||||
|
||||
public static bool QueryContainsParentCategory(int[] queryCats, ICollection<int> releaseCats)
|
||||
{
|
||||
//return (from releaseCat in releaseCats
|
||||
// select AllCats.FirstOrDefault(c => c.ID == releaseCat)
|
||||
// into cat
|
||||
// where cat != null && queryCats != null
|
||||
// select cat.SubCategories.Any(c => queryCats.Contains(c.ID)))
|
||||
// .FirstOrDefault();
|
||||
// Is equal to:
|
||||
foreach (var releaseCat in releaseCats)
|
||||
{
|
||||
var cat = AllCats.FirstOrDefault(c => c.ID == releaseCat);
|
||||
if (cat != null && queryCats != null)
|
||||
return cat.SubCategories.Any(c => queryCats.Contains(c.ID));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string GetCatDesc(int newznabcat) =>
|
||||
AllCats.FirstOrDefault(c => c.ID == newznabcat)?.Name ?? string.Empty;
|
||||
public static string GetCatDesc(int torznabCatId) =>
|
||||
AllCats.FirstOrDefault(c => c.ID == torznabCatId)?.Name ?? string.Empty;
|
||||
|
||||
public static TorznabCategory GetCatByName(string name) => AllCats.FirstOrDefault(c => c.Name == name);
|
||||
}
|
||||
|
@@ -34,5 +34,7 @@ namespace Jackett.Common.Models
|
||||
// Get Hash code should be calculated off read only properties.
|
||||
// ID is not readonly
|
||||
public override int GetHashCode() => ID;
|
||||
|
||||
public TorznabCategory CopyWithoutSubCategories() => new TorznabCategory(ID, Name);
|
||||
}
|
||||
}
|
||||
|
@@ -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]
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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);
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user