test(sales): привести oversell-тест к политике «продажа в минус разрешена»
RetailOversellingTests ждал 409 на продажу сверх остатка — устаревшая политика. По решению владельца 08.10 продажа в минус разрешена и создаёт предупреждение об отрицательном остатке. Тест переписан: проведение успешно, остаток уходит в минус, создан negative-stock alert. Плюс обновлён docs/filters-sweep-progress.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
f3a177a121
commit
d7db011331
|
|
@ -96,10 +96,20 @@ _(pageSize=50, время полного HTTP-ответа)_
|
||||||
- [ ] P1–P4, каждый контрол, positive + границы + ошибки ввода + права + mobile 390px.
|
- [ ] P1–P4, каждый контрол, positive + границы + ошибки ввода + права + mobile 390px.
|
||||||
|
|
||||||
## Найденные попутно баги (фикс в этой же сессии)
|
## Найденные попутно баги (фикс в этой же сессии)
|
||||||
- [ ] showcase «Последние продажи» — будущие времена (TZ double-shift) — фикс по корню.
|
- [x] showcase «Последние продажи» — будущие времена. Корень: дата чека бралась от
|
||||||
- [ ] causeUserId=null в уведомлениях о минусах — не пишется автор документа (все типы).
|
клиента без нормализации. `BusinessTime.ToInstantUtc` (Kind→UTC + clamp будущего к now)
|
||||||
- [ ] Ошибки ввода приходят техническим английским (JSON-conversion) — перевести все
|
в рознице и приёме чеков с кассы. Юнит-тесты. Коммит f3a177a.
|
||||||
model-binding/validation ошибки в дружелюбный русский (web toast + mobile API).
|
- [x] causeUserId=null в уведомлениях о минусах. Корень: StockService писал автора
|
||||||
|
только из черновика; теперь fallback на `ITenantContext.UserId` в единой точке
|
||||||
|
ApplyMovementAsync → пишется для ВСЕХ типов документов. Тест. Коммит 9dc8f6e.
|
||||||
|
- [x] Ошибки ввода техническим английским (JSON-conversion) → `ModelErrorTranslator`:
|
||||||
|
«Неверное значение поля «Причина»», без классов/путей/англ.; сырой текст только в лог.
|
||||||
|
Действует на web (toast) и mobile API. Тест. Коммит 4aceda3.
|
||||||
|
- [x] (НЕ баг, устаревший тест) `RetailOversellingTests` ждал 409 на продажу сверх
|
||||||
|
остатка — но по решению владельца 08.10 продажа в минус РАЗРЕШЕНА (создаётся
|
||||||
|
предупреждение). Тест обновлён на актуальную политику (204 + алерт).
|
||||||
|
- [x] (попутно) `food-market.UnitTests` не компилировался (FakeServer не реализовывал
|
||||||
|
новый QuickCreateProductAsync) → все юнит-тесты не запускались. Стаб добавлен. Коммит 1324ffd.
|
||||||
|
|
||||||
## Что НЕ трогаем
|
## Что НЕ трогаем
|
||||||
Прод, shared-postgres, global.json, gateway nginx, sklad.
|
Прод, shared-postgres, global.json, gateway nginx, sklad.
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,11 @@ public class RetailOversellingTests
|
||||||
private static string RandomBarcode()
|
private static string RandomBarcode()
|
||||||
=> string.Concat(Enumerable.Range(0, 13).Select(_ => Random.Shared.Next(0, 10)));
|
=> string.Concat(Enumerable.Range(0, 13).Select(_ => Random.Shared.Next(0, 10)));
|
||||||
|
|
||||||
|
// Решение владельца 08.10.2026: продажа в минус РАЗРЕШЕНА (как у МойСклада по
|
||||||
|
// умолчанию) — вместо блокировки создаётся предупреждение об отрицательном
|
||||||
|
// остатке. Этот тест раньше ждал 409 (старая политика) и был устаревшим.
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Posting_sale_above_available_stock_is_rejected()
|
public async Task Posting_sale_above_available_stock_is_allowed_and_creates_negative_alert()
|
||||||
{
|
{
|
||||||
var api = new ApiActor(_factory.CreateClient());
|
var api = new ApiActor(_factory.CreateClient());
|
||||||
await api.SignupAndLoginAsync($"oversell-{Guid.NewGuid():N}");
|
await api.SignupAndLoginAsync($"oversell-{Guid.NewGuid():N}");
|
||||||
|
|
@ -42,7 +45,13 @@ public async Task Posting_sale_above_available_stock_is_rejected()
|
||||||
var saleId = (await draftResp.Content.ReadFromJsonAsync<JsonElement>()).GetProperty("id").GetString();
|
var saleId = (await draftResp.Content.ReadFromJsonAsync<JsonElement>()).GetProperty("id").GetString();
|
||||||
|
|
||||||
using var post = await api.Http.PostAsJsonAsync($"/api/sales/retail/{saleId}/post", new { });
|
using var post = await api.Http.PostAsJsonAsync($"/api/sales/retail/{saleId}/post", new { });
|
||||||
((int)post.StatusCode).Should().Be(409, "продажа сверх остатка должна блокироваться");
|
post.IsSuccessStatusCode.Should().BeTrue(
|
||||||
|
$"продажа в минус разрешена: {(int)post.StatusCode} {await post.Content.ReadAsStringAsync()}");
|
||||||
|
|
||||||
|
// Остаток ушёл в −5, и создано предупреждение об отрицательном остатке.
|
||||||
|
(await api.StockOfAsync(refs.StoreId, productId)).Should().Be(-5m);
|
||||||
|
var cnt = await api.GetJsonAsync("/api/negative-stock/count");
|
||||||
|
cnt.GetProperty("total").GetInt32().Should().BeGreaterThan(0, "минус создаёт предупреждение");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue