Fixing show creation

This commit is contained in:
Zoe Roux 2021-06-09 23:11:20 +02:00
parent d61f3538fe
commit 6cac991653
8 changed files with 105 additions and 49 deletions

View File

@ -119,7 +119,8 @@ namespace Kyoo.SqLite
/// <inheritdoc />
protected override bool IsDuplicateException(Exception ex)
{
return ex.InnerException is SqliteException { SqliteExtendedErrorCode: 2067 /*SQLITE_CONSTRAINT_UNIQUE*/};
return ex.InnerException is SqliteException { SqliteExtendedErrorCode: 2067 /*SQLITE_CONSTRAINT_UNIQUE*/}
or SqliteException { SqliteExtendedErrorCode: 1555 /*SQLITE_CONSTRAINT_PRIMARYKEY*/};
}
/// <inheritdoc />

View File

@ -24,9 +24,7 @@ namespace Kyoo.Tests
StudioRepository studio = new(_database);
PeopleRepository people = new(_database, provider,
new Lazy<IShowRepository>(() => LibraryManager.ShowRepository));
ShowRepository show = new(_database, studio, people, genre, provider,
new Lazy<ISeasonRepository>(() => LibraryManager.SeasonRepository),
new Lazy<IEpisodeRepository>(() => LibraryManager.EpisodeRepository));
ShowRepository show = new(_database, studio, people, genre, provider);
SeasonRepository season = new(_database, provider, show,
new Lazy<IEpisodeRepository>(() => LibraryManager.EpisodeRepository));
LibraryItemRepository libraryItem = new(_database,

View File

@ -74,5 +74,17 @@ namespace Kyoo.Tests
await _repository.Delete(TestSample.Get<T>());
Assert.Equal(0, await _repository.GetCount());
}
[Fact]
public async Task CreateTest()
{
await Assert.ThrowsAsync<DuplicatedItemException>(() => _repository.Create(TestSample.Get<T>()));
await _repository.Delete(TestSample.Get<T>());
T expected = TestSample.Get<T>();
expected.ID = 0;
await _repository.Create(expected);
KAssert.DeepEqual(expected, await _repository.Get(expected.Slug));
}
}
}

View File

@ -1,3 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using Kyoo.Models;
@ -5,12 +7,25 @@ using Xunit;
namespace Kyoo.Tests.SpecificTests
{
public class GlobalTests
public class GlobalTests : IDisposable, IAsyncDisposable
{
private readonly RepositoryActivator _repositories;
public GlobalTests()
{
_repositories = new RepositoryActivator();
}
[Fact]
[SuppressMessage("ReSharper", "EqualExpressionComparison")]
public void SampleTest()
{
Assert.False(ReferenceEquals(TestSample.Get<Show>(), TestSample.Get<Show>()));
}
[Fact]
public async Task DeleteShowWithEpisodeAndSeason()
{
RepositoryActivator repositories = new();
Show show = TestSample.Get<Show>();
show.Seasons = new[]
{
@ -20,13 +35,24 @@ namespace Kyoo.Tests.SpecificTests
{
TestSample.Get<Episode>()
};
await repositories.Context.AddAsync(show);
await _repositories.Context.AddAsync(show);
Assert.Equal(1, await repositories.LibraryManager.ShowRepository.GetCount());
await repositories.LibraryManager.ShowRepository.Delete(show);
Assert.Equal(0, await repositories.LibraryManager.ShowRepository.GetCount());
Assert.Equal(0, await repositories.LibraryManager.SeasonRepository.GetCount());
Assert.Equal(0, await repositories.LibraryManager.EpisodeRepository.GetCount());
Assert.Equal(1, await _repositories.LibraryManager.ShowRepository.GetCount());
await _repositories.LibraryManager.ShowRepository.Delete(show);
Assert.Equal(0, await _repositories.LibraryManager.ShowRepository.GetCount());
Assert.Equal(0, await _repositories.LibraryManager.SeasonRepository.GetCount());
Assert.Equal(0, await _repositories.LibraryManager.EpisodeRepository.GetCount());
}
public void Dispose()
{
_repositories.Dispose();
GC.SuppressFinalize(this);
}
public ValueTask DisposeAsync()
{
return _repositories.DisposeAsync();
}
}
}

View File

@ -178,5 +178,43 @@ namespace Kyoo.Tests.SpecificTests
Assert.Null(edited.Genres);
Assert.Null(edited.Studio);
}
[Fact]
public async Task CreateWithRelationsTest()
{
Show expected = TestSample.Get<Show>();
expected.ID = 0;
expected.Slug = "created-relation-test";
expected.ExternalIDs = new[]
{
new MetadataID<Show>
{
First = expected,
Second = new Provider("provider", "provider.png"),
DataID = "ID"
}
};
expected.Genres = new[]
{
new Genre
{
Name = "Genre",
Slug = "genre"
}
};
expected.People = new[]
{
new PeopleRole
{
People = TestSample.Get<People>(),
Show = expected,
ForPeople = false,
Role = "actor"
}
};
expected.Studio = new Studio("studio");
Show created = await _repository.Create(expected);
KAssert.DeepEqual(expected, created);
}
}
}

View File

@ -93,6 +93,7 @@ namespace Kyoo.Tests
public void Dispose()
{
_connection.Close();
GC.SuppressFinalize(this);
}
public async ValueTask DisposeAsync()

View File

@ -6,11 +6,11 @@ namespace Kyoo.Tests
{
public static class TestSample
{
private static readonly Dictionary<Type, object> Samples = new()
private static readonly Dictionary<Type, Func<object>> Samples = new()
{
{
typeof(Show),
new Show
() => new Show
{
ID = 1,
Slug = "anohana",
@ -37,7 +37,7 @@ namespace Kyoo.Tests
},
{
typeof(Season),
new Season
() => new Season
{
ID = 1,
ShowSlug = "anohana",
@ -52,7 +52,7 @@ namespace Kyoo.Tests
},
{
typeof(Episode),
new Episode
() => new Episode
{
ID = 1,
ShowSlug = "anohana",
@ -70,7 +70,7 @@ namespace Kyoo.Tests
},
{
typeof(People),
new People
() => new People
{
ID = 1,
Slug = "the-actor",
@ -82,7 +82,7 @@ namespace Kyoo.Tests
public static T Get<T>()
{
return (T)Samples[typeof(T)];
return (T)Samples[typeof(T)]();
}
}
}

View File

@ -33,14 +33,6 @@ namespace Kyoo.Controllers
/// A provider repository to handle externalID creation and deletion
/// </summary>
private readonly IProviderRepository _providers;
/// <summary>
/// A lazy loaded season repository to handle cascade deletion (seasons deletion whith it's show)
/// </summary>
private readonly Lazy<ISeasonRepository> _seasons;
/// <summary>
/// A lazy loaded episode repository to handle cascade deletion (episode deletion whith it's show)
/// </summary>
private readonly Lazy<IEpisodeRepository> _episodes;
/// <inheritdoc />
protected override Expression<Func<Show, object>> DefaultSort => x => x.Title;
@ -53,15 +45,11 @@ namespace Kyoo.Controllers
/// <param name="people">A people repository</param>
/// <param name="genres">A genres repository</param>
/// <param name="providers">A provider repository</param>
/// <param name="seasons">A lazy loaded season repository</param>
/// <param name="episodes">A lazy loaded episode repository</param>
public ShowRepository(DatabaseContext database,
IStudioRepository studios,
IPeopleRepository people,
IGenreRepository genres,
IProviderRepository providers,
Lazy<ISeasonRepository> seasons,
Lazy<IEpisodeRepository> episodes)
IProviderRepository providers)
: base(database)
{
_database = database;
@ -69,8 +57,6 @@ namespace Kyoo.Controllers
_people = people;
_genres = genres;
_providers = providers;
_seasons = seasons;
_episodes = episodes;
}
@ -103,12 +89,16 @@ namespace Kyoo.Controllers
await base.Validate(resource);
if (resource.Studio != null)
resource.Studio = await _studios.CreateIfNotExists(resource.Studio);
resource.Genres = await TaskUtils.DefaultIfNull(resource.Genres
?.SelectAsync(x => _genres.CreateIfNotExists(x))
.ToListAsync());
resource.GenreLinks = resource.Genres?
.Select(x => Link.UCreate(resource, x))
.Select(x => Link.Create(resource, x))
.ToList();
await resource.GenreLinks.ForEachAsync(async id =>
{
id.Second = await _genres.CreateIfNotExists(id.Second);
id.SecondID = id.Second.ID;
_database.Entry(id.Second).State = EntityState.Detached;
});
await resource.ExternalIDs.ForEachAsync(async id =>
{
id.Second = await _providers.CreateIfNotExists(id.Second);
@ -139,8 +129,8 @@ namespace Kyoo.Controllers
if (changed.Genres != null || resetOld)
{
await Database.Entry(resource).Collection(x => x.GenreLinks).LoadAsync();
resource.GenreLinks = changed.Genres?.Select(x => Link.UCreate(resource, x)).ToList();
await Database.Entry(resource).Collection(x => x.Genres).LoadAsync();
resource.Genres = changed.Genres;
}
if (changed.People != null || resetOld)
@ -191,18 +181,8 @@ namespace Kyoo.Controllers
/// <inheritdoc />
public override async Task Delete(Show obj)
{
if (obj == null)
throw new ArgumentNullException(nameof(obj));
_database.Entry(obj).State = EntityState.Deleted;
await _database.SaveChangesAsync();
// TODO handle that with events maybe. (for now, seasons & episodes might not be loaded)
if (obj.Seasons != null)
await _seasons.Value.DeleteRange(obj.Seasons);
if (obj.Episodes != null)
await _episodes.Value.DeleteRange(obj.Episodes);
}
}
}