Files
IKAR/test/outbox_persistence_test.dart
T

82 lines
2.4 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:ikar/core/storage/message_persistence.dart';
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
void main() {
sqfliteFfiInit();
late Database db;
final queued = <String, dynamic>{
'id': 'temp',
'account_id': 42,
'chat_id': 7,
'text': 'ciphertext',
'status': 'pending',
'deleted': 0,
};
setUp(() async {
db = await databaseFactoryFfi.openDatabase(inMemoryDatabasePath);
await db.execute(
'CREATE TABLE messages (id TEXT NOT NULL, account_id INTEGER NOT NULL, '
'chat_id INTEGER NOT NULL, text TEXT NOT NULL, status TEXT, deleted INTEGER, '
'PRIMARY KEY (account_id, id))',
);
await db.insert('messages', queued);
});
tearDown(() => db.close());
test('receipt replaces a pending item atomically', () async {
expect(
await MessagePersistence.replacePending(db, {
...queued,
'id': 'ack',
'status': 'sent',
}, pendingId: 'temp'),
isTrue,
);
expect((await db.query('messages')).single['id'], 'ack');
});
for (final mode in [
'removed',
'deleted',
'already sent',
'other account',
'other chat',
]) {
test('late result cannot overwrite $mode item', () async {
if (mode == 'removed') await db.delete('messages');
if (mode == 'deleted') await db.update('messages', {'deleted': 1});
if (mode == 'already sent') {
await db.update('messages', {'status': 'sent'});
}
final before = await db.query('messages');
expect(
await MessagePersistence.replacePending(db, {
...queued,
'status': 'error',
if (mode == 'other account') 'account_id': 84,
if (mode == 'other chat') 'chat_id': 8,
}, pendingId: 'temp'),
isFalse,
);
expect(await db.query('messages'), before);
});
}
test(
'failed delete rolls back receipt and preserves retryable wire text',
() async {
await db.execute(
"CREATE TRIGGER reject_delete BEFORE DELETE ON messages BEGIN SELECT RAISE(ABORT, 'disk error'); END",
);
await expectLater(
MessagePersistence.replacePending(db, {
...queued,
'id': 'ack',
'status': 'sent',
}, pendingId: 'temp'),
throwsA(isA<DatabaseException>()),
);
expect((await db.query('messages')).single, queued);
},
);
}