using Microsoft.EntityFrameworkCore;
using TeleWave.Application.Library.Collections;
using TeleWave.Infrastructure.Persistence;
using Xunit;
namespace TeleWave.Integration.Tests;
///
/// Проверка переводимости запросов в SQL. Соединение не открывается: ToQueryString компилирует
/// запрос и падает ровно там, где падал бы прод («The LINQ expression could not be translated»).
/// Поэтому Docker не нужен, и такие ошибки ловятся быстро.
///
/// Повод: карточка шоу отвечала 500, потому что сортировка стояла после сборки DTO — EF не переводит
/// порядок по свойству record'а.
///
public sealed class QueryTranslationTests : IDisposable
{
private readonly AppDbContext _db = new(
new DbContextOptionsBuilder()
// Сервера по адресу нет и не требуется — запрос только компилируется.
.UseNpgsql("Host=127.0.0.1;Port=1;Database=telewave;Username=u;Password=p")
.Options
);
[Fact]
public void ShowCollections_Translates()
{
var showId = Guid.NewGuid();
var sql = _db
.CollectionItems.AsNoTracking()
.Where(i => i.ShowId == showId)
.Join(
_db.Collections.AsNoTracking(),
item => item.CollectionId,
collection => collection.Id,
(item, collection) =>
new
{
collection.Id,
collection.Name,
item.Position,
}
)
.OrderBy(c => c.Name)
.Select(c => new ShowCollectionRefDto(c.Id, c.Name, c.Position))
.ToQueryString();
Assert.Contains("ORDER BY", sql, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void ShowCollections_OrderingAfterProjection_DoesNotTranslate()
{
// Зафиксировано намеренно: именно эта форма роняла карточку шоу в 500. Если EF когда-нибудь
// научится её переводить, тест упадёт — и это будет поводом упростить запрос обратно.
var showId = Guid.NewGuid();
var query = _db
.CollectionItems.AsNoTracking()
.Where(i => i.ShowId == showId)
.Join(
_db.Collections.AsNoTracking(),
item => item.CollectionId,
collection => collection.Id,
(item, collection) =>
new ShowCollectionRefDto(collection.Id, collection.Name, item.Position)
)
.OrderBy(c => c.Name);
Assert.Throws(() => query.ToQueryString());
}
public void Dispose() => _db.Dispose();
}