Some checks are pending
Auto-tag / Create date-tag (push) Waiting to run
CI / Backend (.NET 8) (push) Waiting to run
CI / Web (React + Vite) (push) Waiting to run
CI / POS (WPF, Windows) (push) Waiting to run
Docker API / Build + push API (push) Waiting to run
Docker API / Deploy API on stage (push) Blocked by required conditions
Правки владельца 08.10 (п.4 паритета): - Сохранить можно при наличии Наименования. Единица не обязательна в запросе → дефолт «шт»; группа → корень. Штрихкод ОБЯЗАТЕЛЕН у любого товара: нет в запросе/ импорте → автогенерация внутреннего EAN-13 (верная контр. цифра, префикс не пересекается с весовыми/ценовыми префиксами орг. — InternalBarcode). - Цена продажи не обязательна для сохранения; но ПРОДАТЬ без неё нельзя — касса и розничная продажа дают «У товара «X» нет цены продажи» (можно ввести вручную). - Быстрое создание из кассы/приёмки: POST /api/catalog/products/quick (имя + опц. штрихкод/цена/весовой). - Снят FluentValidation NotEqual(Guid.Empty) на единицу (контроллер подставляет дефолт). Тесты: unit InternalBarcode 3/3 (валидный EAN-13, не парсится как весовой, обходит префиксы); integration 3/3 (создание по одному имени, продажа без цены → 400, quick). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
47 lines
1.7 KiB
C#
47 lines
1.7 KiB
C#
using foodmarket.Shared.Barcodes;
|
||
using FluentAssertions;
|
||
using Xunit;
|
||
|
||
namespace foodmarket.UnitTests;
|
||
|
||
public class InternalBarcodeTests
|
||
{
|
||
[Fact]
|
||
public void Generated_is_valid_ean13_with_correct_check_digit()
|
||
{
|
||
for (int i = 0; i < 100; i++)
|
||
{
|
||
var code = InternalBarcode.Generate();
|
||
code.Should().HaveLength(13);
|
||
code.Should().MatchRegex("^[0-9]{13}$");
|
||
var body = code[..12];
|
||
InternalBarcode.Ean13CheckDigit(body).Should().Be(code[12] - '0');
|
||
}
|
||
}
|
||
|
||
[Fact]
|
||
public void Default_prefix_is_02_and_not_parsed_as_weighted()
|
||
{
|
||
var code = InternalBarcode.Generate(WeightedBarcodeSettings.Default);
|
||
code.Should().StartWith("02");
|
||
// Внутренний код НЕ должен распознаваться как весовая/ценовая этикетка.
|
||
WeightedBarcode.Parse(code, WeightedBarcodeSettings.Default).IsWeighted.Should().BeFalse();
|
||
}
|
||
|
||
[Fact]
|
||
public void Prefix_avoids_weight_and_price_prefixes()
|
||
{
|
||
// Орг. заняла и 02 под вес — генератор должен уйти на другой свободный префикс.
|
||
var settings = new WeightedBarcodeSettings
|
||
{
|
||
Enabled = true,
|
||
WeightPrefixes = new[] { 2, 20, 21, 22, 23, 24 },
|
||
PricePrefixes = new[] { 25, 26, 27, 28, 29 },
|
||
};
|
||
var prefix = InternalBarcode.PickPrefix(settings);
|
||
new[] { 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29 }.Should().NotContain(prefix);
|
||
var code = InternalBarcode.Generate(settings);
|
||
WeightedBarcode.Parse(code, settings).IsWeighted.Should().BeFalse();
|
||
}
|
||
}
|