From af39793b7c68b67eb5b543298c9a03a2f12626a6 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Thu, 10 Jun 2021 21:01:50 +0200 Subject: [PATCH] Testing more the base repository class --- Kyoo.Common/Controllers/IRepository.cs | 43 +-------- Kyoo.CommonAPI/CrudApi.cs | 2 +- Kyoo.CommonAPI/LocalRepository.cs | 27 +----- Kyoo.Tests/Library/RepositoryActivator.cs | 3 +- Kyoo.Tests/Library/RepositoryTests.cs | 94 ++++++++++++++++++- Kyoo.Tests/Library/SpecificTests/ShowTests.cs | 17 ++++ .../Repositories/EpisodeRepository.cs | 2 +- .../Repositories/SeasonRepository.cs | 17 +--- 8 files changed, 124 insertions(+), 81 deletions(-) diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Common/Controllers/IRepository.cs index 3db8d475..352ebe04 100644 --- a/Kyoo.Common/Controllers/IRepository.cs +++ b/Kyoo.Common/Controllers/IRepository.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Linq.Expressions; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -242,49 +241,13 @@ namespace Kyoo.Controllers /// The resource to delete /// If the item is not found Task Delete([NotNull] T obj); - + /// - /// Delete a list of resources. - /// - /// One or multiple resources to delete - /// If the item is not found - Task DeleteRange(params T[] objs) => DeleteRange(objs.AsEnumerable()); - /// - /// Delete a list of resources. - /// - /// An enumerable of resources to delete - /// If the item is not found - Task DeleteRange(IEnumerable objs); - /// - /// Delete a list of resources. - /// - /// One or multiple resource's id - /// If the item is not found - Task DeleteRange(params int[] ids) => DeleteRange(ids.AsEnumerable()); - /// - /// Delete a list of resources. - /// - /// An enumerable of resource's id - /// If the item is not found - Task DeleteRange(IEnumerable ids); - /// - /// Delete a list of resources. - /// - /// One or multiple resource's slug - /// If the item is not found - Task DeleteRange(params string[] slugs) => DeleteRange(slugs.AsEnumerable()); - /// - /// Delete a list of resources. - /// - /// An enumerable of resource's slug - /// If the item is not found - Task DeleteRange(IEnumerable slugs); - /// - /// Delete a list of resources. + /// Delete all resources that match the predicate. /// /// A predicate to filter resources to delete. Every resource that match this will be deleted. /// If the item is not found - Task DeleteRange([NotNull] Expression> where); + Task DeleteAll([NotNull] Expression> where); } /// diff --git a/Kyoo.CommonAPI/CrudApi.cs b/Kyoo.CommonAPI/CrudApi.cs index b6d03580..336d3226 100644 --- a/Kyoo.CommonAPI/CrudApi.cs +++ b/Kyoo.CommonAPI/CrudApi.cs @@ -194,7 +194,7 @@ namespace Kyoo.CommonApi { try { - await _repository.DeleteRange(ApiHelper.ParseWhere(where)); + await _repository.DeleteAll(ApiHelper.ParseWhere(where)); } catch (ItemNotFoundException) { diff --git a/Kyoo.CommonAPI/LocalRepository.cs b/Kyoo.CommonAPI/LocalRepository.cs index 42653843..9c23c774 100644 --- a/Kyoo.CommonAPI/LocalRepository.cs +++ b/Kyoo.CommonAPI/LocalRepository.cs @@ -295,31 +295,10 @@ namespace Kyoo.Controllers public abstract Task Delete(T obj); /// - public virtual async Task DeleteRange(IEnumerable objs) + public async Task DeleteAll(Expression> where) { - foreach (T obj in objs) - await Delete(obj); - } - - /// - public virtual async Task DeleteRange(IEnumerable ids) - { - foreach (int id in ids) - await Delete(id); - } - - /// - public virtual async Task DeleteRange(IEnumerable slugs) - { - foreach (string slug in slugs) - await Delete(slug); - } - - /// - public async Task DeleteRange(Expression> where) - { - ICollection resources = await GetAll(where); - await DeleteRange(resources); + foreach (T resource in await GetAll(where)) + await Delete(resource); } } } \ No newline at end of file diff --git a/Kyoo.Tests/Library/RepositoryActivator.cs b/Kyoo.Tests/Library/RepositoryActivator.cs index 42468a49..7352a781 100644 --- a/Kyoo.Tests/Library/RepositoryActivator.cs +++ b/Kyoo.Tests/Library/RepositoryActivator.cs @@ -25,8 +25,7 @@ namespace Kyoo.Tests PeopleRepository people = new(_database, provider, new Lazy(() => LibraryManager.ShowRepository)); ShowRepository show = new(_database, studio, people, genre, provider); - SeasonRepository season = new(_database, provider, show, - new Lazy(() => LibraryManager.EpisodeRepository)); + SeasonRepository season = new(_database, provider, show); LibraryItemRepository libraryItem = new(_database, new Lazy(() => LibraryManager.LibraryRepository), new Lazy(() => LibraryManager.ShowRepository), diff --git a/Kyoo.Tests/Library/RepositoryTests.cs b/Kyoo.Tests/Library/RepositoryTests.cs index e8504a16..82482bc7 100644 --- a/Kyoo.Tests/Library/RepositoryTests.cs +++ b/Kyoo.Tests/Library/RepositoryTests.cs @@ -1,4 +1,7 @@ +using System; +using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; using System.Threading.Tasks; using Kyoo.Controllers; using Kyoo.Models; @@ -8,7 +11,7 @@ using Xunit; namespace Kyoo.Tests { public abstract class RepositoryTests - where T : class, IResource + where T : class, IResource, new() { protected readonly RepositoryActivator Repositories; private readonly IRepository _repository; @@ -86,5 +89,94 @@ namespace Kyoo.Tests await _repository.Create(expected); KAssert.DeepEqual(expected, await _repository.Get(expected.Slug)); } + + [Fact] + public async Task CreateNullTest() + { + await Assert.ThrowsAsync(() => _repository.Create(null!)); + } + + [Fact] + public async Task CreateIfNotExistNullTest() + { + await Assert.ThrowsAsync(() => _repository.CreateIfNotExists(null!)); + } + + [Fact] + public async Task CreateIfNotExistTest() + { + T expected = TestSample.Get(); + KAssert.DeepEqual(expected, await _repository.CreateIfNotExists(TestSample.Get())); + await _repository.Delete(TestSample.Get()); + KAssert.DeepEqual(expected, await _repository.CreateIfNotExists(TestSample.Get())); + } + + [Fact] + public async Task EditNullTest() + { + await Assert.ThrowsAsync(() => _repository.Edit(null!, false)); + } + + [Fact] + public async Task EditNonExistingTest() + { + await Assert.ThrowsAsync(() => _repository.Edit(new T {ID = 56}, false)); + } + + [Fact] + public async Task GetExpressionIDTest() + { + KAssert.DeepEqual(TestSample.Get(), await _repository.Get(x => x.ID == TestSample.Get().ID)); + } + + [Fact] + public async Task GetExpressionSlugTest() + { + KAssert.DeepEqual(TestSample.Get(), await _repository.Get(x => x.Slug == TestSample.Get().Slug)); + } + + [Fact] + public async Task GetExpressionNotFoundTest() + { + await Assert.ThrowsAsync(() => _repository.Get(x => x.Slug == "non-existing")); + } + + [Fact] + public async Task GetExpressionNullTest() + { + await Assert.ThrowsAsync(() => _repository.Get((Expression>)null!)); + } + + [Fact] + public async Task GetOrDefaultTest() + { + Assert.Null(await _repository.GetOrDefault(56)); + Assert.Null(await _repository.GetOrDefault("non-existing")); + Assert.Null(await _repository.GetOrDefault(x => x.Slug == "non-existing")); + } + + [Fact] + public async Task GetCountWithFilterTest() + { + string slug = TestSample.Get().Slug[2..4]; + Assert.Equal(1, await _repository.GetCount(x => x.Slug.Contains(slug))); + } + + [Fact] + public async Task GetAllTest() + { + string slug = TestSample.Get().Slug[2..4]; + ICollection ret = await _repository.GetAll(x => x.Slug.Contains(slug)); + Assert.Equal(1, ret.Count); + KAssert.DeepEqual(TestSample.Get(), ret.First()); + } + + [Fact] + public async Task DeleteAllTest() + { + string slug = TestSample.Get().Slug[2..4]; + await _repository.DeleteAll(x => x.Slug.Contains(slug)); + Assert.Equal(0, await _repository.GetCount()); + } } } \ No newline at end of file diff --git a/Kyoo.Tests/Library/SpecificTests/ShowTests.cs b/Kyoo.Tests/Library/SpecificTests/ShowTests.cs index c49ca824..183780aa 100644 --- a/Kyoo.Tests/Library/SpecificTests/ShowTests.cs +++ b/Kyoo.Tests/Library/SpecificTests/ShowTests.cs @@ -216,5 +216,22 @@ namespace Kyoo.Tests.SpecificTests Show created = await _repository.Create(expected); KAssert.DeepEqual(expected, created); } + + [Fact] + public async Task SlugDuplicationTest() + { + Show test = TestSample.Get(); + test.ID = 0; + test.Slug = "300"; + Show created = await _repository.Create(test); + Assert.Equal("300!", created.Slug); + } + + [Fact] + public async Task GetSlugTest() + { + Show reference = TestSample.Get(); + Assert.Equal(reference.Slug, await _repository.GetSlug(reference.ID)); + } } } \ No newline at end of file diff --git a/Kyoo/Controllers/Repositories/EpisodeRepository.cs b/Kyoo/Controllers/Repositories/EpisodeRepository.cs index 46c8d62c..e6765c13 100644 --- a/Kyoo/Controllers/Repositories/EpisodeRepository.cs +++ b/Kyoo/Controllers/Repositories/EpisodeRepository.cs @@ -195,7 +195,7 @@ namespace Kyoo.Controllers if (changed.Tracks != null || resetOld) { - await _tracks.DeleteRange(x => x.EpisodeID == resource.ID); + await _tracks.DeleteAll(x => x.EpisodeID == resource.ID); resource.Tracks = changed.Tracks; await ValidateTracks(resource); } diff --git a/Kyoo/Controllers/Repositories/SeasonRepository.cs b/Kyoo/Controllers/Repositories/SeasonRepository.cs index 1f31ace7..ad3d5064 100644 --- a/Kyoo/Controllers/Repositories/SeasonRepository.cs +++ b/Kyoo/Controllers/Repositories/SeasonRepository.cs @@ -27,11 +27,7 @@ namespace Kyoo.Controllers /// A show repository to get show's slug from their ID and keep the slug in each episode. /// private readonly IShowRepository _shows; - /// - /// A lazilly loaded episode repository to handle deletion of episodes with the season. - /// - private readonly Lazy _episodes; - + /// protected override Expression> DefaultSort => x => x.SeasonNumber; @@ -43,17 +39,14 @@ namespace Kyoo.Controllers /// The database handle that will be used /// A provider repository /// A show repository - /// A lazy loaded episode repository. public SeasonRepository(DatabaseContext database, IProviderRepository providers, - IShowRepository shows, - Lazy episodes) + IShowRepository shows) : base(database) { _database = database; _providers = providers; _shows = shows; - _episodes = episodes; } @@ -186,9 +179,9 @@ namespace Kyoo.Controllers _database.Entry(obj).State = EntityState.Deleted; obj.ExternalIDs.ForEach(x => _database.Entry(x).State = EntityState.Deleted); await _database.SaveChangesAsync(); - - if (obj.Episodes != null) - await _episodes.Value.DeleteRange(obj.Episodes); + // + // if (obj.Episodes != null) + // await _episodes.Value.DeleteRange(obj.Episodes); } } } \ No newline at end of file