import 'package:flutter_test/flutter_test.dart'; import 'package:sysfarma_mobile/src/features/yape_inbox/domain/payment_notification_parser.dart'; /// Casos basados en textos REALES de notificaciones (investigacion 2026-08-20: /// repos lector-de-yape/CheckPay/Yapex, con tests propios en produccion). void main() { const yape = PaymentNotificationParser.yapePackage; const interbank = 'pe.com.interbank.mobilebanking'; CapturedPayment? parse(String pkg, String? title, String? text) => PaymentNotificationParser.parse( packageName: pkg, title: title, text: text, postedAtMillis: 1787270400000, // 2026-08-21 ); group('Yape recibido', () { test('formato real con codigo antifraude 2025', () { final p = parse(yape, 'Confirmación de Pago', 'Pamela Valencia te envió S/ 100. Código: 593'); expect(p, isNotNull); expect(p!.provider, 'YAPE'); expect(p.amount, 100.0); expect(p.senderName, 'Pamela Valencia'); }); test('monto simple sin decimales', () { final p = parse(yape, null, 'Ana te envió S/ 5'); expect(p!.amount, 5.0); expect(p.senderName, 'Ana'); }); test('monto con miles y decimales', () { final p = parse(yape, null, 'Marco te envió S/ 1,000.50'); expect(p!.amount, 1000.50); }); test('monto con decimales', () { final p = parse(yape, null, 'Luis te envió S/ 12.50'); expect(p!.amount, 12.50); }); test('formato actual enmascarado de Yape conserva el remitente', () { final p = parse( yape, 'Confirmación de Pago', 'Melisa Car* te envió un pago por S/ 1. El cód. de seguridad es: 578', ); expect(p, isNotNull); expect(p!.senderName, 'Melisa Car*'); expect(p.amount, 1.0); }); test('formato observado en Samsung', () { final p = parse( yape, 'Yape!', 'Jean Claude Vega Salazar te envi\u00f3 un pago por S/ 1', ); expect(p, isNotNull); expect(p!.provider, 'YAPE'); expect(p.amount, 1.0); expect(p.senderName, 'Jean Claude Vega Salazar'); }); test('variante "¡Recibiste un yapeo!"', () { final p = parse(yape, '¡Te Yapearon!', '¡Recibiste un yapeo de S/ 20!'); expect(p, isNotNull); expect(p!.amount, 20.0); }); }); group('exclusiones', () { test('yapeo ENVIADO no cuenta', () { expect(parse(yape, null, 'Yapeaste S/ 8 a Luis'), isNull); }); test('promocion/cashback no cuenta', () { expect(parse(yape, 'Promoción', '¡Gana cashback! Recibiste un premio'), isNull); }); test('otra app cualquiera no cuenta', () { expect(parse('com.whatsapp', null, 'Juan te envió S/ 50'), isNull); }); test('notificacion de Yape sin monto (summary) no cuenta', () { expect(parse(yape, 'Yape', 'Tienes 3 notificaciones'), isNull); }); }); group('Plin via app de banco', () { test('Interbank "Te plinearon"', () { final p = parse(interbank, 'Interbank', 'Te plinearon S/ 15 de Carlos Diaz.'); expect(p, isNotNull); expect(p!.provider, 'PLIN'); expect(p.amount, 15.0); expect(p.senderName, 'Carlos Diaz'); }); test('notif del banco que NO es plin se ignora', () { expect( parse( interbank, 'Interbank', 'Recibiste una transferencia de S/ 500'), isNull); }); }); group('idempotencia', () { test('mismo evento produce el mismo dedup_hash (repost de Android)', () { final a = parse(yape, 'Confirmación de Pago', 'Ana te envió S/ 5'); final b = parse(yape, 'Confirmación de Pago', 'Ana te envió S/ 5'); expect(a!.dedupHash, b!.dedupHash); }); test('pagos distintos producen hash distinto', () { final a = parse(yape, null, 'Ana te envió S/ 5'); final b = parse(yape, null, 'Ana te envió S/ 6'); expect(a!.dedupHash, isNot(b!.dedupHash)); }); test('payload API tiene la forma que espera el backend', () { final p = parse(yape, null, 'Ana te envió S/ 5'); final payload = p!.toApiPayload('device-1'); expect(payload['provider'], 'YAPE'); expect(payload['amount'], 5.0); expect(payload['device_id'], 'device-1'); expect(payload['dedup_hash'], isNotEmpty); expect(payload['posted_at'], contains('2026')); }); }); }