76 lines
3.1 KiB
C#
76 lines
3.1 KiB
C#
using Microsoft.EntityFrameworkCore;
|
||
using TeleWave.Application.Library.Collections;
|
||
using TeleWave.Infrastructure.Persistence;
|
||
using Xunit;
|
||
|
||
namespace TeleWave.Integration.Tests;
|
||
|
||
/// <summary>
|
||
/// Проверка переводимости запросов в SQL. Соединение не открывается: <c>ToQueryString</c> компилирует
|
||
/// запрос и падает ровно там, где падал бы прод («The LINQ expression could not be translated»).
|
||
/// Поэтому Docker не нужен, и такие ошибки ловятся быстро.
|
||
///
|
||
/// Повод: карточка шоу отвечала 500, потому что сортировка стояла после сборки DTO — EF не переводит
|
||
/// порядок по свойству record'а.
|
||
/// </summary>
|
||
public sealed class QueryTranslationTests : IDisposable
|
||
{
|
||
private readonly AppDbContext _db = new(
|
||
new DbContextOptionsBuilder<AppDbContext>()
|
||
// Сервера по адресу нет и не требуется — запрос только компилируется.
|
||
.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<InvalidOperationException>(() => query.ToQueryString());
|
||
}
|
||
|
||
public void Dispose() => _db.Dispose();
|
||
}
|