Files
ingtrakapp/test/pb_sync_merge_test.dart
T
2026-09-10 11:40:28 +02:00

137 lines
3.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:myapp/models/bank.dart';
import 'package:myapp/models/transaction_meta.dart';
import 'package:myapp/services/pb_sync_service.dart';
import 'package:myapp/services/storage_service.dart';
void main() {
test('mergeTxMetaStores unions labels and metas without dropping either side',
() {
final local = TxMetaStoreData(
byId: {
'tx1': const TxMeta(labelIds: ['groceries'], notes: 'local note'),
'tx2': const TxMeta(recurring: true),
},
labelsByMerchant: {
'albert heijn': ['groceries'],
},
customLabels: const [
TxLabel(
id: 'custom_ah',
name: 'AH',
color: Color(0xFF0F766E),
custom: true,
),
],
labelParents: const {'custom_ah': 'groceries'},
);
final remote = TxMetaStoreData(
byId: {
'tx1': const TxMeta(labelIds: ['dining'], notes: ''),
'tx3': const TxMeta(notes: 'remote only'),
},
labelsByMerchant: {
'albert heijn': ['shopping'],
'jumbo': ['groceries'],
},
notesByMerchant: const {'jumbo': 'weekly'},
customLabels: const [
TxLabel(
id: 'custom_fuel',
name: 'Fuel',
color: Color(0xFFEA580C),
custom: true,
),
],
);
final merged = mergeTxMetaStores(local, remote);
expect(merged.byId['tx1']!.labelIds, containsAll(['groceries', 'dining']));
expect(merged.byId['tx1']!.notes, 'local note');
expect(merged.byId['tx2']!.recurring, isTrue);
expect(merged.byId['tx3']!.notes, 'remote only');
expect(merged.labelsByMerchant['albert heijn'],
containsAll(['groceries', 'shopping']));
expect(merged.labelsByMerchant['jumbo'], ['groceries']);
expect(merged.notesByMerchant['jumbo'], 'weekly');
expect(merged.customLabels.map((l) => l.id),
containsAll(['custom_ah', 'custom_fuel']));
expect(merged.labelParents['custom_ah'], 'groceries');
});
test('mergeBankTransactionLists unions without dropping either side', () {
const localOnly = BankTransaction(
date: '2024-01-02',
description: 'Local Cafe',
amount: -4.5,
currency: 'EUR',
pending: false,
);
const shared = BankTransaction(
date: '2024-01-01',
description: 'Shared Shop',
amount: -12.0,
currency: 'EUR',
pending: false,
);
const remoteOnly = BankTransaction(
date: '2024-01-03',
description: 'Remote Market',
amount: -9.25,
currency: 'EUR',
pending: true,
);
final merged = mergeBankTransactionLists(
[localOnly, shared],
[shared, remoteOnly],
);
expect(merged.length, 3);
expect(merged.map((t) => t.id), containsAll([
localOnly.id,
shared.id,
remoteOnly.id,
]));
expect(merged.first.date, '2024-01-03');
});
test('bank API merge keeps cloud-only txs outside the API window', () {
const cloudOnly = BankTransaction(
date: '2020-06-01',
description: 'Old cloud tx',
amount: -20,
currency: 'EUR',
pending: false,
);
const recentShared = BankTransaction(
date: '2026-09-01',
description: 'Recent Shop',
amount: -5,
currency: 'EUR',
pending: false,
);
const apiOnly = BankTransaction(
date: '2026-09-02',
description: 'New API tx',
amount: -3,
currency: 'EUR',
pending: false,
);
// Same order as BankController._loadLinkedData: API first, then existing.
final afterRefresh = mergeBankTransactionLists(
[recentShared, apiOnly],
[cloudOnly, recentShared],
);
expect(afterRefresh.length, 3);
expect(
afterRefresh.map((t) => t.description),
containsAll(['Old cloud tx', 'Recent Shop', 'New API tx']),
);
});
}