food-market/tests/food-market.UnitTests/InternalBarcodeTests.cs
nns 0ca0d6cc3b
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
feat(catalog): карточка товара как МойСклад+ — обязательно только наименование
Правки владельца 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>
2026-10-09 05:45:38 +05:00

47 lines
1.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}
}