203 lines
6.4 KiB
Dart
203 lines
6.4 KiB
Dart
|
|
// test/edit_transaction_dialog_test.dart
|
||
|
|
|
||
|
|
import 'package:flutter/material.dart';
|
||
|
|
import 'package:flutter_test/flutter_test.dart';
|
||
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
||
|
|
import 'package:cashumit/models/report_transaction.dart';
|
||
|
|
import 'package:cashumit/widgets/edit_transaction_dialog.dart';
|
||
|
|
import 'package:cashumit/widgets/transaction_links_dialog.dart';
|
||
|
|
|
||
|
|
void main() {
|
||
|
|
setUp(() {
|
||
|
|
SharedPreferences.setMockInitialValues({
|
||
|
|
'firefly_url': 'https://firefly.example.com',
|
||
|
|
'firefly_token': 'mock_token',
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
final sampleTx = ReportTransaction(
|
||
|
|
id: 'tx-123',
|
||
|
|
transactionGroupId: 'group-456',
|
||
|
|
date: DateTime(2026, 8, 15, 10, 30),
|
||
|
|
description: 'Beli ATK Kantor',
|
||
|
|
amount: 150000,
|
||
|
|
direction: 'pengeluaran',
|
||
|
|
counterpartyName: 'Toko Buku Maju',
|
||
|
|
tags: ['kantor'],
|
||
|
|
);
|
||
|
|
|
||
|
|
testWidgets('EditTransactionDialog displays transaction info and browser link',
|
||
|
|
(WidgetTester tester) async {
|
||
|
|
await tester.pumpWidget(
|
||
|
|
MaterialApp(
|
||
|
|
home: Scaffold(
|
||
|
|
body: EditTransactionDialog(
|
||
|
|
transaction: sampleTx,
|
||
|
|
fireflyUrl: 'https://firefly.example.com',
|
||
|
|
accessToken: 'token123',
|
||
|
|
availableTags: const ['kantor', 'atk', 'operasional', 'snack'],
|
||
|
|
onSaveLocal: (_) {},
|
||
|
|
),
|
||
|
|
),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
await tester.pumpAndSettle();
|
||
|
|
|
||
|
|
// Verify Title & description
|
||
|
|
expect(find.text('Edit Transaksi'), findsOneWidget);
|
||
|
|
expect(find.text('Beli ATK Kantor'), findsOneWidget);
|
||
|
|
|
||
|
|
// Verify browser link banner and header icon
|
||
|
|
expect(find.text('Buka transaksi di browser Firefly III'), findsOneWidget);
|
||
|
|
expect(find.byIcon(Icons.open_in_browser), findsOneWidget);
|
||
|
|
expect(find.byIcon(Icons.open_in_new), findsOneWidget);
|
||
|
|
|
||
|
|
// Verify current tag is shown in chips
|
||
|
|
expect(find.text('kantor'), findsOneWidget);
|
||
|
|
|
||
|
|
// Verify suggestion tag section shows unselected server tags
|
||
|
|
expect(find.text('Saran Tag dari Server:'), findsOneWidget);
|
||
|
|
expect(find.text('atk'), findsOneWidget);
|
||
|
|
expect(find.text('operasional'), findsOneWidget);
|
||
|
|
expect(find.text('snack'), findsOneWidget);
|
||
|
|
});
|
||
|
|
|
||
|
|
testWidgets('Tapping server suggestion chip adds tag to transaction',
|
||
|
|
(WidgetTester tester) async {
|
||
|
|
ReportTransaction? savedTx;
|
||
|
|
|
||
|
|
await tester.pumpWidget(
|
||
|
|
MaterialApp(
|
||
|
|
home: Scaffold(
|
||
|
|
body: EditTransactionDialog(
|
||
|
|
transaction: sampleTx,
|
||
|
|
fireflyUrl: 'https://firefly.example.com',
|
||
|
|
accessToken: 'token123',
|
||
|
|
availableTags: const ['atk', 'operasional'],
|
||
|
|
onSaveLocal: (tx) {
|
||
|
|
savedTx = tx;
|
||
|
|
},
|
||
|
|
),
|
||
|
|
),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
await tester.pumpAndSettle();
|
||
|
|
|
||
|
|
// Tap on '+ atk' chip
|
||
|
|
final atkChip = find.widgetWithText(ActionChip, 'atk');
|
||
|
|
expect(atkChip, findsOneWidget);
|
||
|
|
await tester.tap(atkChip);
|
||
|
|
await tester.pumpAndSettle();
|
||
|
|
|
||
|
|
// Now 'atk' should be in the assigned tags chips
|
||
|
|
expect(find.widgetWithText(Chip, 'atk'), findsOneWidget);
|
||
|
|
|
||
|
|
// Save and verify onSaveLocal received updated tags
|
||
|
|
final saveButton = find.text('Edit Selesai');
|
||
|
|
await tester.ensureVisible(saveButton);
|
||
|
|
await tester.tap(saveButton);
|
||
|
|
await tester.pumpAndSettle();
|
||
|
|
|
||
|
|
expect(savedTx, isNotNull);
|
||
|
|
expect(savedTx!.tags, contains('kantor'));
|
||
|
|
expect(savedTx!.tags, contains('atk'));
|
||
|
|
});
|
||
|
|
|
||
|
|
testWidgets('Typing in new tag input field and tapping add button adds custom tag',
|
||
|
|
(WidgetTester tester) async {
|
||
|
|
tester.view.physicalSize = const Size(1080, 1920);
|
||
|
|
tester.view.devicePixelRatio = 1.0;
|
||
|
|
addTearDown(tester.view.resetPhysicalSize);
|
||
|
|
|
||
|
|
ReportTransaction? savedTx;
|
||
|
|
|
||
|
|
await tester.pumpWidget(
|
||
|
|
MaterialApp(
|
||
|
|
home: Scaffold(
|
||
|
|
body: EditTransactionDialog(
|
||
|
|
transaction: sampleTx,
|
||
|
|
fireflyUrl: 'https://firefly.example.com',
|
||
|
|
accessToken: 'token123',
|
||
|
|
availableTags: const ['atk'],
|
||
|
|
onSaveLocal: (tx) {
|
||
|
|
savedTx = tx;
|
||
|
|
},
|
||
|
|
),
|
||
|
|
),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
await tester.pumpAndSettle();
|
||
|
|
|
||
|
|
// Enter a new custom tag into the text field
|
||
|
|
final tagField = find.widgetWithText(TextFormField, 'Ketik untuk cari / tambah tag...');
|
||
|
|
expect(tagField, findsOneWidget);
|
||
|
|
await tester.enterText(tagField, 'project-2026');
|
||
|
|
await tester.pumpAndSettle();
|
||
|
|
|
||
|
|
// Tap the add icon button
|
||
|
|
final addButton = find.byIcon(Icons.add).first;
|
||
|
|
await tester.tap(addButton);
|
||
|
|
await tester.pumpAndSettle();
|
||
|
|
|
||
|
|
// Verify 'project-2026' is now in assigned tags
|
||
|
|
expect(find.widgetWithText(Chip, 'project-2026'), findsOneWidget);
|
||
|
|
|
||
|
|
// Click Edit Selesai
|
||
|
|
final saveButton = find.text('Edit Selesai');
|
||
|
|
await tester.ensureVisible(saveButton);
|
||
|
|
await tester.tap(saveButton);
|
||
|
|
await tester.pumpAndSettle();
|
||
|
|
|
||
|
|
expect(savedTx, isNotNull);
|
||
|
|
expect(savedTx!.tags, contains('project-2026'));
|
||
|
|
});
|
||
|
|
|
||
|
|
testWidgets('EditTransactionDialog adapts cleanly to dark theme',
|
||
|
|
(WidgetTester tester) async {
|
||
|
|
await tester.pumpWidget(
|
||
|
|
MaterialApp(
|
||
|
|
theme: ThemeData.dark(),
|
||
|
|
home: Scaffold(
|
||
|
|
body: EditTransactionDialog(
|
||
|
|
transaction: sampleTx,
|
||
|
|
fireflyUrl: 'https://firefly.example.com',
|
||
|
|
accessToken: 'token123',
|
||
|
|
availableTags: const ['kantor', 'atk'],
|
||
|
|
onSaveLocal: (_) {},
|
||
|
|
),
|
||
|
|
),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
await tester.pumpAndSettle();
|
||
|
|
|
||
|
|
expect(find.text('Edit Transaksi'), findsOneWidget);
|
||
|
|
expect(find.text('Beli ATK Kantor'), findsOneWidget);
|
||
|
|
expect(find.text('kantor'), findsOneWidget);
|
||
|
|
});
|
||
|
|
|
||
|
|
testWidgets('TransactionLinksDialog renders links and copy/open actions',
|
||
|
|
(WidgetTester tester) async {
|
||
|
|
await tester.pumpWidget(
|
||
|
|
const MaterialApp(
|
||
|
|
home: Scaffold(
|
||
|
|
body: TransactionLinksDialog(
|
||
|
|
urls: [
|
||
|
|
'https://firefly.example.com/transactions/show/1',
|
||
|
|
'https://firefly.example.com/transactions/show/2',
|
||
|
|
],
|
||
|
|
),
|
||
|
|
),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
await tester.pumpAndSettle();
|
||
|
|
|
||
|
|
expect(find.text('Link Transaksi'), findsOneWidget);
|
||
|
|
expect(
|
||
|
|
find.text('https://firefly.example.com/transactions/show/1'), findsOneWidget);
|
||
|
|
expect(
|
||
|
|
find.text('https://firefly.example.com/transactions/show/2'), findsOneWidget);
|
||
|
|
expect(find.byIcon(Icons.copy), findsNWidgets(2));
|
||
|
|
expect(find.byIcon(Icons.open_in_new), findsNWidgets(2));
|
||
|
|
});
|
||
|
|
}
|