Подключить NSubstitute и мигрировать FakePasswordHasher, зафиксировать правила тестов
ci / build-test (push) Has been cancelled

NSubstitute 6.1.0 в 5 тест-проектов; эталон миграции: FakePasswordHasher удалён,
вместо него Support/TestHashers.New() (Substitute.For с детерминированной
семантикой fake-hash:, DI-регистрации переведены на инстанс хелпера).
Правила владельца в §11 код-стайла: классы напрямую не вызываем (DTO/хелперы/
экстеншены — исключения), моки через NSubstitute, маркерные классы не используем.
План миграции оставшихся фейков — backlog TD-TESTS-NSUBSTITUTE. Build 5 sln 0/0,
тесты 1340/130/52/38/9 зелёные.
This commit is contained in:
Rustam Khalimov
2026-09-11 20:25:39 +03:00
parent 93e9100ae4
commit b745c324e3
30 changed files with 157 additions and 75 deletions
+2 -1
View File
@@ -16,7 +16,8 @@
| BL-RECLASS-SSE | **Сделано (2026-09-11):** пакетная переклассификация отдаёт промежуточный прогресс через SSE `cards_reclassified` (`{progress:true,done,total,moved,kept,trashed,skipped}`) и финальное событие (`{progress:false,reclassified,moved}`); `CardReclassifier.ReclassifyInboxAsync` принимает `IProgress<ReclassifyProgressDto>`; в UI — индикатор `done/total` в шапке «Неразобранного» | этап 12, D | P3 | DONE |
| TD-CARD-MERGE | Полное слияние внутренних DTO карточки в единый `CardDto`. **Решение (2026-09-11): DEFERRED.** Наружный контракт единый; внутренние DTO (read/write/DB/patch) намеренно разделены по слоям, слияние — риск без пользы | этап 9/11 | P3 | DEFERRED |
| TD-PROTO-COMMENTS | **Сделано (2026-09-11):** из комментариев убраны ссылки на процесс/прототип (`Task/Ruling/этап/python L…/main.py/прототип/LEADRADAR_*`), удалены блоки `<remarks>`, `<summary>` сжаты до короткой фразы; `//`-комментарии со ссылками удалены, в `.proto` — тоже. Строк комментариев 27 210 → ~19 100 | запрос владельца 2026-09-11 | P2 | DONE |
| TD-COMMENTS-IFACE | Привести код к правилам код-стайла (`docs/spec/Код-стайл-Дейл.md`). **Сделано (2026-09-11):** (1) `<summary>` только блочно — исправлено 5286 шт. в 833 файлах; (2) комментарии только на public/protected — понижено 2028 XML-доков с private/internal (359 файлов), повторный прогон — ещё 12; (3) дедупликация `<summary>``<inheritdoc/>`: **закрыто — дублей нет** (проверено сканами по тексту и по имени члена: 39 интерфейсов, 229 членов, случаев `<param>`+дубль не существует); (4) явная реализация интерфейсов — **остаётся точечным ревью владельца** (54 интерфейса с doc, 43 с реализациями, массовая правка не автоматизируется). Попутно: добавлены 4 недостающих `<summary>` членам интерфейсов, переведены 3 англоязычных комментария. Скрипты: `scripts/fix_summary_blocks.py`, `scripts/fix_private_docs.py`, `scripts/dedup_summary_inheritdoc.py`. Детали — `docs/spec/Код-стайл-аудит-2026-09-11.md` | запрос владельца 2026-09-11 | P2 | TECHDEBT (13 — DONE; 4 — ревью владельца) |
| TD-COMMENTS-IFACE | Привести код к правилам код-стайла (`docs/spec/Код-стайл-Дейл.md`). **Сделано (2026-09-11):** (1) `<summary>` только блочно — 5286 шт.; (2) приватные XML-доки понижены — 2028+12; (3) дедупликация `<summary>``<inheritdoc/>` — дублей нет (сканы); (4) **явные реализации интерфейсов — сделано (2026-09-11, вечер, вариант A)**: 161 член в 30 прод-файлах конвертирован codemod'ом `scripts/make_explicit.py`, потребители перетипизированы на интерфейсы (8 мест в проде, 17 тест-файлов), Card/ICard-семейство оставлено implicit как DTO; попутно маркерные классы заменены маркерными интерфейсами. Детали — `docs/spec/Код-стайл-аудит-2026-09-11.md` | запрос владельца 2026-09-11 | P2 | DONE |
| TD-TESTS-NSUBSTITUTE | Миграция тестовых фейков на NSubstitute (решение владельца 2026-09-11: моки — через NSubstitute, новых фейк-классов не заводить). **Сделано (2026-09-11):** NSubstitute 6.1.0 подключён к 5 тест-проектам; эталон миграции — `FakePasswordHasher` → хелпер `TestHashers.New()` (NSubstitute, детерминированная семантика сохранена), фейк удалён. **Осталось (по размеру):** FakeDiscoveryPacer (1 файл), FakeRatesListener (2), FakeTenantProvisioner (5), FakeSecretCipher (8), FakeAiTools (4), FakeRatesSource (1), FakeGlobalSettingsStore (4), FakeTenantRegistry/FakeTenantRepository (3+7), FakeAiClassifier (5), FakeSettingsStore (42), FakeRateLimitCounterStore (5), FakeAuditLogStore (13), FakeTenantStore (10), FakeMlLearningStore (5), FakeMlClient (17), FakeOperatorAuthStore (14), FakeInviteStore (7), FakeFileStorage (9), FakeTokenUsageEventStore (10), FakeAuthStore (15), Recording*/Harness* (gRPC-харнессы — оставить как хелперы), крупные stateful: FakeTelegramGateway (5), FakeDiscoveryGateway (2), FakeTelegramStore (7), FakeTenantLimitStore (15), FakePipelineStore (12), FakeDiscoveryStore (7), FakeKanjStore (21). Для каждого: заменить подставку на `Substitute.For<>()` + `Returns`, семантику состояния воспроизвести в конфигурации, тесты перетипизировать на интерфейс | решение владельца 2026-09-11 | P2 | BACKLOG |
| TD-STYLE-ANALYZERS | Остаток мягких правил код-стайла. **Закрыто (2026-09-11):** (1) `var` — включён ломающий сборку гейт только для встроенных типов (`csharp_style_var_for_built_in_types = false:warning`), остаток выправлен `dotnet format style --diagnostics IDE0008` по 5 sln; режимы «очевидный/прочий тип» — silent осознанно (~1600 субъективных замен); (2) дедупликация `<summary>` — дублей нет (см. TD-COMMENTS-IFACE); (3) переводы строк — **решено: LF** (`.gitattributes` `* text=auto eol=lf`, `.editorconfig` → lf, 1029 файлов нормализовано, `git add --renormalize`; попутно починены 42 CRLF-.sh — до этого первый прогон удалённого CI падал бы). `this.` и именование приватных полей уже закрыты в `.editorconfig` | аудит 2026-09-11 | P3 | DONE |
## 2. Инфраструктура и эксплуатация