Updated the CreateCollectionFromSuggestionCommandHandler and CreateGroupFromSuggestionCommandHandler to compare names in memory rather than using SQL queries for case-insensitive checks. This change addresses potential discrepancies with SQL's case sensitivity, particularly with special characters. Additionally, modified unit tests to use array syntax for assertions, enhancing readability and consistency across the test suite.
211 lines
7.2 KiB
C#
211 lines
7.2 KiB
C#
using Microsoft.Extensions.Options;
|
||
using TeleWave.Application.Tests.TestSupport;
|
||
using TeleWave.Domain.Library;
|
||
using TeleWave.Infrastructure.Metadata;
|
||
using Xunit;
|
||
|
||
namespace TeleWave.Application.Tests.Metadata;
|
||
|
||
/// <summary>
|
||
/// Разбор ответов OMDb. Особенности источника, ради которых тесты и написаны: «N/A» вместо
|
||
/// отсутствующего значения, флаг <c>Response</c> вместо кода ошибки и жанры одной строкой.
|
||
/// </summary>
|
||
public class OmdbMetadataProviderTests
|
||
{
|
||
private static OmdbMetadataProvider Provider(FakeHttpClientFactory http) =>
|
||
new(
|
||
http,
|
||
Options.Create(new MetadataOptions { Omdb = new OmdbOptions { ApiKey = "key" } })
|
||
);
|
||
|
||
[Fact]
|
||
public async Task SearchShows_KeepsOnlyShowsWithId()
|
||
{
|
||
var http = FakeHttpClientFactory.Json(
|
||
"""
|
||
{"Search":[
|
||
{"imdbID":"tt1","Title":"Сериал","Year":"2001–2005","Type":"series","Poster":"http://p/1.jpg"},
|
||
{"imdbID":"tt2","Title":"Серия","Type":"episode"},
|
||
{"Title":"Без идентификатора","Type":"movie"},
|
||
{"imdbID":"tt3","Title":"Фильм","Year":"N/A","Type":"movie","Poster":"N/A"}
|
||
]}
|
||
"""
|
||
);
|
||
|
||
var found = await Provider(http)
|
||
.SearchShowsAsync("сериал", ShowKind.Series, CancellationToken.None);
|
||
|
||
Assert.Contains("type=series", http.LastUrl);
|
||
Assert.Equal(2, found.Count);
|
||
Assert.Equal("tt1", found[0].ExternalId);
|
||
Assert.Equal(2001, found[0].Year);
|
||
Assert.Equal("http://p/1.jpg", found[0].PosterUrl);
|
||
Assert.Equal(ShowKind.Series, found[0].Kind);
|
||
// Отдельные серии просачиваются в выдачу и шоу не годятся, запись без imdbID — тоже.
|
||
Assert.Equal("tt3", found[1].ExternalId);
|
||
Assert.Equal(ShowKind.Single, found[1].Kind);
|
||
Assert.Null(found[1].Year);
|
||
Assert.Null(found[1].PosterUrl);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task SearchShows_Single_AsksForMovies()
|
||
{
|
||
var http = FakeHttpClientFactory.Json("{}");
|
||
|
||
var found = await Provider(http)
|
||
.SearchShowsAsync("фильм", ShowKind.Single, CancellationToken.None);
|
||
|
||
Assert.Contains("type=movie", http.LastUrl);
|
||
Assert.Empty(found);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetShow_ReadsRatingAndSplitsGenres()
|
||
{
|
||
var http = FakeHttpClientFactory.Json(
|
||
"""
|
||
{"Response":"True","Title":"Сериал","Year":"2001–2005","Plot":"описание",
|
||
"Poster":"http://p/1.jpg","Genre":"Action, Sci-Fi","Rated":"TV-14"}
|
||
"""
|
||
);
|
||
|
||
var show = await Provider(http)
|
||
.GetShowAsync("tt1", ShowKind.Series, CancellationToken.None);
|
||
|
||
Assert.Contains("i=tt1", http.LastUrl);
|
||
Assert.NotNull(show);
|
||
Assert.Equal("tt1", show.ExternalId);
|
||
Assert.Equal("Сериал", show.Title);
|
||
Assert.Equal(2001, show.Year);
|
||
Assert.Equal("описание", show.Overview);
|
||
Assert.Equal(["Action", "Sci-Fi"], show.Genres);
|
||
Assert.Equal("TV-14", show.ContentRating);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetShow_TreatsNotAvailableAsMissing()
|
||
{
|
||
var http = FakeHttpClientFactory.Json(
|
||
"""{"Response":"True","Title":"N/A","Plot":"N/A","Poster":"N/A","Genre":"N/A","Rated":"N/A"}"""
|
||
);
|
||
|
||
var show = await Provider(http)
|
||
.GetShowAsync("tt1", ShowKind.Single, CancellationToken.None);
|
||
|
||
Assert.NotNull(show);
|
||
Assert.Equal("—", show.Title);
|
||
Assert.Null(show.Overview);
|
||
Assert.Null(show.PosterUrl);
|
||
Assert.Null(show.ContentRating);
|
||
Assert.Empty(show.Genres!);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetShow_ReturnsNull_WhenResponseIsFalse()
|
||
{
|
||
var http = FakeHttpClientFactory.Json(
|
||
"""{"Response":"False","Error":"Movie not found!"}"""
|
||
);
|
||
|
||
var show = await Provider(http)
|
||
.GetShowAsync("tt0", ShowKind.Series, CancellationToken.None);
|
||
|
||
Assert.Null(show);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetShow_ReturnsNull_WhenRequestFails()
|
||
{
|
||
var show = await Provider(FakeHttpClientFactory.Failing())
|
||
.GetShowAsync("tt1", ShowKind.Series, CancellationToken.None);
|
||
|
||
Assert.Null(show);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetEpisode_ReadsTitleAndReleaseDate()
|
||
{
|
||
var http = FakeHttpClientFactory.Json(
|
||
"""
|
||
{"Response":"True","Title":"Серия","Plot":"о серии","Poster":"http://p/s.jpg",
|
||
"Released":"07 Jun 2001"}
|
||
"""
|
||
);
|
||
|
||
var episode = await Provider(http).GetEpisodeAsync("tt1", 2, 3, CancellationToken.None);
|
||
|
||
Assert.Contains("Season=2", http.LastUrl);
|
||
Assert.Contains("Episode=3", http.LastUrl);
|
||
Assert.NotNull(episode);
|
||
Assert.Equal("Серия", episode.Title);
|
||
Assert.Equal("http://p/s.jpg", episode.StillUrl);
|
||
Assert.Equal(new DateOnly(2001, 6, 7), episode.AirDate);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetEpisode_ReturnsNull_WhenResponseIsFalse()
|
||
{
|
||
var http = FakeHttpClientFactory.Json("""{"Response":"False"}""");
|
||
|
||
var episode = await Provider(http).GetEpisodeAsync("tt1", 9, 9, CancellationToken.None);
|
||
|
||
Assert.Null(episode);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetSeasonEpisodeCount_CountsEpisodes()
|
||
{
|
||
var http = FakeHttpClientFactory.Json(
|
||
"""{"Response":"True","Episodes":[{"Episode":"1"},{"Episode":"2"}]}"""
|
||
);
|
||
|
||
var count = await Provider(http)
|
||
.GetSeasonEpisodeCountAsync("tt1", 2, CancellationToken.None);
|
||
|
||
Assert.Equal(2, count);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetSeasonEpisodeCount_ReturnsNull_WhenSeasonMissing()
|
||
{
|
||
var http = FakeHttpClientFactory.Json("""{"Response":"True"}""");
|
||
|
||
var count = await Provider(http)
|
||
.GetSeasonEpisodeCountAsync("tt1", 9, CancellationToken.None);
|
||
|
||
Assert.Null(count);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetSeasonNumbers_NumbersSeasonsContinuously()
|
||
{
|
||
// Перечня сезонов OMDb не отдаёт — только их количество строкой.
|
||
var http = FakeHttpClientFactory.Json("""{"Response":"True","totalSeasons":"3"}""");
|
||
|
||
var seasons = await Provider(http).GetSeasonNumbersAsync("tt1", CancellationToken.None);
|
||
|
||
Assert.Equal([1, 2, 3], seasons);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetSeasonNumbers_ReturnsEmpty_WhenTotalIsNotANumber()
|
||
{
|
||
var http = FakeHttpClientFactory.Json("""{"Response":"True","totalSeasons":"N/A"}""");
|
||
|
||
var seasons = await Provider(http).GetSeasonNumbersAsync("tt1", CancellationToken.None);
|
||
|
||
Assert.Empty(seasons);
|
||
}
|
||
|
||
[Fact]
|
||
public async Task GetSeasonNumbers_ReturnsEmpty_WhenResponseIsFalse()
|
||
{
|
||
var http = FakeHttpClientFactory.Json("""{"Response":"False"}""");
|
||
|
||
var seasons = await Provider(http).GetSeasonNumbersAsync("tt1", CancellationToken.None);
|
||
|
||
Assert.Empty(seasons);
|
||
}
|
||
}
|