Files
ersatztv/ErsatzTV.Scanner.Tests/Application/Jellyfin/SynchronizeJellyfinLibraryByIdHandlerTests.cs
T
timothy 5560790bcb
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 3m53s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 5m4s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
feat(jellyfin): sync music video libraries refs #42
2026-06-30 19:33:06 +02:00

100 lines
4.1 KiB
C#

using ErsatzTV.Core;
using ErsatzTV.Core.Domain;
using ErsatzTV.Core.Interfaces.Jellyfin;
using ErsatzTV.Core.Interfaces.Repositories;
using ErsatzTV.Core.Jellyfin;
using ErsatzTV.Scanner.Application.Jellyfin;
using ErsatzTV.Scanner.Core.Interfaces;
using Microsoft.Extensions.Logging;
using NSubstitute;
using NUnit.Framework;
using Shouldly;
namespace ErsatzTV.Scanner.Tests.Application.Jellyfin;
public class SynchronizeJellyfinLibraryByIdHandlerTests
{
[TestFixture]
public class Handle
{
[Test]
public async Task Should_Scan_MusicVideo_Libraries()
{
var scannerProxy = Substitute.For<IScannerProxy>();
var mediaSourceRepository = Substitute.For<IMediaSourceRepository>();
var jellyfinSecretStore = Substitute.For<IJellyfinSecretStore>();
var jellyfinMovieLibraryScanner = Substitute.For<IJellyfinMovieLibraryScanner>();
var jellyfinTelevisionLibraryScanner = Substitute.For<IJellyfinTelevisionLibraryScanner>();
var jellyfinMusicVideoLibraryScanner = Substitute.For<IJellyfinMusicVideoLibraryScanner>();
var libraryRepository = Substitute.For<ILibraryRepository>();
var configElementRepository = Substitute.For<IConfigElementRepository>();
var library = new JellyfinLibrary
{
Id = 42,
Name = "Concerts",
MediaKind = LibraryMediaKind.MusicVideos,
MediaSourceId = 7
};
var mediaSource = new JellyfinMediaSource
{
Id = 7,
Connections =
[
new JellyfinConnection
{
Address = "http://jellyfin.example",
JellyfinMediaSourceId = 7
}
]
};
mediaSourceRepository.GetJellyfinByLibraryId(library.Id).Returns(Some(mediaSource).AsTask());
mediaSourceRepository.GetJellyfinLibrary(library.Id).Returns(Some(library).AsTask());
jellyfinSecretStore.ReadSecrets().Returns(new JellyfinSecrets
{
Address = "http://jellyfin.example",
ApiKey = "abc"
});
configElementRepository.GetValue<int>(
Arg.Is<ConfigElementKey>(key => key.Key == ConfigElementKey.LibraryRefreshInterval.Key),
Arg.Any<CancellationToken>())
.Returns(Task.FromResult<Option<int>>(Some(0)));
jellyfinMusicVideoLibraryScanner.ScanLibrary(
Arg.Any<JellyfinConnectionParameters>(),
library,
true,
Arg.Any<CancellationToken>())
.Returns(Right<BaseError, Unit>(Unit.Default).AsTask());
var handler = new SynchronizeJellyfinLibraryByIdHandler(
scannerProxy,
mediaSourceRepository,
jellyfinSecretStore,
jellyfinMovieLibraryScanner,
jellyfinTelevisionLibraryScanner,
jellyfinMusicVideoLibraryScanner,
libraryRepository,
configElementRepository,
Substitute.For<ILogger<SynchronizeJellyfinLibraryByIdHandler>>());
Either<BaseError, string> result = await handler.Handle(
new SynchronizeJellyfinLibraryById("http://ersatztv.example", library.Id, true, true),
CancellationToken.None);
result.LeftToSeq().ShouldBeEmpty();
result.IsRight.ShouldBeTrue();
result.RightToSeq().Single().ShouldBe("Concerts");
await jellyfinMusicVideoLibraryScanner.Received(1).ScanLibrary(
Arg.Is<JellyfinConnectionParameters>(cp =>
cp.Address == "http://jellyfin.example" &&
cp.ApiKey == "abc" &&
cp.MediaSourceId == 7),
library,
true,
Arg.Any<CancellationToken>());
await libraryRepository.Received(1).UpdateLastScan(library);
}
}
}