sync transactions with pocketbase 2

This commit is contained in:
davmar
2026-09-09 22:31:04 +02:00
parent 96627a830e
commit e35a4d6893
12 changed files with 1442 additions and 12 deletions
+1 -1
View File
@@ -41,7 +41,7 @@ void main() {
await auth.init();
bank = BankController(storage: storage);
meta = TxMetaController(storage);
sync = SyncController(auth: auth, meta: meta);
sync = SyncController(auth: auth, meta: meta, bank: bank);
});
tearDown(() {
+1 -1
View File
@@ -33,7 +33,7 @@ void main() {
// seed a couple txs
// ignore: invalid_use_of_visible_for_testing_member
meta = TxMetaController(storage);
sync = SyncController(auth: auth, meta: meta);
sync = SyncController(auth: auth, meta: meta, bank: bank);
});
tearDown(() {
+100
View File
@@ -0,0 +1,100 @@
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');
});
}