mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-03 13:44:33 -04:00
Delete useles tests
This commit is contained in:
parent
3e44d38a90
commit
d7e5b8b916
60
.github/workflows/tests.yml
vendored
60
.github/workflows/tests.yml
vendored
@ -1,60 +0,0 @@
|
|||||||
name: Testing
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
- next
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
tests:
|
|
||||||
name: Back tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: mcr.microsoft.com/dotnet/sdk:7.0
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres
|
|
||||||
env:
|
|
||||||
POSTGRES_PASSWORD: postgres
|
|
||||||
options: >-
|
|
||||||
--health-cmd pg_isready
|
|
||||||
--health-interval 10s
|
|
||||||
--health-timeout 5s
|
|
||||||
--health-retries 5
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
cd back
|
|
||||||
dotnet build '-p:SkipTranscoder=true' -p:CopyLocalLockFileAssemblies=true
|
|
||||||
cp ./out/bin/Kyoo.Abstractions/Debug/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll ./tests/Kyoo.Tests/bin/Debug/net7.0/
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: |
|
|
||||||
cd back
|
|
||||||
dotnet test --no-build '-p:CollectCoverage=true;CoverletOutputFormat=opencover' --logger "trx;LogFileName=TestOutputResults.xml"
|
|
||||||
env:
|
|
||||||
POSTGRES_HOST: postgres
|
|
||||||
POSTGRES_USER: postgres
|
|
||||||
POSTGRES_PASSWORD: postgres
|
|
||||||
|
|
||||||
- name: Sanitize coverage output
|
|
||||||
if: ${{ always() }}
|
|
||||||
run: sed -i "s'$(pwd)/back'.'" back/tests/Kyoo.Tests/coverage.opencover.xml
|
|
||||||
|
|
||||||
- name: Upload tests results
|
|
||||||
if: ${{ always() }}
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: results.xml
|
|
||||||
path: "**/TestOutputResults.xml"
|
|
||||||
|
|
||||||
- name: Upload coverage report
|
|
||||||
if: ${{ always() }}
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: coverage.xml
|
|
||||||
path: "**/coverage.opencover.xml"
|
|
@ -12,7 +12,6 @@ COPY src/Kyoo.Host/Kyoo.Host.csproj src/Kyoo.Host/Kyoo.Host.csproj
|
|||||||
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||||
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
||||||
COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj
|
COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj
|
||||||
COPY tests/Kyoo.Tests/Kyoo.Tests.csproj tests/Kyoo.Tests/Kyoo.Tests.csproj
|
|
||||||
RUN dotnet restore -a $TARGETARCH
|
RUN dotnet restore -a $TARGETARCH
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
@ -12,7 +12,6 @@ COPY src/Kyoo.Host/Kyoo.Host.csproj src/Kyoo.Host/Kyoo.Host.csproj
|
|||||||
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
COPY src/Kyoo.Postgresql/Kyoo.Postgresql.csproj src/Kyoo.Postgresql/Kyoo.Postgresql.csproj
|
||||||
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
COPY src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj src/Kyoo.Meilisearch/Kyoo.Meilisearch.csproj
|
||||||
COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj
|
COPY src/Kyoo.Swagger/Kyoo.Swagger.csproj src/Kyoo.Swagger/Kyoo.Swagger.csproj
|
||||||
COPY tests/Kyoo.Tests/Kyoo.Tests.csproj tests/Kyoo.Tests/Kyoo.Tests.csproj
|
|
||||||
RUN dotnet restore
|
RUN dotnet restore
|
||||||
|
|
||||||
WORKDIR /kyoo
|
WORKDIR /kyoo
|
||||||
|
@ -7,12 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Postgresql", "src\Kyoo
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Authentication", "src\Kyoo.Authentication\Kyoo.Authentication.csproj", "{7A841335-6523-47DB-9717-80AA7BD943FD}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Authentication", "src\Kyoo.Authentication\Kyoo.Authentication.csproj", "{7A841335-6523-47DB-9717-80AA7BD943FD}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Tests", "tests\Kyoo.Tests\Kyoo.Tests.csproj", "{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Swagger", "src\Kyoo.Swagger\Kyoo.Swagger.csproj", "{7D1A7596-73F6-4D35-842E-A5AD9C620596}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Swagger", "src\Kyoo.Swagger\Kyoo.Swagger.csproj", "{7D1A7596-73F6-4D35-842E-A5AD9C620596}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{FEAE1B0E-D797-470F-9030-0EF743575ECC}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Host", "src\Kyoo.Host\Kyoo.Host.csproj", "{0938459E-2E2B-457F-8120-7D8CA93866A6}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Host", "src\Kyoo.Host\Kyoo.Host.csproj", "{0938459E-2E2B-457F-8120-7D8CA93866A6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Meilisearch", "src\Kyoo.Meilisearch\Kyoo.Meilisearch.csproj", "{F8E6018A-FD51-40EB-99FF-A26BA59F2762}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kyoo.Meilisearch", "src\Kyoo.Meilisearch\Kyoo.Meilisearch.csproj", "{F8E6018A-FD51-40EB-99FF-A26BA59F2762}"
|
||||||
@ -43,10 +39,6 @@ Global
|
|||||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Release|Any CPU.Build.0 = Release|Any CPU
|
{6515380E-1E57-42DA-B6E3-E1C8A848818A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{2374D500-1ADB-4752-85DB-8BB0DDF5A8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@ -68,7 +60,4 @@ Global
|
|||||||
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.Build.0 = Release|Any CPU
|
{F8E6018A-FD51-40EB-99FF-A26BA59F2762}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
|
||||||
{0C8AA7EA-E723-4532-852F-35AA4E8AFED5} = {FEAE1B0E-D797-470F-9030-0EF743575ECC}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Host;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
|
||||||
namespace Kyoo.Host
|
namespace Kyoo.Host
|
||||||
|
@ -1,132 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Data.Common;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Core;
|
|
||||||
using Kyoo.Core.Controllers;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Moq;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Database
|
|
||||||
{
|
|
||||||
public class RepositoryActivator : IDisposable, IAsyncDisposable
|
|
||||||
{
|
|
||||||
public TestContext Context { get; }
|
|
||||||
public ILibraryManager LibraryManager { get; }
|
|
||||||
|
|
||||||
private readonly List<IAsyncDisposable> _databases = new();
|
|
||||||
|
|
||||||
private readonly IBaseRepository[] _repositories;
|
|
||||||
|
|
||||||
public RepositoryActivator(ITestOutputHelper output, PostgresFixture postgres = null)
|
|
||||||
{
|
|
||||||
Context = new PostgresTestContext(postgres, output);
|
|
||||||
|
|
||||||
Mock<IThumbnailsManager> thumbs = new();
|
|
||||||
CollectionRepository collection = new(_NewContext(), thumbs.Object);
|
|
||||||
StudioRepository studio = new(_NewContext(), thumbs.Object);
|
|
||||||
PeopleRepository people =
|
|
||||||
new(
|
|
||||||
_NewContext(),
|
|
||||||
new Lazy<IRepository<Show>>(() => LibraryManager.Shows),
|
|
||||||
thumbs.Object
|
|
||||||
);
|
|
||||||
MovieRepository movies = new(_NewContext(), studio, people, thumbs.Object);
|
|
||||||
ShowRepository show = new(_NewContext(), studio, people, thumbs.Object);
|
|
||||||
SeasonRepository season = new(_NewContext(), thumbs.Object);
|
|
||||||
LibraryItemRepository libraryItem = new(_NewConnection(), new(null));
|
|
||||||
EpisodeRepository episode = new(_NewContext(), show, thumbs.Object);
|
|
||||||
UserRepository user =
|
|
||||||
new(_NewContext(), _NewConnection(), new(null), thumbs.Object, new());
|
|
||||||
|
|
||||||
_repositories = new IBaseRepository[]
|
|
||||||
{
|
|
||||||
libraryItem,
|
|
||||||
collection,
|
|
||||||
movies,
|
|
||||||
show,
|
|
||||||
season,
|
|
||||||
episode,
|
|
||||||
people,
|
|
||||||
studio,
|
|
||||||
user
|
|
||||||
};
|
|
||||||
|
|
||||||
ServiceCollection container = new();
|
|
||||||
container.AddScoped((_) => _NewContext());
|
|
||||||
CoreModule.Services = container.BuildServiceProvider();
|
|
||||||
|
|
||||||
LibraryManager = new LibraryManager(
|
|
||||||
libraryItem,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
collection,
|
|
||||||
movies,
|
|
||||||
show,
|
|
||||||
season,
|
|
||||||
episode,
|
|
||||||
people,
|
|
||||||
studio,
|
|
||||||
user
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IRepository<T> GetRepository<T>()
|
|
||||||
where T : class, IResource, IQuery
|
|
||||||
{
|
|
||||||
return _repositories.First(x => x.RepositoryType == typeof(T)) as IRepository<T>;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DatabaseContext _NewContext()
|
|
||||||
{
|
|
||||||
DatabaseContext context = Context.New();
|
|
||||||
_databases.Add(context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DbConnection _NewConnection()
|
|
||||||
{
|
|
||||||
DbConnection context = Context.NewConnection();
|
|
||||||
_databases.Add(context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
foreach (IDisposable context in _databases)
|
|
||||||
context.Dispose();
|
|
||||||
Context.Dispose();
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async ValueTask DisposeAsync()
|
|
||||||
{
|
|
||||||
foreach (IAsyncDisposable context in _databases)
|
|
||||||
await context.DisposeAsync();
|
|
||||||
await Context.DisposeAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Abstractions.Models.Exceptions;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Database
|
|
||||||
{
|
|
||||||
public abstract class RepositoryTests<T> : IDisposable, IAsyncDisposable
|
|
||||||
where T : class, IResource, IQuery
|
|
||||||
{
|
|
||||||
protected readonly RepositoryActivator Repositories;
|
|
||||||
private readonly IRepository<T> _repository;
|
|
||||||
|
|
||||||
protected RepositoryTests(RepositoryActivator repositories)
|
|
||||||
{
|
|
||||||
Repositories = repositories;
|
|
||||||
_repository = Repositories.GetRepository<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Repositories.Dispose();
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ValueTask DisposeAsync()
|
|
||||||
{
|
|
||||||
return Repositories.DisposeAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task FillTest()
|
|
||||||
{
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
|
|
||||||
Assert.Equal(1, database.Shows.Count());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task GetByIdTest()
|
|
||||||
{
|
|
||||||
T value = await _repository.Get(TestSample.Get<T>().Id);
|
|
||||||
KAssert.DeepEqual(TestSample.Get<T>(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task GetBySlugTest()
|
|
||||||
{
|
|
||||||
T value = await _repository.Get(TestSample.Get<T>().Slug);
|
|
||||||
KAssert.DeepEqual(TestSample.Get<T>(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task GetByFakeSlugTest()
|
|
||||||
{
|
|
||||||
await Assert.ThrowsAsync<ItemNotFoundException>(() => _repository.Get("non-existent"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task DeleteByIdTest()
|
|
||||||
{
|
|
||||||
await _repository.Delete(TestSample.Get<T>().Id);
|
|
||||||
Assert.Equal(0, await _repository.GetCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task DeleteBySlugTest()
|
|
||||||
{
|
|
||||||
await _repository.Delete(TestSample.Get<T>().Slug);
|
|
||||||
Assert.Equal(0, await _repository.GetCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task DeleteByValueTest()
|
|
||||||
{
|
|
||||||
await _repository.Delete(TestSample.Get<T>());
|
|
||||||
Assert.Equal(0, await _repository.GetCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
// [Fact]
|
|
||||||
// public async Task EditNonExistingTest()
|
|
||||||
// {
|
|
||||||
// await Assert.ThrowsAsync<ItemNotFoundException>(() => _repository.Edit(new T { Id = 56 }));
|
|
||||||
// }
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task GetOrDefaultTest()
|
|
||||||
{
|
|
||||||
Assert.Null(await _repository.GetOrDefault("non-existing"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,158 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Xunit;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Database
|
|
||||||
{
|
|
||||||
namespace PostgreSQL
|
|
||||||
{
|
|
||||||
[Collection(nameof(Postgresql))]
|
|
||||||
public class CollectionTests : ACollectionTests
|
|
||||||
{
|
|
||||||
public CollectionTests(PostgresFixture postgres, ITestOutputHelper output)
|
|
||||||
: base(new RepositoryActivator(output, postgres)) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class ACollectionTests : RepositoryTests<Collection>
|
|
||||||
{
|
|
||||||
private readonly IRepository<Collection> _repository;
|
|
||||||
|
|
||||||
protected ACollectionTests(RepositoryActivator repositories)
|
|
||||||
: base(repositories)
|
|
||||||
{
|
|
||||||
_repository = Repositories.LibraryManager.Collections;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateWithEmptySlugTest()
|
|
||||||
{
|
|
||||||
Collection collection = TestSample.GetNew<Collection>();
|
|
||||||
collection.Slug = string.Empty;
|
|
||||||
await Assert.ThrowsAsync<ArgumentException>(() => _repository.Create(collection));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateWithNumberSlugTest()
|
|
||||||
{
|
|
||||||
Collection collection = TestSample.GetNew<Collection>();
|
|
||||||
collection.Slug = "2";
|
|
||||||
Collection ret = await _repository.Create(collection);
|
|
||||||
Assert.Equal("2!", ret.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateWithExternalIdTest()
|
|
||||||
{
|
|
||||||
Collection collection = TestSample.GetNew<Collection>();
|
|
||||||
collection.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["1"] = new() { Link = "link", DataId = "id" },
|
|
||||||
["2"] = new() { Link = "new-provider-link", DataId = "new-id" }
|
|
||||||
};
|
|
||||||
await _repository.Create(collection);
|
|
||||||
|
|
||||||
Collection retrieved = await _repository.Get(2.AsGuid());
|
|
||||||
Assert.Equal(2, retrieved.ExternalId.Count);
|
|
||||||
KAssert.DeepEqual(collection.ExternalId.First(), retrieved.ExternalId.First());
|
|
||||||
KAssert.DeepEqual(collection.ExternalId.Last(), retrieved.ExternalId.Last());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EditTest()
|
|
||||||
{
|
|
||||||
Collection value = await _repository.Get(TestSample.Get<Collection>().Slug);
|
|
||||||
value.Name = "New Title";
|
|
||||||
value.Poster = new Image("new-poster");
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Collection retrieved = await database.Collections.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EditMetadataTest()
|
|
||||||
{
|
|
||||||
Collection value = await _repository.Get(TestSample.Get<Collection>().Slug);
|
|
||||||
value.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["test"] = new() { Link = "link", DataId = "id" },
|
|
||||||
};
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Collection retrieved = await database.Collections.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task AddMetadataTest()
|
|
||||||
{
|
|
||||||
Collection value = await _repository.Get(TestSample.Get<Collection>().Slug);
|
|
||||||
value.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["toto"] = new() { Link = "link", DataId = "id" },
|
|
||||||
};
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
{
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Collection retrieved = await database.Collections.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
|
|
||||||
value.ExternalId.Add("test", new MetadataId { Link = "link", DataId = "id" });
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
{
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Collection retrieved = await database.Collections.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("test")]
|
|
||||||
[InlineData("super")]
|
|
||||||
[InlineData("title")]
|
|
||||||
[InlineData("TiTlE")]
|
|
||||||
[InlineData("SuPeR")]
|
|
||||||
public async Task SearchTest(string query)
|
|
||||||
{
|
|
||||||
Collection value = new() { Slug = "super-test", Name = "This is a test title", };
|
|
||||||
await _repository.Create(value);
|
|
||||||
ICollection<Collection> ret = await _repository.Search(query);
|
|
||||||
KAssert.DeepEqual(value, ret.First());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,329 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Abstractions.Models.Exceptions;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Xunit;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Database
|
|
||||||
{
|
|
||||||
namespace PostgreSQL
|
|
||||||
{
|
|
||||||
[Collection(nameof(Postgresql))]
|
|
||||||
public class EpisodeTests : AEpisodeTests
|
|
||||||
{
|
|
||||||
public EpisodeTests(PostgresFixture postgres, ITestOutputHelper output)
|
|
||||||
: base(new RepositoryActivator(output, postgres)) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class AEpisodeTests : RepositoryTests<Episode>
|
|
||||||
{
|
|
||||||
private readonly IRepository<Episode> _repository;
|
|
||||||
|
|
||||||
protected AEpisodeTests(RepositoryActivator repositories)
|
|
||||||
: base(repositories)
|
|
||||||
{
|
|
||||||
_repository = repositories.LibraryManager.Episodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SlugEditTest()
|
|
||||||
{
|
|
||||||
Episode episode = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e1", episode.Slug);
|
|
||||||
await Repositories.LibraryManager.Shows.Patch(
|
|
||||||
episode.ShowId,
|
|
||||||
(x) =>
|
|
||||||
{
|
|
||||||
x.Slug = "new-slug";
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
episode = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal("new-slug-s1e1", episode.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SeasonNumberEditTest()
|
|
||||||
{
|
|
||||||
Episode episode = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e1", episode.Slug);
|
|
||||||
episode = await _repository.Patch(
|
|
||||||
1.AsGuid(),
|
|
||||||
(x) =>
|
|
||||||
{
|
|
||||||
x.SeasonNumber = 2;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s2e1", episode.Slug);
|
|
||||||
episode = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s2e1", episode.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EpisodeNumberEditTest()
|
|
||||||
{
|
|
||||||
Episode episode = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e1", episode.Slug);
|
|
||||||
episode = await Repositories.LibraryManager.Episodes.Patch(
|
|
||||||
episode.Id,
|
|
||||||
(x) =>
|
|
||||||
{
|
|
||||||
x.EpisodeNumber = 2;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e2", episode.Slug);
|
|
||||||
episode = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e2", episode.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EpisodeCreationSlugTest()
|
|
||||||
{
|
|
||||||
Episode model = TestSample.Get<Episode>();
|
|
||||||
model.Id = 0.AsGuid();
|
|
||||||
model.ShowId = TestSample.Get<Show>().Id;
|
|
||||||
model.SeasonNumber = 2;
|
|
||||||
model.EpisodeNumber = 4;
|
|
||||||
Episode episode = await _repository.Create(model);
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s2e4", episode.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void AbsoluteSlugTest()
|
|
||||||
{
|
|
||||||
Assert.Equal(
|
|
||||||
$"{TestSample.Get<Show>().Slug}-{TestSample.GetAbsoluteEpisode().AbsoluteNumber}",
|
|
||||||
TestSample.GetAbsoluteEpisode().Slug
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EpisodeCreationAbsoluteSlugTest()
|
|
||||||
{
|
|
||||||
Episode episode = await _repository.Create(TestSample.GetAbsoluteEpisode());
|
|
||||||
Assert.Equal(
|
|
||||||
$"{TestSample.Get<Show>().Slug}-{TestSample.GetAbsoluteEpisode().AbsoluteNumber}",
|
|
||||||
episode.Slug
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SlugEditAbsoluteTest()
|
|
||||||
{
|
|
||||||
Episode episode = await _repository.Create(TestSample.GetAbsoluteEpisode());
|
|
||||||
await Repositories.LibraryManager.Shows.Patch(
|
|
||||||
episode.ShowId,
|
|
||||||
(x) =>
|
|
||||||
{
|
|
||||||
x.Slug = "new-slug";
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
episode = await _repository.Get(2.AsGuid());
|
|
||||||
Assert.Equal($"new-slug-3", episode.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task AbsoluteNumberEditTest()
|
|
||||||
{
|
|
||||||
await _repository.Create(TestSample.GetAbsoluteEpisode());
|
|
||||||
Episode episode = await _repository.Patch(
|
|
||||||
2.AsGuid(),
|
|
||||||
(x) =>
|
|
||||||
{
|
|
||||||
x.AbsoluteNumber = 56;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-56", episode.Slug);
|
|
||||||
episode = await _repository.Get(2.AsGuid());
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-56", episode.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task AbsoluteToNormalEditTest()
|
|
||||||
{
|
|
||||||
await _repository.Create(TestSample.GetAbsoluteEpisode());
|
|
||||||
Episode episode = await _repository.Patch(
|
|
||||||
2.AsGuid(),
|
|
||||||
(x) =>
|
|
||||||
{
|
|
||||||
x.SeasonNumber = 1;
|
|
||||||
x.EpisodeNumber = 2;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e2", episode.Slug);
|
|
||||||
episode = await _repository.Get(2.AsGuid());
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e2", episode.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task NormalToAbsoluteEditTest()
|
|
||||||
{
|
|
||||||
Episode episode = await _repository.Get(1.AsGuid());
|
|
||||||
episode.SeasonNumber = null;
|
|
||||||
episode.AbsoluteNumber = 12;
|
|
||||||
episode = await _repository.Edit(episode);
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-12", episode.Slug);
|
|
||||||
episode = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-12", episode.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateWithExternalIdTest()
|
|
||||||
{
|
|
||||||
Episode value = TestSample.GetNew<Episode>();
|
|
||||||
value.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["2"] = new() { Link = "link", DataId = "id" },
|
|
||||||
["3"] = new() { Link = "new-provider-link", DataId = "new-id" }
|
|
||||||
};
|
|
||||||
await _repository.Create(value);
|
|
||||||
|
|
||||||
Episode retrieved = await _repository.Get(2.AsGuid());
|
|
||||||
Assert.Equal(2, retrieved.ExternalId.Count);
|
|
||||||
KAssert.DeepEqual(value.ExternalId.First(), retrieved.ExternalId.First());
|
|
||||||
KAssert.DeepEqual(value.ExternalId.Last(), retrieved.ExternalId.Last());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EditTest()
|
|
||||||
{
|
|
||||||
Episode value = await _repository.Get(TestSample.Get<Episode>().Slug);
|
|
||||||
value.Name = "New Title";
|
|
||||||
value.Poster = new Image("poster");
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
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<Episode>().Slug);
|
|
||||||
value.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["1"] = new() { Link = "link", DataId = "id" },
|
|
||||||
};
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Episode retrieved = await database.Episodes.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task AddMetadataTest()
|
|
||||||
{
|
|
||||||
Episode value = await _repository.Get(TestSample.Get<Episode>().Slug);
|
|
||||||
value.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["toto"] = new() { Link = "link", DataId = "id" },
|
|
||||||
};
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
{
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Episode retrieved = await database.Episodes.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
|
|
||||||
value.ExternalId.Add("test", new MetadataId { Link = "link", DataId = "id" });
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
{
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Episode retrieved = await database.Episodes.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("test")]
|
|
||||||
[InlineData("super")]
|
|
||||||
[InlineData("title")]
|
|
||||||
[InlineData("TiTlE")]
|
|
||||||
[InlineData("SuPeR")]
|
|
||||||
public async Task SearchTest(string query)
|
|
||||||
{
|
|
||||||
Episode value = TestSample.Get<Episode>();
|
|
||||||
value.Id = 0.AsGuid();
|
|
||||||
value.Name = "This is a test super title";
|
|
||||||
value.EpisodeNumber = 56;
|
|
||||||
await _repository.Create(value);
|
|
||||||
ICollection<Episode> ret = await _repository.Search(query);
|
|
||||||
KAssert.DeepEqual(value, ret.First());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateTest()
|
|
||||||
{
|
|
||||||
await Assert.ThrowsAsync<DuplicatedItemException>(
|
|
||||||
() => _repository.Create(TestSample.Get<Episode>())
|
|
||||||
);
|
|
||||||
await _repository.Delete(TestSample.Get<Episode>());
|
|
||||||
|
|
||||||
Episode expected = TestSample.Get<Episode>();
|
|
||||||
expected.Id = 0.AsGuid();
|
|
||||||
expected.ShowId = (
|
|
||||||
await Repositories.LibraryManager.Shows.Create(TestSample.Get<Show>())
|
|
||||||
).Id;
|
|
||||||
expected.SeasonId = (
|
|
||||||
await Repositories.LibraryManager.Seasons.Create(TestSample.Get<Season>())
|
|
||||||
).Id;
|
|
||||||
await _repository.Create(expected);
|
|
||||||
KAssert.DeepEqual(expected, await _repository.Get(expected.Slug));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateIfNotExistTest()
|
|
||||||
{
|
|
||||||
Episode expected = TestSample.Get<Episode>();
|
|
||||||
KAssert.DeepEqual(
|
|
||||||
expected,
|
|
||||||
await _repository.CreateIfNotExists(TestSample.Get<Episode>())
|
|
||||||
);
|
|
||||||
await _repository.Delete(TestSample.Get<Episode>());
|
|
||||||
expected.ShowId = (
|
|
||||||
await Repositories.LibraryManager.Shows.Create(TestSample.Get<Show>())
|
|
||||||
).Id;
|
|
||||||
expected.SeasonId = (
|
|
||||||
await Repositories.LibraryManager.Seasons.Create(TestSample.Get<Season>())
|
|
||||||
).Id;
|
|
||||||
KAssert.DeepEqual(expected, await _repository.CreateIfNotExists(expected));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Database
|
|
||||||
{
|
|
||||||
public class GlobalTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
[SuppressMessage("ReSharper", "EqualExpressionComparison")]
|
|
||||||
public void SampleTest()
|
|
||||||
{
|
|
||||||
Assert.False(ReferenceEquals(TestSample.Get<Show>(), TestSample.Get<Show>()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,183 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Xunit;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Database
|
|
||||||
{
|
|
||||||
namespace PostgreSQL
|
|
||||||
{
|
|
||||||
[Collection(nameof(Postgresql))]
|
|
||||||
public class SeasonTests : ASeasonTests
|
|
||||||
{
|
|
||||||
public SeasonTests(PostgresFixture postgres, ITestOutputHelper output)
|
|
||||||
: base(new RepositoryActivator(output, postgres)) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class ASeasonTests : RepositoryTests<Season>
|
|
||||||
{
|
|
||||||
private readonly IRepository<Season> _repository;
|
|
||||||
|
|
||||||
protected ASeasonTests(RepositoryActivator repositories)
|
|
||||||
: base(repositories)
|
|
||||||
{
|
|
||||||
_repository = Repositories.LibraryManager.Seasons;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SlugEditTest()
|
|
||||||
{
|
|
||||||
Season season = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal("anohana-s1", season.Slug);
|
|
||||||
await Repositories.LibraryManager.Shows.Patch(
|
|
||||||
season.ShowId,
|
|
||||||
(x) =>
|
|
||||||
{
|
|
||||||
x.Slug = "new-slug";
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
season = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal("new-slug-s1", season.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SeasonNumberEditTest()
|
|
||||||
{
|
|
||||||
Season season = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal("anohana-s1", season.Slug);
|
|
||||||
await _repository.Patch(
|
|
||||||
season.Id,
|
|
||||||
(x) =>
|
|
||||||
{
|
|
||||||
x.SeasonNumber = 2;
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
season = await _repository.Get(1.AsGuid());
|
|
||||||
Assert.Equal("anohana-s2", season.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SeasonCreationSlugTest()
|
|
||||||
{
|
|
||||||
Season season = await _repository.Create(
|
|
||||||
new Season { ShowId = TestSample.Get<Show>().Id, SeasonNumber = 2 }
|
|
||||||
);
|
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s2", season.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateWithExternalIdTest()
|
|
||||||
{
|
|
||||||
Season season = TestSample.GetNew<Season>();
|
|
||||||
season.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["2"] = new() { Link = "link", DataId = "id" },
|
|
||||||
["1"] = new() { Link = "new-provider-link", DataId = "new-id" }
|
|
||||||
};
|
|
||||||
await _repository.Create(season);
|
|
||||||
|
|
||||||
Season retrieved = await _repository.Get(2.AsGuid());
|
|
||||||
Assert.Equal(2, retrieved.ExternalId.Count);
|
|
||||||
KAssert.DeepEqual(season.ExternalId.First(), retrieved.ExternalId.First());
|
|
||||||
KAssert.DeepEqual(season.ExternalId.Last(), retrieved.ExternalId.Last());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EditTest()
|
|
||||||
{
|
|
||||||
Season value = await _repository.Get(TestSample.Get<Season>().Slug);
|
|
||||||
value.Name = "New Title";
|
|
||||||
value.Poster = new Image("test");
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Season retrieved = await database.Seasons.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EditMetadataTest()
|
|
||||||
{
|
|
||||||
Season value = await _repository.Get(TestSample.Get<Season>().Slug);
|
|
||||||
value.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["toto"] = new() { Link = "link", DataId = "id" },
|
|
||||||
};
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Season retrieved = await database.Seasons.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task AddMetadataTest()
|
|
||||||
{
|
|
||||||
Season value = await _repository.Get(TestSample.Get<Season>().Slug);
|
|
||||||
value.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["1"] = new() { Link = "link", DataId = "id" },
|
|
||||||
};
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
{
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Season retrieved = await database.Seasons.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
|
|
||||||
value.ExternalId.Add("toto", new MetadataId { Link = "link", DataId = "id" });
|
|
||||||
await _repository.Edit(value);
|
|
||||||
|
|
||||||
{
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Season retrieved = await database.Seasons.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(value, retrieved);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("test")]
|
|
||||||
[InlineData("super")]
|
|
||||||
[InlineData("title")]
|
|
||||||
[InlineData("TiTlE")]
|
|
||||||
[InlineData("SuPeR")]
|
|
||||||
public async Task SearchTest(string query)
|
|
||||||
{
|
|
||||||
Season value = new() { Name = "This is a test super title", ShowId = 1.AsGuid() };
|
|
||||||
await _repository.Create(value);
|
|
||||||
ICollection<Season> ret = await _repository.Search(query);
|
|
||||||
KAssert.DeepEqual(value, ret.First());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,297 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Kyoo.Utils;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Xunit;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Database
|
|
||||||
{
|
|
||||||
namespace PostgreSQL
|
|
||||||
{
|
|
||||||
[Collection(nameof(Postgresql))]
|
|
||||||
public class ShowTests : AShowTests
|
|
||||||
{
|
|
||||||
public ShowTests(PostgresFixture postgres, ITestOutputHelper output)
|
|
||||||
: base(new RepositoryActivator(output, postgres)) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class AShowTests : RepositoryTests<Show>
|
|
||||||
{
|
|
||||||
private readonly IRepository<Show> _repository;
|
|
||||||
|
|
||||||
protected AShowTests(RepositoryActivator repositories)
|
|
||||||
: base(repositories)
|
|
||||||
{
|
|
||||||
_repository = Repositories.LibraryManager.Shows;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EditTest()
|
|
||||||
{
|
|
||||||
Show value = await _repository.Get(TestSample.Get<Show>().Slug);
|
|
||||||
value.Name = "New Title";
|
|
||||||
Show edited = await _repository.Edit(value);
|
|
||||||
KAssert.DeepEqual(value, edited);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Show show = await database.Shows.FirstAsync();
|
|
||||||
|
|
||||||
KAssert.DeepEqual(show, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EditGenreTest()
|
|
||||||
{
|
|
||||||
Show value = await _repository.Get(TestSample.Get<Show>().Slug);
|
|
||||||
value.Genres = new List<Genre> { Genre.Action };
|
|
||||||
Show edited = await _repository.Edit(value);
|
|
||||||
|
|
||||||
Assert.Equal(value.Slug, edited.Slug);
|
|
||||||
Assert.Equal(value.Genres, edited.Genres);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Show show = await database.Shows.FirstAsync();
|
|
||||||
|
|
||||||
Assert.Equal(value.Slug, show.Slug);
|
|
||||||
Assert.Equal(value.Genres, show.Genres);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task AddGenreTest()
|
|
||||||
{
|
|
||||||
Show value = await _repository.Get(TestSample.Get<Show>().Slug);
|
|
||||||
value.Genres.Add(Genre.Drama);
|
|
||||||
Show edited = await _repository.Edit(value);
|
|
||||||
|
|
||||||
Assert.Equal(value.Slug, edited.Slug);
|
|
||||||
Assert.Equal(value.Genres, edited.Genres);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Show show = await database.Shows.FirstAsync();
|
|
||||||
|
|
||||||
Assert.Equal(value.Slug, show.Slug);
|
|
||||||
Assert.Equal(value.Genres, show.Genres);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EditStudioTest()
|
|
||||||
{
|
|
||||||
Show value = await _repository.Get(TestSample.Get<Show>().Slug);
|
|
||||||
value.Studio = new Studio("studio");
|
|
||||||
Show edited = await _repository.Edit(value);
|
|
||||||
|
|
||||||
Assert.Equal(value.Slug, edited.Slug);
|
|
||||||
Assert.Equal("studio", edited.Studio!.Slug);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Show show = await database.Shows.Include(x => x.Studio).FirstAsync();
|
|
||||||
|
|
||||||
Assert.Equal(value.Slug, show.Slug);
|
|
||||||
Assert.Equal("studio", show.Studio!.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EditAliasesTest()
|
|
||||||
{
|
|
||||||
Show value = await _repository.Get(TestSample.Get<Show>().Slug);
|
|
||||||
value.Aliases = new List<string>() { "NiceNewAlias", "SecondAlias" };
|
|
||||||
Show edited = await _repository.Edit(value);
|
|
||||||
|
|
||||||
Assert.Equal(value.Slug, edited.Slug);
|
|
||||||
Assert.Equal(value.Aliases, edited.Aliases);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Show show = await database.Shows.FirstAsync();
|
|
||||||
|
|
||||||
Assert.Equal(value.Slug, show.Slug);
|
|
||||||
Assert.Equal(value.Aliases, show.Aliases);
|
|
||||||
}
|
|
||||||
|
|
||||||
// [Fact]
|
|
||||||
// public async Task EditPeopleTest()
|
|
||||||
// {
|
|
||||||
// Show value = await _repository.Get(TestSample.Get<Show>().Slug);
|
|
||||||
// value.People = new[]
|
|
||||||
// {
|
|
||||||
// new PeopleRole
|
|
||||||
// {
|
|
||||||
// Show = value,
|
|
||||||
// People = TestSample.Get<People>(),
|
|
||||||
// ForPeople = false,
|
|
||||||
// Type = "Actor",
|
|
||||||
// Role = "NiceCharacter"
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// Show edited = await _repository.Edit(value);
|
|
||||||
//
|
|
||||||
// Assert.Equal(value.Slug, edited.Slug);
|
|
||||||
// Assert.Equal(edited.People!.First().ShowID, value.Id);
|
|
||||||
// Assert.Equal(
|
|
||||||
// value.People.Select(x => new { x.Role, x.Slug, x.People.Name }),
|
|
||||||
// edited.People.Select(x => new { x.Role, x.Slug, x.People.Name }));
|
|
||||||
//
|
|
||||||
// await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
// Show show = await database.Shows
|
|
||||||
// .Include(x => x.People)
|
|
||||||
// .ThenInclude(x => x.People)
|
|
||||||
// .FirstAsync();
|
|
||||||
//
|
|
||||||
// Assert.Equal(value.Slug, show.Slug);
|
|
||||||
// Assert.Equal(
|
|
||||||
// value.People.Select(x => new { x.Role, x.Slug, x.People.Name }),
|
|
||||||
// show.People!.Select(x => new { x.Role, x.Slug, x.People.Name }));
|
|
||||||
// }
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task EditExternalIDsTest()
|
|
||||||
{
|
|
||||||
Show value = await _repository.Get(TestSample.Get<Show>().Slug);
|
|
||||||
value.ExternalId = new Dictionary<string, MetadataId>()
|
|
||||||
{
|
|
||||||
["test"] = new() { DataId = "1234" }
|
|
||||||
};
|
|
||||||
Show edited = await _repository.Edit(value);
|
|
||||||
|
|
||||||
Assert.Equal(value.Slug, edited.Slug);
|
|
||||||
KAssert.DeepEqual(value.ExternalId, edited.ExternalId);
|
|
||||||
|
|
||||||
await using DatabaseContext database = Repositories.Context.New();
|
|
||||||
Show show = await database.Shows.FirstAsync();
|
|
||||||
|
|
||||||
Assert.Equal(value.Slug, show.Slug);
|
|
||||||
KAssert.DeepEqual(value.ExternalId, show.ExternalId);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateWithRelationsTest()
|
|
||||||
{
|
|
||||||
Show expected = TestSample.Get<Show>();
|
|
||||||
expected.Id = 0.AsGuid();
|
|
||||||
expected.Slug = "created-relation-test";
|
|
||||||
expected.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["test"] = new() { DataId = "ID" }
|
|
||||||
};
|
|
||||||
expected.Genres = new List<Genre>() { Genre.Action };
|
|
||||||
// expected.People = new[]
|
|
||||||
// {
|
|
||||||
// new PeopleRole
|
|
||||||
// {
|
|
||||||
// People = TestSample.Get<People>(),
|
|
||||||
// Show = expected,
|
|
||||||
// ForPeople = false,
|
|
||||||
// Role = "actor",
|
|
||||||
// Type = "actor"
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
expected.Studio = new Studio("studio");
|
|
||||||
Show created = await _repository.Create(expected);
|
|
||||||
KAssert.DeepEqual(expected, created);
|
|
||||||
|
|
||||||
await using DatabaseContext context = Repositories.Context.New();
|
|
||||||
Show retrieved = await context
|
|
||||||
.Shows
|
|
||||||
// .Include(x => x.People)
|
|
||||||
// .ThenInclude(x => x.People)
|
|
||||||
.Include(x => x.Studio)
|
|
||||||
.FirstAsync(x => x.Id == created.Id);
|
|
||||||
// retrieved.People.ForEach(x =>
|
|
||||||
// {
|
|
||||||
// x.Show = null;
|
|
||||||
// x.People.Roles = null;
|
|
||||||
// x.People.Poster = null;
|
|
||||||
// x.People.Thumbnail = null;
|
|
||||||
// x.People.Logo = null;
|
|
||||||
// });
|
|
||||||
retrieved.Studio!.Shows = null;
|
|
||||||
// expected.People.ForEach(x =>
|
|
||||||
// {
|
|
||||||
// x.Show = null;
|
|
||||||
// x.People.Roles = null;
|
|
||||||
// x.People.Poster = null;
|
|
||||||
// x.People.Thumbnail = null;
|
|
||||||
// x.People.Logo = null;
|
|
||||||
// });
|
|
||||||
|
|
||||||
KAssert.DeepEqual(retrieved, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateWithExternalID()
|
|
||||||
{
|
|
||||||
Show expected = TestSample.Get<Show>();
|
|
||||||
expected.Id = 0.AsGuid();
|
|
||||||
expected.Slug = "created-relation-test";
|
|
||||||
expected.ExternalId = new Dictionary<string, MetadataId>
|
|
||||||
{
|
|
||||||
["test"] = new() { DataId = "ID" }
|
|
||||||
};
|
|
||||||
Show created = await _repository.Create(expected);
|
|
||||||
KAssert.DeepEqual(expected, created);
|
|
||||||
await using DatabaseContext context = Repositories.Context.New();
|
|
||||||
Show retrieved = await context.Shows.FirstAsync(x => x.Id == created.Id);
|
|
||||||
KAssert.DeepEqual(expected, retrieved);
|
|
||||||
Assert.Single(retrieved.ExternalId);
|
|
||||||
Assert.Equal("ID", retrieved.ExternalId["test"].DataId);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SlugDuplicationTest()
|
|
||||||
{
|
|
||||||
Show test = TestSample.Get<Show>();
|
|
||||||
test.Id = 0.AsGuid();
|
|
||||||
test.Slug = "300";
|
|
||||||
Show created = await _repository.Create(test);
|
|
||||||
Assert.Equal("300!", created.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData("test")]
|
|
||||||
[InlineData("super")]
|
|
||||||
[InlineData("title")]
|
|
||||||
[InlineData("TiTlE")]
|
|
||||||
[InlineData("SuPeR")]
|
|
||||||
public async Task SearchTest(string query)
|
|
||||||
{
|
|
||||||
Show value = new() { Slug = "super-test", Name = "This is a test title?" };
|
|
||||||
await _repository.Create(value);
|
|
||||||
ICollection<Show> ret = await _repository.Search(query);
|
|
||||||
KAssert.DeepEqual(value, ret.First());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task DeleteShowWithEpisodeAndSeason()
|
|
||||||
{
|
|
||||||
Show show = TestSample.Get<Show>();
|
|
||||||
Assert.Equal(1, await _repository.GetCount());
|
|
||||||
await _repository.Delete(show);
|
|
||||||
Assert.Equal(0, await Repositories.LibraryManager.Shows.GetCount());
|
|
||||||
Assert.Equal(0, await Repositories.LibraryManager.Seasons.GetCount());
|
|
||||||
Assert.Equal(0, await Repositories.LibraryManager.Episodes.GetCount());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Xunit;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Database
|
|
||||||
{
|
|
||||||
namespace PostgreSQL
|
|
||||||
{
|
|
||||||
[Collection(nameof(Postgresql))]
|
|
||||||
public class StudioTests : AStudioTests
|
|
||||||
{
|
|
||||||
public StudioTests(PostgresFixture postgres, ITestOutputHelper output)
|
|
||||||
: base(new RepositoryActivator(output, postgres)) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class AStudioTests : RepositoryTests<Studio>
|
|
||||||
{
|
|
||||||
[SuppressMessage("ReSharper", "NotAccessedField.Local")]
|
|
||||||
private readonly IRepository<Studio> _repository;
|
|
||||||
|
|
||||||
protected AStudioTests(RepositoryActivator repositories)
|
|
||||||
: base(repositories)
|
|
||||||
{
|
|
||||||
_repository = Repositories.LibraryManager.Studios;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Kyoo.Abstractions.Controllers;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Xunit;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Database
|
|
||||||
{
|
|
||||||
namespace PostgreSQL
|
|
||||||
{
|
|
||||||
[Collection(nameof(Postgresql))]
|
|
||||||
public class UserTests : AUserTests
|
|
||||||
{
|
|
||||||
public UserTests(PostgresFixture postgres, ITestOutputHelper output)
|
|
||||||
: base(new RepositoryActivator(output, postgres)) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class AUserTests : RepositoryTests<User>
|
|
||||||
{
|
|
||||||
[SuppressMessage("ReSharper", "NotAccessedField.Local")]
|
|
||||||
private readonly IRepository<User> _repository;
|
|
||||||
|
|
||||||
protected AUserTests(RepositoryActivator repositories)
|
|
||||||
: base(repositories)
|
|
||||||
{
|
|
||||||
_repository = Repositories.LibraryManager.Users;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,174 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Data.Common;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Npgsql;
|
|
||||||
using Xunit;
|
|
||||||
using Xunit.Abstractions;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests
|
|
||||||
{
|
|
||||||
[CollectionDefinition(nameof(Postgresql))]
|
|
||||||
public class PostgresCollection : ICollectionFixture<PostgresFixture> { }
|
|
||||||
|
|
||||||
public sealed class PostgresFixture : IDisposable
|
|
||||||
{
|
|
||||||
private readonly DbContextOptions<DatabaseContext> _options;
|
|
||||||
|
|
||||||
public string Template { get; }
|
|
||||||
|
|
||||||
public string Connection => PostgresTestContext.GetConnectionString(Template);
|
|
||||||
|
|
||||||
public PostgresFixture()
|
|
||||||
{
|
|
||||||
string id = Guid.NewGuid().ToString().Replace('-', '_');
|
|
||||||
Template = $"kyoo_template_{id}";
|
|
||||||
|
|
||||||
_options = new DbContextOptionsBuilder<DatabaseContext>().UseNpgsql(Connection).Options;
|
|
||||||
|
|
||||||
using PostgresContext context = new(_options, null);
|
|
||||||
context.Database.Migrate();
|
|
||||||
|
|
||||||
using NpgsqlConnection conn = (NpgsqlConnection)context.Database.GetDbConnection();
|
|
||||||
conn.Open();
|
|
||||||
conn.ReloadTypes();
|
|
||||||
|
|
||||||
TestSample.FillDatabase(context);
|
|
||||||
conn.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
using PostgresContext context = new(_options, null);
|
|
||||||
context.Database.EnsureDeleted();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class PostgresTestContext : TestContext
|
|
||||||
{
|
|
||||||
private readonly string _database;
|
|
||||||
private readonly DbContextOptions<DatabaseContext> _context;
|
|
||||||
|
|
||||||
public PostgresTestContext(PostgresFixture template, ITestOutputHelper output)
|
|
||||||
{
|
|
||||||
string id = Guid.NewGuid().ToString().Replace('-', '_');
|
|
||||||
_database = $"kyoo_test_{id}";
|
|
||||||
|
|
||||||
using (NpgsqlConnection connection = new(template.Connection))
|
|
||||||
{
|
|
||||||
connection.Open();
|
|
||||||
using NpgsqlCommand cmd =
|
|
||||||
new(
|
|
||||||
$"CREATE DATABASE {_database} WITH TEMPLATE {template.Template}",
|
|
||||||
connection
|
|
||||||
);
|
|
||||||
cmd.ExecuteNonQuery();
|
|
||||||
}
|
|
||||||
|
|
||||||
_context = new DbContextOptionsBuilder<DatabaseContext>()
|
|
||||||
.UseNpgsql(GetConnectionString(_database))
|
|
||||||
.UseLoggerFactory(
|
|
||||||
LoggerFactory.Create(x =>
|
|
||||||
{
|
|
||||||
x.ClearProviders();
|
|
||||||
x.AddXunit(output);
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.EnableSensitiveDataLogging()
|
|
||||||
.EnableDetailedErrors()
|
|
||||||
.Options;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetConnectionString(string database)
|
|
||||||
{
|
|
||||||
string server = Environment.GetEnvironmentVariable("POSTGRES_HOST") ?? "127.0.0.1";
|
|
||||||
string port = Environment.GetEnvironmentVariable("POSTGRES_PORT") ?? "5432";
|
|
||||||
string username = Environment.GetEnvironmentVariable("POSTGRES_USER") ?? "KyooUser";
|
|
||||||
string password =
|
|
||||||
Environment.GetEnvironmentVariable("POSTGRES_PASSWORD") ?? "KyooPassword";
|
|
||||||
return $"Server={server};Port={port};Database={database};User ID={username};Password={password};Include Error Detail=true";
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Dispose()
|
|
||||||
{
|
|
||||||
using DatabaseContext db = New();
|
|
||||||
db.Database.EnsureDeleted();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async ValueTask DisposeAsync()
|
|
||||||
{
|
|
||||||
await using DatabaseContext db = New();
|
|
||||||
await db.Database.EnsureDeletedAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DatabaseContext New()
|
|
||||||
{
|
|
||||||
return new PostgresContext(_context, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DbConnection NewConnection()
|
|
||||||
{
|
|
||||||
return new NpgsqlConnection(GetConnectionString(_database));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Class responsible to fill and create in memory databases for unit tests.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class TestContext : IDisposable, IAsyncDisposable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Add an arbitrary data to the test context.
|
|
||||||
/// </summary>
|
|
||||||
public void Add<T>(T obj)
|
|
||||||
where T : class
|
|
||||||
{
|
|
||||||
using DatabaseContext context = New();
|
|
||||||
context.Set<T>().Add(obj);
|
|
||||||
context.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add an arbitrary data to the test context.
|
|
||||||
/// </summary>
|
|
||||||
public async Task AddAsync<T>(T obj)
|
|
||||||
where T : class
|
|
||||||
{
|
|
||||||
await using DatabaseContext context = New();
|
|
||||||
await context.Set<T>().AddAsync(obj);
|
|
||||||
await context.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get a new database context connected to a in memory Sqlite database.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>A valid DatabaseContext</returns>
|
|
||||||
public abstract DatabaseContext New();
|
|
||||||
|
|
||||||
public abstract DbConnection NewConnection();
|
|
||||||
|
|
||||||
public abstract void Dispose();
|
|
||||||
|
|
||||||
public abstract ValueTask DisposeAsync();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,290 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Postgresql;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests
|
|
||||||
{
|
|
||||||
public static class TestSample
|
|
||||||
{
|
|
||||||
private static readonly Dictionary<Type, Func<object>> NewSamples =
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
typeof(Collection),
|
|
||||||
() =>
|
|
||||||
new Collection
|
|
||||||
{
|
|
||||||
Id = 2.AsGuid(),
|
|
||||||
Slug = "new-collection",
|
|
||||||
Name = "New Collection",
|
|
||||||
Overview = "A collection created by new sample",
|
|
||||||
Thumbnail = new Image("thumbnail")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeof(Show),
|
|
||||||
() =>
|
|
||||||
new Show
|
|
||||||
{
|
|
||||||
Id = 2.AsGuid(),
|
|
||||||
Slug = "new-show",
|
|
||||||
Name = "New Show",
|
|
||||||
Overview = "overview",
|
|
||||||
Status = Status.Planned,
|
|
||||||
StartAir = new DateTime(2011, 1, 1).ToUniversalTime(),
|
|
||||||
EndAir = new DateTime(2011, 1, 1).ToUniversalTime(),
|
|
||||||
Poster = new Image("Poster"),
|
|
||||||
Logo = new Image("Logo"),
|
|
||||||
Thumbnail = new Image("Thumbnail"),
|
|
||||||
Studio = null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeof(Season),
|
|
||||||
() =>
|
|
||||||
new Season
|
|
||||||
{
|
|
||||||
Id = 2.AsGuid(),
|
|
||||||
ShowId = 1.AsGuid(),
|
|
||||||
ShowSlug = Get<Show>().Slug,
|
|
||||||
Name = "New season",
|
|
||||||
Overview = "New overview",
|
|
||||||
EndDate = new DateTime(2000, 10, 10).ToUniversalTime(),
|
|
||||||
SeasonNumber = 2,
|
|
||||||
StartDate = new DateTime(2010, 10, 10).ToUniversalTime(),
|
|
||||||
Logo = new Image("logo")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeof(Episode),
|
|
||||||
() =>
|
|
||||||
new Episode
|
|
||||||
{
|
|
||||||
Id = 2.AsGuid(),
|
|
||||||
ShowId = 1.AsGuid(),
|
|
||||||
ShowSlug = Get<Show>().Slug,
|
|
||||||
SeasonId = 1.AsGuid(),
|
|
||||||
SeasonNumber = Get<Season>().SeasonNumber,
|
|
||||||
EpisodeNumber = 3,
|
|
||||||
AbsoluteNumber = 4,
|
|
||||||
Path = "/episode-path",
|
|
||||||
Name = "New Episode Title",
|
|
||||||
ReleaseDate = new DateTime(2000, 10, 10).ToUniversalTime(),
|
|
||||||
Overview = "new episode overview",
|
|
||||||
Logo = new Image("new episode logo")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeof(People),
|
|
||||||
() =>
|
|
||||||
new People
|
|
||||||
{
|
|
||||||
Id = 2.AsGuid(),
|
|
||||||
Slug = "new-person-name",
|
|
||||||
Name = "New person name",
|
|
||||||
Logo = new Image("Old Logo"),
|
|
||||||
Poster = new Image("Old poster")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static readonly Dictionary<Type, Func<object>> Samples =
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
typeof(Collection),
|
|
||||||
() =>
|
|
||||||
new Collection
|
|
||||||
{
|
|
||||||
Id = 1.AsGuid(),
|
|
||||||
Slug = "collection",
|
|
||||||
Name = "Collection",
|
|
||||||
Overview = "A nice collection for tests",
|
|
||||||
Poster = new Image("Poster")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeof(Show),
|
|
||||||
() =>
|
|
||||||
new Show
|
|
||||||
{
|
|
||||||
Id = 1.AsGuid(),
|
|
||||||
Slug = "anohana",
|
|
||||||
Name = "Anohana: The Flower We Saw That Day",
|
|
||||||
Aliases = new List<string>
|
|
||||||
{
|
|
||||||
"Ano Hi Mita Hana no Namae o Bokutachi wa Mada Shiranai.",
|
|
||||||
"AnoHana",
|
|
||||||
"We Still Don't Know the Name of the Flower We Saw That Day."
|
|
||||||
},
|
|
||||||
Overview =
|
|
||||||
"When Yadomi Jinta was a child, he was a central piece in a group of close friends. "
|
|
||||||
+ "In time, however, these childhood friends drifted apart, and when they became high "
|
|
||||||
+ "school students, they had long ceased to think of each other as friends.",
|
|
||||||
Status = Status.Finished,
|
|
||||||
StudioId = 1.AsGuid(),
|
|
||||||
StartAir = new DateTime(2011, 1, 1).ToUniversalTime(),
|
|
||||||
EndAir = new DateTime(2011, 1, 1).ToUniversalTime(),
|
|
||||||
Poster = new Image("Poster"),
|
|
||||||
Logo = new Image("Logo"),
|
|
||||||
Thumbnail = new Image("Thumbnail"),
|
|
||||||
Studio = null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeof(Season),
|
|
||||||
() =>
|
|
||||||
new Season
|
|
||||||
{
|
|
||||||
Id = 1.AsGuid(),
|
|
||||||
ShowSlug = "anohana",
|
|
||||||
ShowId = 1.AsGuid(),
|
|
||||||
SeasonNumber = 1,
|
|
||||||
Name = "Season 1",
|
|
||||||
Overview = "The first season",
|
|
||||||
StartDate = new DateTime(2020, 06, 05).ToUniversalTime(),
|
|
||||||
EndDate = new DateTime(2020, 07, 05).ToUniversalTime(),
|
|
||||||
Poster = new Image("Poster"),
|
|
||||||
Logo = new Image("Logo"),
|
|
||||||
Thumbnail = new Image("Thumbnail")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeof(Episode),
|
|
||||||
() =>
|
|
||||||
new Episode
|
|
||||||
{
|
|
||||||
Id = 1.AsGuid(),
|
|
||||||
ShowSlug = "anohana",
|
|
||||||
ShowId = 1.AsGuid(),
|
|
||||||
SeasonId = 1.AsGuid(),
|
|
||||||
SeasonNumber = 1,
|
|
||||||
EpisodeNumber = 1,
|
|
||||||
AbsoluteNumber = 1,
|
|
||||||
Path = "/home/kyoo/anohana-s1e1",
|
|
||||||
Poster = new Image("Poster"),
|
|
||||||
Logo = new Image("Logo"),
|
|
||||||
Thumbnail = new Image("Thumbnail"),
|
|
||||||
Name = "Episode 1",
|
|
||||||
Overview = "Summary of the first episode",
|
|
||||||
ReleaseDate = new DateTime(2020, 06, 05).ToUniversalTime()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeof(People),
|
|
||||||
() =>
|
|
||||||
new People
|
|
||||||
{
|
|
||||||
Id = 1.AsGuid(),
|
|
||||||
Slug = "the-actor",
|
|
||||||
Name = "The Actor",
|
|
||||||
Poster = new Image("Poster"),
|
|
||||||
Logo = new Image("Logo"),
|
|
||||||
Thumbnail = new Image("Thumbnail")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeof(Studio),
|
|
||||||
() =>
|
|
||||||
new Studio
|
|
||||||
{
|
|
||||||
Id = 1.AsGuid(),
|
|
||||||
Slug = "hyper-studio",
|
|
||||||
Name = "Hyper studio",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
typeof(User),
|
|
||||||
() =>
|
|
||||||
new User
|
|
||||||
{
|
|
||||||
Id = 1.AsGuid(),
|
|
||||||
Slug = "user",
|
|
||||||
Username = "User",
|
|
||||||
Email = "user@im-a-user.com",
|
|
||||||
Password = "MD5-encoded",
|
|
||||||
Permissions = new[] { "overall.read" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public static T Get<T>()
|
|
||||||
{
|
|
||||||
return (T)Samples[typeof(T)]();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static T GetNew<T>()
|
|
||||||
{
|
|
||||||
return (T)NewSamples[typeof(T)]();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void FillDatabase(DatabaseContext context)
|
|
||||||
{
|
|
||||||
Collection collection = Get<Collection>();
|
|
||||||
context.Collections.Add(collection);
|
|
||||||
|
|
||||||
Show show = Get<Show>();
|
|
||||||
context.Shows.Add(show);
|
|
||||||
|
|
||||||
Season season = Get<Season>();
|
|
||||||
season.Show = show;
|
|
||||||
context.Seasons.Add(season);
|
|
||||||
|
|
||||||
Episode episode = Get<Episode>();
|
|
||||||
episode.Show = show;
|
|
||||||
episode.Season = season;
|
|
||||||
context.Episodes.Add(episode);
|
|
||||||
|
|
||||||
Studio studio = Get<Studio>();
|
|
||||||
studio.Shows = new List<Show> { show };
|
|
||||||
context.Studios.Add(studio);
|
|
||||||
|
|
||||||
People people = Get<People>();
|
|
||||||
// context.People.Add(people);
|
|
||||||
|
|
||||||
User user = Get<User>();
|
|
||||||
context.Users.Add(user);
|
|
||||||
|
|
||||||
context.SaveChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Episode GetAbsoluteEpisode()
|
|
||||||
{
|
|
||||||
return new()
|
|
||||||
{
|
|
||||||
Id = 2.AsGuid(),
|
|
||||||
ShowSlug = "anohana",
|
|
||||||
ShowId = 1.AsGuid(),
|
|
||||||
SeasonNumber = null,
|
|
||||||
EpisodeNumber = null,
|
|
||||||
AbsoluteNumber = 3,
|
|
||||||
Path = "/home/kyoo/anohana-3",
|
|
||||||
Poster = new Image("Poster"),
|
|
||||||
Logo = new Image("Logo"),
|
|
||||||
Thumbnail = new Image("Thumbnail"),
|
|
||||||
Name = "Episode 3",
|
|
||||||
Overview = "Summary of the third absolute episode",
|
|
||||||
ReleaseDate = new DateTime(2020, 06, 05).ToUniversalTime()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using FluentAssertions;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Xunit.Sdk;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Custom assertions used by Kyoo's tests.
|
|
||||||
/// </summary>
|
|
||||||
public static class KAssert
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Check if every property of the item is equal to the other's object.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="expected">The value to check against</param>
|
|
||||||
/// <param name="value">The value to check</param>
|
|
||||||
/// <typeparam name="T">The type to check</typeparam>
|
|
||||||
[AssertionMethod]
|
|
||||||
public static void DeepEqual<T>(T expected, T value)
|
|
||||||
{
|
|
||||||
if (expected is IAddedDate ea && value is IAddedDate va)
|
|
||||||
{
|
|
||||||
ea.AddedDate = DateTime.UnixEpoch;
|
|
||||||
va.AddedDate = DateTime.UnixEpoch;
|
|
||||||
}
|
|
||||||
value.Should().BeEquivalentTo(expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Explicitly fail a test.
|
|
||||||
/// </summary>
|
|
||||||
[AssertionMethod]
|
|
||||||
public static void Fail()
|
|
||||||
{
|
|
||||||
throw new XunitException("Explicit fail");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Explicitly fail a test.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="message">The message that will be seen in the test report</param>
|
|
||||||
[AssertionMethod]
|
|
||||||
public static void Fail(string message)
|
|
||||||
{
|
|
||||||
throw new XunitException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Guid AsGuid(this string src)
|
|
||||||
{
|
|
||||||
// Use MD5 since (1) it's faster then SHA and (2) it's already 16 bytes which matches the Guid
|
|
||||||
return string.IsNullOrWhiteSpace(src)
|
|
||||||
? Guid.Empty
|
|
||||||
: new Guid(MD5.Create().ComputeHash(System.Text.Encoding.UTF8.GetBytes(src)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Guid AsGuid(this int src)
|
|
||||||
{
|
|
||||||
// Use MD5 since (1) it's faster then SHA and (2) it's already 16 bytes which matches the Guid
|
|
||||||
return src == 0
|
|
||||||
? Guid.Empty
|
|
||||||
: new Guid(MD5.Create().ComputeHash(BitConverter.GetBytes(src)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
|
||||||
<LangVersion>default</LangVersion>
|
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="coverlet.msbuild" Version="6.0.0">
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Divergic.Logging.Xunit" Version="4.2.0" />
|
|
||||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
|
|
||||||
<PackageReference Include="Moq" Version="4.20.69" />
|
|
||||||
<PackageReference Include="TvDbSharper" Version="4.0.10" />
|
|
||||||
<PackageReference Include="xunit" Version="2.5.1" />
|
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.1">
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.0">
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
</PackageReference>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="../../src/Kyoo.Abstractions/Kyoo.Abstractions.csproj" />
|
|
||||||
<ProjectReference Include="../../src/Kyoo.Host/Kyoo.Host.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
@ -1,41 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using Kyoo.Utils;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Utility
|
|
||||||
{
|
|
||||||
public class EnumerableTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void IfEmptyTest()
|
|
||||||
{
|
|
||||||
int[] list = { 1, 2, 3, 4 };
|
|
||||||
list = list.IfEmpty(() => KAssert.Fail("Empty action should not be triggered."))
|
|
||||||
.ToArray();
|
|
||||||
list = Array.Empty<int>();
|
|
||||||
Assert.Throws<ArgumentException>(
|
|
||||||
() => list.IfEmpty(() => throw new ArgumentException()).ToList()
|
|
||||||
);
|
|
||||||
Assert.Empty(list.IfEmpty(() => { }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,145 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Kyoo.Utils;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Utility
|
|
||||||
{
|
|
||||||
public class MergerTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void CompleteTest()
|
|
||||||
{
|
|
||||||
Studio genre = new() { Name = "merged" };
|
|
||||||
Studio genre2 = new() { Name = "test", Id = 5.AsGuid(), };
|
|
||||||
Studio ret = Merger.Complete(genre, genre2);
|
|
||||||
Assert.True(ReferenceEquals(genre, ret));
|
|
||||||
Assert.Equal(5.AsGuid(), ret.Id);
|
|
||||||
Assert.Equal("test", genre.Name);
|
|
||||||
Assert.Null(genre.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CompleteDictionaryTest()
|
|
||||||
{
|
|
||||||
Collection collection = new() { Name = "merged", };
|
|
||||||
Collection collection2 = new() { Id = 5.AsGuid(), Name = "test", };
|
|
||||||
Collection ret = Merger.Complete(collection, collection2);
|
|
||||||
Assert.True(ReferenceEquals(collection, ret));
|
|
||||||
Assert.Equal(5.AsGuid(), ret.Id);
|
|
||||||
Assert.Equal("test", ret.Name);
|
|
||||||
Assert.Null(ret.Slug);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CompleteDictionaryOutParam()
|
|
||||||
{
|
|
||||||
Dictionary<string, string> first = new() { ["logo"] = "logo", ["poster"] = "poster" };
|
|
||||||
Dictionary<string, string> second =
|
|
||||||
new() { ["poster"] = "new-poster", ["thumbnail"] = "thumbnails" };
|
|
||||||
IDictionary<string, string> ret = Merger.CompleteDictionaries(
|
|
||||||
first,
|
|
||||||
second,
|
|
||||||
out bool changed
|
|
||||||
);
|
|
||||||
Assert.True(changed);
|
|
||||||
Assert.Equal(3, ret.Count);
|
|
||||||
Assert.Equal("new-poster", ret["poster"]);
|
|
||||||
Assert.Equal("thumbnails", ret["thumbnail"]);
|
|
||||||
Assert.Equal("logo", ret["logo"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CompleteDictionaryEqualTest()
|
|
||||||
{
|
|
||||||
Dictionary<string, string> first = new() { ["poster"] = "poster" };
|
|
||||||
Dictionary<string, string> second = new() { ["poster"] = "new-poster", };
|
|
||||||
IDictionary<string, string> ret = Merger.CompleteDictionaries(
|
|
||||||
first,
|
|
||||||
second,
|
|
||||||
out bool changed
|
|
||||||
);
|
|
||||||
Assert.True(changed);
|
|
||||||
Assert.Single(ret);
|
|
||||||
Assert.Equal("new-poster", ret["poster"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestMergeSetter
|
|
||||||
{
|
|
||||||
public Dictionary<int, int> Backing;
|
|
||||||
|
|
||||||
[UsedImplicitly]
|
|
||||||
public Dictionary<int, int> Dictionary
|
|
||||||
{
|
|
||||||
get => Backing;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Backing = value;
|
|
||||||
KAssert.Fail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CompleteDictionaryNoChangeNoSetTest()
|
|
||||||
{
|
|
||||||
TestMergeSetter first = new() { Backing = new Dictionary<int, int> { [2] = 3 } };
|
|
||||||
TestMergeSetter second = new() { Backing = new Dictionary<int, int>() };
|
|
||||||
Merger.Complete(first, second);
|
|
||||||
// This should no call the setter of first so the test should pass.
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CompleteDictionaryNullValue()
|
|
||||||
{
|
|
||||||
Dictionary<string, string> first = new() { ["logo"] = "logo", ["poster"] = null };
|
|
||||||
Dictionary<string, string> second =
|
|
||||||
new() { ["poster"] = "new-poster", ["thumbnail"] = "thumbnails" };
|
|
||||||
IDictionary<string, string> ret = Merger.CompleteDictionaries(
|
|
||||||
first,
|
|
||||||
second,
|
|
||||||
out bool changed
|
|
||||||
);
|
|
||||||
Assert.True(changed);
|
|
||||||
Assert.Equal(3, ret.Count);
|
|
||||||
Assert.Equal("new-poster", ret["poster"]);
|
|
||||||
Assert.Equal("thumbnails", ret["thumbnail"]);
|
|
||||||
Assert.Equal("logo", ret["logo"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CompleteDictionaryNullValueNoChange()
|
|
||||||
{
|
|
||||||
Dictionary<string, string> first = new() { ["logo"] = "logo", ["poster"] = null };
|
|
||||||
Dictionary<string, string> second = new() { ["poster"] = null, };
|
|
||||||
IDictionary<string, string> ret = Merger.CompleteDictionaries(
|
|
||||||
first,
|
|
||||||
second,
|
|
||||||
out bool changed
|
|
||||||
);
|
|
||||||
Assert.False(changed);
|
|
||||||
Assert.Equal(2, ret.Count);
|
|
||||||
Assert.Null(ret["poster"]);
|
|
||||||
Assert.Equal("logo", ret["logo"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,96 +0,0 @@
|
|||||||
// Kyoo - A portable and vast media library solution.
|
|
||||||
// Copyright (c) Kyoo.
|
|
||||||
//
|
|
||||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
|
||||||
//
|
|
||||||
// Kyoo is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// any later version.
|
|
||||||
//
|
|
||||||
// Kyoo is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Reflection;
|
|
||||||
using Kyoo.Abstractions.Models;
|
|
||||||
using Xunit;
|
|
||||||
using KUtility = Kyoo.Utils.Utility;
|
|
||||||
|
|
||||||
namespace Kyoo.Tests.Utility
|
|
||||||
{
|
|
||||||
public class UtilityTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void IsPropertyExpression_Tests()
|
|
||||||
{
|
|
||||||
Expression<Func<Show, Guid>> member = x => x.Id;
|
|
||||||
Expression<Func<Show, object>> memberCast = x => x.Id;
|
|
||||||
|
|
||||||
Assert.True(KUtility.IsPropertyExpression(member));
|
|
||||||
Assert.True(KUtility.IsPropertyExpression(memberCast));
|
|
||||||
|
|
||||||
Expression<Func<Show, object>> call = x => x.ToString();
|
|
||||||
Assert.False(KUtility.IsPropertyExpression(call));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetPropertyName_Test()
|
|
||||||
{
|
|
||||||
Expression<Func<Show, Guid>> member = x => x.Id;
|
|
||||||
Expression<Func<Show, object>> memberCast = x => x.Id;
|
|
||||||
|
|
||||||
Assert.Equal("Id", KUtility.GetPropertyName(member));
|
|
||||||
Assert.Equal("Id", KUtility.GetPropertyName(memberCast));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetMethodTest()
|
|
||||||
{
|
|
||||||
MethodInfo method = KUtility.GetMethod(
|
|
||||||
typeof(UtilityTests),
|
|
||||||
BindingFlags.Instance | BindingFlags.Public,
|
|
||||||
nameof(GetMethodTest),
|
|
||||||
Array.Empty<Type>(),
|
|
||||||
Array.Empty<object>()
|
|
||||||
);
|
|
||||||
Assert.Equal(MethodBase.GetCurrentMethod(), method);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetMethodInvalidGenericsTest()
|
|
||||||
{
|
|
||||||
Assert.Throws<ArgumentException>(
|
|
||||||
() =>
|
|
||||||
KUtility.GetMethod(
|
|
||||||
typeof(UtilityTests),
|
|
||||||
BindingFlags.Instance | BindingFlags.Public,
|
|
||||||
nameof(GetMethodTest),
|
|
||||||
new[] { typeof(KUtility) },
|
|
||||||
Array.Empty<object>()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetMethodInvalidParamsTest()
|
|
||||||
{
|
|
||||||
Assert.Throws<ArgumentException>(
|
|
||||||
() =>
|
|
||||||
KUtility.GetMethod(
|
|
||||||
typeof(UtilityTests),
|
|
||||||
BindingFlags.Instance | BindingFlags.Public,
|
|
||||||
nameof(GetMethodTest),
|
|
||||||
Array.Empty<Type>(),
|
|
||||||
new object[] { this }
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user