import 'dart:convert'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:cashumit/models/receipt_item.dart'; import 'package:cashumit/widgets/invoice_image_widget.dart'; void main() { final tinyPng = base64Decode( 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==', ); InvoiceData buildData({ String disclaimer = '', String thankYouText = '', String pantunText = '', double tipAmount = 0.0, double? total, Uint8List? qrisBytes, }) { return InvoiceData( invoiceNumber: 'INV24-1', storeName: 'TOKO SEMBAKO MURAH', storeAddress: 'Jl. Merdeka No. 123', adminName: 'Budi Santoso', adminPhone: '08123456789', customerName: 'NISFIA', date: DateTime(2026, 10, 7, 14, 30), items: [ ReceiptItem( description: 'AKRILIK PUTIH SUSU 3MM', quantity: 2, price: 22000, ), ], total: total ?? (44000 + tipAmount), tipAmount: tipAmount, qrisBytes: qrisBytes, disclaimer: disclaimer, thankYouText: thankYouText, pantunText: pantunText, ); } Future pumpInvoice(WidgetTester tester, InvoiceData data) async { await tester.pumpWidget( MaterialApp( home: Scaffold( body: SingleChildScrollView( child: InvoiceImageWidget(data: data), ), ), ), ); } testWidgets('header menampilkan info toko', (tester) async { await pumpInvoice(tester, buildData()); expect(find.text('INVOICE'), findsOneWidget); expect(find.text('TOKO SEMBAKO MURAH'), findsNWidgets(2)); expect(find.text('Jl. Merdeka No. 123'), findsOneWidget); expect(find.text('Telp: 08123456789'), findsOneWidget); expect(find.text('Admin: Budi Santoso'), findsOneWidget); }); testWidgets('footer menampilkan disclaimer, terima kasih, dan pantun', (tester) async { await pumpInvoice( tester, buildData( disclaimer: 'Barang tidak dapat dikembalikan.', thankYouText: '*** TERIMA KASIH ***', pantunText: 'Baris satu,\\nBaris dua,\nBaris tiga', ), ); expect(find.text('*** TERIMA KASIH ***'), findsOneWidget); expect(find.text('Baris satu,'), findsOneWidget); expect(find.text('Baris dua,'), findsOneWidget); expect(find.text('Baris tiga'), findsOneWidget); expect(find.text('Barang tidak dapat dikembalikan.'), findsOneWidget); }); testWidgets('footer tidak menampilkan teks opsional yang kosong', (tester) async { await pumpInvoice(tester, buildData()); expect(find.text('*** TERIMA KASIH ***'), findsNothing); expect(find.text('Barang tidak dapat dikembalikan.'), findsNothing); expect(find.text('Baris satu,'), findsNothing); }); testWidgets('tip dijumlahkan ke total dan jumlah yang harus dibayar', (tester) async { final data = buildData(tipAmount: 10000); await pumpInvoice(tester, data); expect(find.text('Tip'), findsOneWidget); expect(find.text('Rp 10.000'), findsOneWidget); expect(find.text('Rp 54.000'), findsNWidgets(2)); }); testWidgets('tip tidak ditampilkan bila nominalnya nol', (tester) async { await pumpInvoice(tester, buildData()); expect(find.text('Tip'), findsNothing); }); testWidgets('gambar QRIS menggantikan instruksi pembayaran', (tester) async { await pumpInvoice(tester, buildData(qrisBytes: tinyPng)); expect(find.text('Pembayaran via QRIS'), findsOneWidget); expect(find.text('Instruksi Pembayaran'), findsNothing); expect(find.byType(Image), findsWidgets); }); testWidgets('QRIS tidak tampil bila belum diatur', (tester) async { await pumpInvoice(tester, buildData()); expect(find.text('Pembayaran via QRIS'), findsNothing); expect(find.text('Instruksi Pembayaran'), findsNothing); }); }