Files
TeleWave/backend/tests/TeleWave.Application.Tests/Library/AddShowsToCollectionTests.cs
T
Leonid Pershin 3fecd81333
ci / build-backend (push) Successful in 1m37s
ci / build-frontend (push) Successful in 53s
ci / tests (push) Successful in 1m46s
ci / sonar (push) Successful in 4m38s
Enhance ShowMetadataApplier with logging for poster retrieval failures
Updated the ShowMetadataApplier class to include logging for scenarios where show posters are not retrieved successfully. Introduced logging statements to capture warnings when poster URLs are empty or when downloads fail, improving traceability and debugging capabilities. Additionally, updated related tests to ensure proper logging behavior during poster processing.
2026-07-30 02:00:07 +03:00

148 lines
5.5 KiB
C#

using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging.Abstractions;
using NSubstitute;
using TeleWave.Application.Common.Interfaces;
using TeleWave.Application.Library.Collections.AddShowsToCollection;
using TeleWave.Application.Library.Genres;
using TeleWave.Application.Metadata;
using TeleWave.Application.Metadata.EnrichShows;
using TeleWave.Application.Tests.Support;
using TeleWave.Domain.Library;
using Xunit;
namespace TeleWave.Application.Tests.Library;
/// <summary>Массовые операции над отмеченными шоу: раскладка по франшизам и обогащение.</summary>
public class AddShowsToCollectionTests
{
[Fact]
public async Task AddsToExistingCollection_SkippingThoseAlreadyIn()
{
var fixture = new TestDb();
var inside = Show.Create("Уже внутри", ShowKind.Single);
var outside = Show.Create("Ещё нет", ShowKind.Single);
var collection = Collection.Create("Франшиза");
collection.AddShow(inside.Id);
await using (var seed = fixture.New())
{
seed.Shows.AddRange(inside, outside);
seed.Collections.Add(collection);
await seed.SaveChangesAsync(CancellationToken.None);
}
await using var db = fixture.New();
var result = await new AddShowsToCollectionCommandHandler(db).Handle(
new AddShowsToCollectionCommand([inside.Id, outside.Id], collection.Id),
CancellationToken.None
);
await db.SaveChangesAsync(CancellationToken.None);
Assert.True(result.IsSuccess);
// Повторное добавление молча пропускается: падать из-за одного повтора бессмысленно.
Assert.Equal(1, result.Value.Added);
Assert.Equal("Франшиза", result.Value.Name);
await using var check = fixture.New();
Assert.Equal(2, check.Collections.Include(c => c.Items).Single().Items.Count);
}
[Fact]
public async Task Fails_WhenCollectionIsGone()
{
var fixture = new TestDb();
var show = Show.Create("Шоу", ShowKind.Single);
await using (var seed = fixture.New())
{
seed.Shows.Add(show);
await seed.SaveChangesAsync(CancellationToken.None);
}
await using var db = fixture.New();
var result = await new AddShowsToCollectionCommandHandler(db).Handle(
new AddShowsToCollectionCommand([show.Id], Guid.NewGuid()),
CancellationToken.None
);
Assert.False(result.IsSuccess);
}
[Fact]
public async Task Fails_WhenNoneOfTheShowsExist()
{
var fixture = new TestDb();
await using var db = fixture.New();
var result = await new AddShowsToCollectionCommandHandler(db).Handle(
new AddShowsToCollectionCommand([Guid.NewGuid()], NewCollectionName: "Франшиза"),
CancellationToken.None
);
Assert.False(result.IsSuccess);
}
[Fact]
public async Task Enrich_FailsWhenProviderUnavailable()
{
var fixture = new TestDb();
await using var db = fixture.New();
var resolver = Substitute.For<IMetadataProviderResolver>();
// Явно: NSubstitute сам подставляет заглушку вместо интерфейсного null, и без этого
// «источник не настроен» не воспроизводится.
resolver.Resolve(Arg.Any<string>()).Returns((IMetadataProvider?)null);
var result = await new EnrichShowsMetadataCommandHandler(
db,
resolver,
new ShowMetadataApplier(
db,
resolver,
Substitute.For<IImageDownloader>(),
Substitute.For<IImageStore>(),
new GenreMatcher(db),
NullLogger<ShowMetadataApplier>.Instance
)
).Handle(new EnrichShowsMetadataCommand([Guid.NewGuid()], "tmdb"), CancellationToken.None);
Assert.False(result.IsSuccess);
}
[Fact]
public async Task Enrich_IgnoresInterstitials()
{
// Ролики метаданными не обогащаются: у них нет ни года, ни постера.
var fixture = new TestDb();
var clip = Show.Create("Ролик", ShowKind.Interstitial);
await using (var seed = fixture.New())
{
seed.Shows.Add(clip);
await seed.SaveChangesAsync(CancellationToken.None);
}
var provider = Substitute.For<IMetadataProvider>();
var resolver = Substitute.For<IMetadataProviderResolver>();
resolver.Resolve("tmdb").Returns(provider);
await using var db = fixture.New();
var result = await new EnrichShowsMetadataCommandHandler(
db,
resolver,
new ShowMetadataApplier(
db,
resolver,
Substitute.For<IImageDownloader>(),
Substitute.For<IImageStore>(),
new GenreMatcher(db),
NullLogger<ShowMetadataApplier>.Instance
)
).Handle(new EnrichShowsMetadataCommand([clip.Id], "tmdb"), CancellationToken.None);
Assert.True(result.IsSuccess);
Assert.Equal(0, result.Value.Applied);
Assert.Empty(result.Value.Skipped);
await provider
.DidNotReceive()
.SearchShowsAsync(Arg.Any<string>(), Arg.Any<ShowKind>(), Arg.Any<CancellationToken>());
}
}