food-market/tests/food-market.IntegrationTests
nns 7b7a7091b9 feat(auth): TOTP 2FA для админов через AuthenticatorTokenProvider (P2-4)
ASP.NET Identity AuthenticatorTokenProvider (RFC 6238 — Google
Authenticator, Authy, 1Password OTP). TwoFactorEnabled и SecurityStamp
уже были в users-таблице из Identity-схемы.

Endpoints (Bearer-auth):
- GET /api/me/2fa/status — { enabled: bool }.
- POST /api/me/2fa/enroll — генерирует SecretKey (если ещё нет),
  возвращает otpauth-URI для QR + сам shared-key. Пока 2FA включён,
  enroll возвращает alreadyEnabled=true без секрета.
- POST /api/me/2fa/verify { code } — валидирует и включает 2FA.
- POST /api/me/2fa/disable { code } — выключает + ResetAuthenticatorKeyAsync.
  Требует текущий code как защиту от случайного отключения.

AuthorizationController.Exchange (password grant): после успеха проверки
пароля смотрит TwoFactorEnabledAsync; если true и нет otp_code в
запросе — возвращает invalid_grant с error_description="2fa_required";
если otp_code невалиден — "2fa_invalid"; иначе токен выдаётся.

Опционально для всех ролей — User самостоятельно решает включать или нет.
Для админов рекомендуется (отдельная политика — следующий шаг).

Тесты: 4 интеграционных (enroll+verify+status, неверный code → 400,
token-endpoint require otp_code, disable с code). Тесты сами генерируют
TOTP через ручную RFC 6238 имплементацию (HMAC-SHA1, 30-сек step).

Bonus: добавлены DI-заглушки UnusedSupplyWriter / UnusedRetailSalePoster
для CQRS-handler'ов из TD-1 — handler'ы пока не подключены к
контроллерам, заглушки нужны чтобы DI-validation на старте не падала.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 17:57:32 +05:00
..
Support feat(reports): отчёт «Продажи» с группировками и экспортом (P1-8) 2026-05-28 11:09:52 +05:00
AbcReportTests.cs feat(reports): ABC-анализ по Парето (P1-11) 2026-05-28 11:24:26 +05:00
ConcurrencyTokenTests.cs feat(concurrency): RowVersion на документах через Postgres xmin (TD-6) 2026-05-28 17:33:01 +05:00
CustomerReturnTests.cs feat(returns): возврат от покупателя (CustomerReturn) (P1-6) 2026-05-28 09:51:04 +05:00
DemandPostUnpostTests.cs feat(demands): оптовая отгрузка контрагенту-юрлицу (P1-5) 2026-05-28 16:18:49 +05:00
EnterPostUnpostTests.cs feat(enters): оприходование товара без поставщика (P1-1) 2026-05-28 09:18:13 +05:00
food-market.IntegrationTests.csproj test(integration): Testcontainers.PostgreSql + WebApplicationFactory, 10 тестов (P1-21) 2026-05-27 03:14:01 +05:00
HangfireDashboardTests.cs feat(hangfire): dashboard + scheduled cleanup джобы (P1-16) 2026-05-28 10:07:14 +05:00
ImportJobPersistenceTests.cs feat(import-jobs): persisted ImportJobRegistry в БД (TD-5) 2026-05-28 16:45:08 +05:00
InventoryPostUnpostTests.cs feat(inventories): инвентаризация с CSV-импортом факта (P1-4) 2026-05-28 09:39:32 +05:00
LossPostUnpostTests.cs feat(losses): списание со склада с указанием причины (P1-2) 2026-05-28 09:24:40 +05:00
MetricsEndpointTests.cs feat(observability): Prometheus метрики /metrics + бизнес-счётчики (P1-17) 2026-05-28 12:20:01 +05:00
OrgAuditLogTests.cs feat(audit): per-tenant журнал мутаций OrgAuditLog (P1-18) 2026-05-28 16:26:36 +05:00
PermissionTests.cs test(integration): Testcontainers.PostgreSql + WebApplicationFactory, 10 тестов (P1-21) 2026-05-27 03:14:01 +05:00
PosSyncTests.cs feat(pos-api): GET /sync и POST /sales с двойной идемпотентностью (P1-12b) 2026-05-28 12:10:17 +05:00
ProfitReportTests.cs feat(reports): отчёт «Прибыль» (выручка − COGS) (P1-10) 2026-05-28 11:19:19 +05:00
RetailOversellingTests.cs test(integration): Testcontainers.PostgreSql + WebApplicationFactory, 10 тестов (P1-21) 2026-05-27 03:14:01 +05:00
SalesReportTests.cs feat(reports): отчёт «Продажи» с группировками и экспортом (P1-8) 2026-05-28 11:09:52 +05:00
SignupFlowTests.cs test(integration): Testcontainers.PostgreSql + WebApplicationFactory, 10 тестов (P1-21) 2026-05-27 03:14:01 +05:00
StockReportTests.cs feat(reports): отчёт «Остатки на дату» с реконструкцией (P1-9) 2026-05-28 11:14:24 +05:00
SupplierReturnTests.cs feat(supplier-returns): возврат поставщику (P1-7) 2026-05-28 09:58:29 +05:00
SupplyPostUnpostTests.cs test(integration): Testcontainers.PostgreSql + WebApplicationFactory, 10 тестов (P1-21) 2026-05-27 03:14:01 +05:00
TenantIsolationTests.cs test(integration): Testcontainers.PostgreSql + WebApplicationFactory, 10 тестов (P1-21) 2026-05-27 03:14:01 +05:00
TransferPostUnpostTests.cs feat(transfers): атомарное перемещение между складами (P1-3) 2026-05-28 09:32:32 +05:00
TwoFactorTests.cs feat(auth): TOTP 2FA для админов через AuthenticatorTokenProvider (P2-4) 2026-05-28 17:57:32 +05:00