106 lines
2.7 KiB
Dart
106 lines
2.7 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:new_budget/src/features/notification_parsing/data/parser/confidence_scorer.dart';
|
|
import 'package:new_budget/src/features/notification_parsing/data/parser/decision_gate.dart';
|
|
import 'package:new_budget/src/features/notification_parsing/domain/entities/parse_rule.dart';
|
|
import 'package:new_budget/src/features/notification_parsing/domain/enums.dart';
|
|
|
|
ParseRule _rule() => ParseRule(
|
|
id: 'r1',
|
|
userId: 'u1',
|
|
kind: ParseRuleKind.merchantToCategory,
|
|
matchMode: MatchMode.contains,
|
|
pattern: 'PYATEROCHKA',
|
|
categoryId: 'c1',
|
|
createdAt: DateTime(2026, 1, 1),
|
|
);
|
|
|
|
const _strongScores = FieldScores(
|
|
amount: 100,
|
|
account: 100,
|
|
type: 100,
|
|
merchant: 100,
|
|
category: 100,
|
|
);
|
|
|
|
void main() {
|
|
group('decide', () {
|
|
test('rule + sanity + scores ≥ strictness → autoApply', () {
|
|
final d = decide(
|
|
merchantRule: _rule(),
|
|
sanityPassed: true,
|
|
scores: _strongScores,
|
|
strictness: 85,
|
|
amountMinor: 124000,
|
|
hasAccount: true,
|
|
);
|
|
expect(d, GateDecision.autoApply);
|
|
});
|
|
|
|
test('no rule → inbox', () {
|
|
final d = decide(
|
|
merchantRule: null,
|
|
sanityPassed: true,
|
|
scores: _strongScores,
|
|
strictness: 85,
|
|
amountMinor: 124000,
|
|
hasAccount: true,
|
|
);
|
|
expect(d, GateDecision.inbox);
|
|
});
|
|
|
|
test('scores below strictness → inbox', () {
|
|
final d = decide(
|
|
merchantRule: _rule(),
|
|
sanityPassed: true,
|
|
scores: const FieldScores(
|
|
amount: 100,
|
|
account: 45,
|
|
type: 100,
|
|
merchant: 100,
|
|
category: 100,
|
|
),
|
|
strictness: 85,
|
|
amountMinor: 124000,
|
|
hasAccount: true,
|
|
);
|
|
expect(d, GateDecision.inbox);
|
|
});
|
|
|
|
test('no account → inbox even with rule', () {
|
|
final d = decide(
|
|
merchantRule: _rule(),
|
|
sanityPassed: true,
|
|
scores: _strongScores,
|
|
strictness: 85,
|
|
amountMinor: 124000,
|
|
hasAccount: false,
|
|
);
|
|
expect(d, GateDecision.inbox);
|
|
});
|
|
|
|
test('huge amount → inbox even with rule', () {
|
|
final d = decide(
|
|
merchantRule: _rule(),
|
|
sanityPassed: true,
|
|
scores: _strongScores,
|
|
strictness: 85,
|
|
amountMinor: 100001 * 100,
|
|
hasAccount: true,
|
|
);
|
|
expect(d, GateDecision.inbox);
|
|
});
|
|
|
|
test('sanity failed → inbox', () {
|
|
final d = decide(
|
|
merchantRule: _rule(),
|
|
sanityPassed: false,
|
|
scores: _strongScores,
|
|
strictness: 85,
|
|
amountMinor: 124000,
|
|
hasAccount: true,
|
|
);
|
|
expect(d, GateDecision.inbox);
|
|
});
|
|
});
|
|
}
|