diff --git a/Kyoo.Tests/Database/SpecificTests/EpisodeTests.cs b/Kyoo.Tests/Database/SpecificTests/EpisodeTests.cs index d9e0e9ff..77a2c395 100644 --- a/Kyoo.Tests/Database/SpecificTests/EpisodeTests.cs +++ b/Kyoo.Tests/Database/SpecificTests/EpisodeTests.cs @@ -1,6 +1,9 @@ +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Kyoo.Controllers; using Kyoo.Models; +using Microsoft.EntityFrameworkCore; using Xunit; using Xunit.Abstractions; @@ -92,10 +95,6 @@ namespace Kyoo.Tests.Database }); Assert.Equal($"{TestSample.Get().Slug}-s2e4", episode.Slug); } - - - // TODO absolute numbering tests - [Fact] public void AbsoluteSlugTest() @@ -188,5 +187,137 @@ namespace Kyoo.Tests.Database Episode episode = await _repository.Get(3); Assert.Equal("john-wick", episode.Slug); } + + [Fact] + public async Task CreateWithExternalIdTest() + { + Episode value = TestSample.GetNew(); + value.ExternalIDs = new[] + { + new MetadataID + { + Provider = TestSample.Get(), + Link = "link", + DataID = "id" + }, + new MetadataID + { + Provider = TestSample.GetNew(), + Link = "new-provider-link", + DataID = "new-id" + } + }; + await _repository.Create(value); + + Episode retrieved = await _repository.Get(2); + await Repositories.LibraryManager.Load(retrieved, x => x.ExternalIDs); + Assert.Equal(2, retrieved.ExternalIDs.Count); + KAssert.DeepEqual(value.ExternalIDs.First(), retrieved.ExternalIDs.First()); + KAssert.DeepEqual(value.ExternalIDs.Last(), retrieved.ExternalIDs.Last()); + } + + [Fact] + public async Task EditTest() + { + Episode value = await _repository.Get(TestSample.Get().Slug); + value.Title = "New Title"; + value.Images = new Dictionary + { + [Images.Poster] = "new-poster" + }; + await _repository.Edit(value, false); + + await using DatabaseContext database = Repositories.Context.New(); + Episode retrieved = await database.Episodes.FirstAsync(); + + KAssert.DeepEqual(value, retrieved); + } + + [Fact] + public async Task EditMetadataTest() + { + Episode value = await _repository.Get(TestSample.Get().Slug); + value.ExternalIDs = new[] + { + new MetadataID + { + Provider = TestSample.Get(), + Link = "link", + DataID = "id" + }, + }; + await _repository.Edit(value, false); + + await using DatabaseContext database = Repositories.Context.New(); + Episode retrieved = await database.Episodes + .Include(x => x.ExternalIDs) + .ThenInclude(x => x.Provider) + .FirstAsync(); + + KAssert.DeepEqual(value, retrieved); + } + + [Fact] + public async Task AddMetadataTest() + { + Episode value = await _repository.Get(TestSample.Get().Slug); + value.ExternalIDs = new List + { + new() + { + Provider = TestSample.Get(), + Link = "link", + DataID = "id" + }, + }; + await _repository.Edit(value, false); + + { + await using DatabaseContext database = Repositories.Context.New(); + Episode retrieved = await database.Episodes + .Include(x => x.ExternalIDs) + .ThenInclude(x => x.Provider) + .FirstAsync(); + + KAssert.DeepEqual(value, retrieved); + } + + value.ExternalIDs.Add(new MetadataID + { + Provider = TestSample.GetNew(), + Link = "link", + DataID = "id" + }); + await _repository.Edit(value, false); + + { + await using DatabaseContext database = Repositories.Context.New(); + Episode retrieved = await database.Episodes + .Include(x => x.ExternalIDs) + .ThenInclude(x => x.Provider) + .FirstAsync(); + + KAssert.DeepEqual(value, retrieved); + } + } + + [Theory] + [InlineData("test")] + [InlineData("super")] + [InlineData("title")] + [InlineData("TiTlE")] + [InlineData("SuPeR")] + public async Task SearchTest(string query) + { + Episode value = new() + { + Title = "This is a test super title", + ShowID = 1, + AbsoluteNumber = 2 + }; + await _repository.Create(value); + ICollection ret = await _repository.Search(query); + KAssert.DeepEqual(value, ret.First()); + } } } \ No newline at end of file diff --git a/Kyoo.Tests/Database/SpecificTests/SeasonTests.cs b/Kyoo.Tests/Database/SpecificTests/SeasonTests.cs index 4ab36f56..03f7a15f 100644 --- a/Kyoo.Tests/Database/SpecificTests/SeasonTests.cs +++ b/Kyoo.Tests/Database/SpecificTests/SeasonTests.cs @@ -203,6 +203,7 @@ namespace Kyoo.Tests.Database Season value = new() { Title = "This is a test super title", + ShowID = 1 }; await _repository.Create(value); ICollection ret = await _repository.Search(query); diff --git a/Kyoo.Tests/Database/TestSample.cs b/Kyoo.Tests/Database/TestSample.cs index 91ebdd30..423a5c78 100644 --- a/Kyoo.Tests/Database/TestSample.cs +++ b/Kyoo.Tests/Database/TestSample.cs @@ -71,6 +71,27 @@ namespace Kyoo.Tests } } }, + { + typeof(Episode), + () => new Episode + { + ID = 2, + ShowID = 1, + ShowSlug = Get().Slug, + SeasonID = 1, + SeasonNumber = Get().SeasonNumber, + EpisodeNumber = 3, + AbsoluteNumber = 4, + Path = "/episode-path", + Title = "New Episode Title", + ReleaseDate = new DateTime(2000, 10, 10), + Overview = "new episode overview", + Images = new Dictionary + { + [Images.Logo] = "new episode logo" + } + } + }, { typeof(Provider), () => new Provider diff --git a/Kyoo/Controllers/Repositories/EpisodeRepository.cs b/Kyoo/Controllers/Repositories/EpisodeRepository.cs index ac243a68..2d17d418 100644 --- a/Kyoo/Controllers/Repositories/EpisodeRepository.cs +++ b/Kyoo/Controllers/Repositories/EpisodeRepository.cs @@ -99,7 +99,7 @@ namespace Kyoo.Controllers public override async Task> Search(string query) { return await _database.Episodes - .Where(x => x.EpisodeNumber != null) + .Where(x => x.EpisodeNumber != null || x.AbsoluteNumber != null) .Where(_database.Like(x => x.Title, $"%{query}%")) .OrderBy(DefaultSort) .Take(20) @@ -111,7 +111,6 @@ namespace Kyoo.Controllers { await base.Create(obj); _database.Entry(obj).State = EntityState.Added; - obj.ExternalIDs.ForEach(x => _database.MetadataIds().Attach(x)); await _database.SaveChangesAsync($"Trying to insert a duplicated episode (slug {obj.Slug} already exists)."); return await ValidateTracks(obj); } @@ -119,9 +118,6 @@ namespace Kyoo.Controllers /// protected override async Task EditRelations(Episode resource, Episode changed, bool resetOld) { - if (resource.ShowID <= 0) - throw new InvalidOperationException($"Can't store an episode not related to any show (showID: {resource.ShowID})."); - if (changed.Tracks != null || resetOld) { await _tracks.DeleteAll(x => x.EpisodeID == resource.ID); @@ -158,12 +154,20 @@ namespace Kyoo.Controllers protected override async Task Validate(Episode resource) { await base.Validate(resource); - await resource.ExternalIDs.ForEachAsync(async x => - { - x.Provider = await _providers.CreateIfNotExists(x.Provider); - x.ProviderID = x.Provider.ID; - _database.Entry(x.Provider).State = EntityState.Detached; - }); + if (resource.ShowID <= 0) + throw new ArgumentException($"Can't store an episode not related " + + $"to any show (showID: {resource.ShowID})."); + + if (resource.ExternalIDs != null) + { + foreach (MetadataID id in resource.ExternalIDs) + { + id.Provider = await _providers.CreateIfNotExists(id.Provider); + id.ProviderID = id.Provider.ID; + _database.Entry(id.Provider).State = EntityState.Unchanged; + } + _database.MetadataIds().AttachRange(resource.ExternalIDs); + } } /// diff --git a/Kyoo/Controllers/Repositories/SeasonRepository.cs b/Kyoo/Controllers/Repositories/SeasonRepository.cs index 12900300..88abfaea 100644 --- a/Kyoo/Controllers/Repositories/SeasonRepository.cs +++ b/Kyoo/Controllers/Repositories/SeasonRepository.cs @@ -87,7 +87,6 @@ namespace Kyoo.Controllers { await base.Create(obj); _database.Entry(obj).State = EntityState.Added; - obj.ExternalIDs.ForEach(x => _database.MetadataIds().Attach(x)); await _database.SaveChangesAsync($"Trying to insert a duplicated season (slug {obj.Slug} already exists)."); return obj; } @@ -95,32 +94,37 @@ namespace Kyoo.Controllers /// protected override async Task Validate(Season resource) { + await base.Validate(resource); if (resource.ShowID <= 0) { if (resource.Show == null) - throw new InvalidOperationException( + throw new ArgumentException( $"Can't store a season not related to any show (showID: {resource.ShowID})."); resource.ShowID = resource.Show.ID; } - await base.Validate(resource); - await resource.ExternalIDs.ForEachAsync(async id => + if (resource.ExternalIDs != null) { - id.Provider = await _providers.CreateIfNotExists(id.Provider); - id.ProviderID = id.Provider.ID; - _database.Entry(id.Provider).State = EntityState.Detached; - }); + foreach (MetadataID id in resource.ExternalIDs) + { + id.Provider = await _providers.CreateIfNotExists(id.Provider); + id.ProviderID = id.Provider.ID; + _database.Entry(id.Provider).State = EntityState.Unchanged; + } + _database.MetadataIds().AttachRange(resource.ExternalIDs); + } } /// protected override async Task EditRelations(Season resource, Season changed, bool resetOld) { + await Validate(changed); + if (changed.ExternalIDs != null || resetOld) { await Database.Entry(resource).Collection(x => x.ExternalIDs).LoadAsync(); resource.ExternalIDs = changed.ExternalIDs; } - await base.EditRelations(resource, changed, resetOld); } ///