Files
OnBudget/test/features/notification_parsing/parser/regex_parser_test.dart
T
2026-05-30 00:18:06 +03:00

101 lines
3.3 KiB
Dart
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.
import 'package:flutter_test/flutter_test.dart';
import 'package:new_budget/src/core/database/converters/enum_converters.dart';
import 'package:new_budget/src/features/notification_parsing/data/parser/regex_parser.dart';
import 'package:new_budget/src/features/notification_parsing/domain/entities/raw_message.dart';
import 'package:new_budget/src/features/notification_parsing/domain/enums.dart';
RawMessage _msg(String body, {String pkg = 'ru.sberbankmobile'}) {
final now = DateTime(2026, 5, 29, 14, 5);
return RawMessage(
id: 'm1',
userId: 'u1',
packageName: pkg,
body: body,
receivedAt: now,
dedupHash: 'h',
status: RawMessageStatus.pending,
createdAt: now,
);
}
void main() {
const parser = RegexParser();
group('parseAmountMinor', () {
test('plain integer → minor units', () {
expect(parseAmountMinor('1240'), 124000);
});
test('RU thousands separator + decimal comma', () {
expect(parseAmountMinor('1 240,50'), 124050);
});
test('dot decimal', () {
expect(parseAmountMinor('99.90'), 9990);
});
test('trailing dot in 3-digit group is NOT a decimal', () {
// «1.240» — точка как разделитель тысяч (3 цифры после) → 124000.
expect(parseAmountMinor('1.240'), 124000);
});
test('empty / garbage → null', () {
expect(parseAmountMinor(''), isNull);
expect(parseAmountMinor(' '), isNull);
});
});
group('RegexParser.parse', () {
test('purchase amount→card→merchant (Сбер-подобный)', () {
final d = parser.parse(
_msg('Покупка 1240р Карта *3456 PYATEROCHKA 14:05 Баланс: 5000р'),
);
expect(d, isNotNull);
expect(d!.type, TransactionType.expense);
expect(d.amount, 124000);
expect(d.cardLast4, '3456');
expect(d.merchantRaw, 'PYATEROCHKA');
expect(d.source, ParseSource.regex);
expect(d.kind, TxKind.purchase);
});
test('purchase card→amount→merchant (Тинькофф-подобный)', () {
final d = parser.parse(
_msg('Покупка. Карта *3456. 1 240 ₽. Пятёрочка. Доступно 5 000 ₽'),
);
expect(d, isNotNull);
expect(d!.type, TransactionType.expense);
expect(d.amount, 124000);
expect(d.cardLast4, '3456');
expect(d.merchantRaw, 'Пятёрочка');
});
test('income (зачисление)', () {
final d = parser.parse(_msg('Зачисление 5000 ₽ Карта *3456 Зарплата'));
expect(d, isNotNull);
expect(d!.type, TransactionType.income);
expect(d.amount, 500000);
expect(d.cardLast4, '3456');
});
test('SBP transfer by phone', () {
final d = parser.parse(_msg('Перевод 1000 ₽ на +79991234567 успешно'));
expect(d, isNotNull);
expect(d!.amount, 100000);
expect(d.counterpartyPhone, '+79991234567');
});
test('refund → income', () {
final d = parser.parse(_msg('Возврат 1240 ₽ Карта *3456'));
expect(d, isNotNull);
expect(d!.type, TransactionType.income);
expect(d.amount, 124000);
});
test('non-matching body → null', () {
expect(parser.parse(_msg('Ваш баланс по карте *3456 составляет 5000 ₽')),
isNull);
});
});
}