Files
Deal/src/telegram-service/Deal.Telegram.Tests/TestDoubles.cs
T
Rustam Khalimov 492950bdd0 Отформатировать списки параметров по код-стайлу
Больше двух параметров — каждый на отдельной строке (закрывающая
скобка в конце последнего); два и меньше — в одну строку. Правило
добавлено в docs/spec/Код-стайл-Дейл.md; применено к 628 сигнатурам
в 253 файлах.
2026-09-11 13:22:56 +03:00

99 lines
3.8 KiB
C#

using Deal.Grpc.Telegram;
using Deal.Telegram.Core;
using Deal.Telegram.Dialogs;
using Grpc.Core;
namespace Deal.Telegram.Tests;
// Фейк исходящего канала в ядро (ICoreIngressClient) для unit-тестов служб каталога: записывает
// PushMessage/SyncDialogs без сети; SyncDialogs возвращает настраиваемый monitored-набор (роль ядра,
// Ruling 7). Проводка реального gRPC-канала проверяется отдельно — CoreIngressClientTests против
// in-proc фейк-сервера ингресса (FakeIngressServer).
internal sealed class FakeIngress : ICoreIngressClient
{
/// <summary>
/// Отправленные PushMessage (tenant + запрос), в порядке вызовов.
/// </summary>
public List<(string TenantId, PushMessageRequest Message)> Pushes { get; } = [];
/// <summary>
/// Синхронизации каталога (tenant + entries), в порядке вызовов.
/// </summary>
public List<(string TenantId, IReadOnlyList<DialogEntry> Entries)> Syncs { get; } = [];
/// <summary>
/// Monitored-набор, который фейк возвращает ответом SyncDialogs (как ядро).
/// </summary>
public List<string> MonitoredIdsToReturn { get; set; } = [];
/// <summary>
/// Ошибка PushMessageAsync (null — успех).
/// </summary>
public Exception? PushError { get; set; }
/// <summary>
/// Ошибка SyncDialogsAsync (null — успех).
/// </summary>
public Exception? SyncError { get; set; }
/// <summary>
/// Текст последнего PushMessage (для быстрых проверок).
/// </summary>
public string? LastPushText => Pushes.Count == 0 ? null : Pushes[^1].Message.Text;
/// <summary>
/// Id последнего отправленного диалога.
/// </summary>
public string? LastPushDialogId => Pushes.Count == 0 ? null : Pushes[^1].Message.DialogId;
/// <inheritdoc />
public Task<PushMessageReply> PushMessageAsync(
string tenantId,
PushMessageRequest message,
CancellationToken cancellationToken)
{
if (PushError is not null)
{
throw PushError;
}
Pushes.Add((tenantId, message));
return Task.FromResult(new PushMessageReply { Accepted = true, Duplicate = false });
}
/// <inheritdoc />
public Task<IReadOnlyList<string>> SyncDialogsAsync(
string tenantId,
IReadOnlyList<DialogEntry> entries,
CancellationToken cancellationToken)
{
if (SyncError is not null)
{
throw SyncError;
}
Syncs.Add((tenantId, entries.ToArray()));
return Task.FromResult<IReadOnlyList<string>>(MonitoredIdsToReturn.ToArray());
}
}
// Фейк анти-бан-пейсера: паузы не ждёт, а записывает запрошенные диапазоны (сек) — проверка
// «паузы 1.5–3 с/сообщение, 3–6 с/диалог» без реальных задержек (fake clock плана Task 10).
internal sealed class RecordingPacer : IBackfillPacer
{
/// <summary>
/// Запрошенные диапазоны пауз (min/max, сек), в порядке вызовов.
/// </summary>
public List<(double MinSeconds, double MaxSeconds)> Waits { get; } = [];
/// <inheritdoc />
public Task WaitAsync(
double minSeconds,
double maxSeconds,
CancellationToken cancellationToken)
{
Waits.Add((minSeconds, maxSeconds));
return Task.CompletedTask;
}
}