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(); }