Files
IKAR/test/phonebook_contact_sync_test.dart
T

144 lines
3.8 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:ikar/backend/modules/contacts.dart';
import 'package:ikar/core/contacts/phonebook_contact_sync.dart';
void main() {
const existing = CachedContact(
id: 2,
accountId: 1,
firstName: 'Existing',
phone: 79000000002,
updateTime: 0,
);
var current = true;
late List<String> lookups;
late List<String> additions;
late Map<String, int> accounts;
setUp(() {
current = true;
lookups = [];
additions = [];
accounts = {'+79000000003': 3};
});
Future<int> sync(
Map<String, String> book, {
int accountId = 1,
List<CachedContact> contacts = const [existing],
Future<PhoneLookupResult?> Function(String)? lookup,
Future<AddContactResult> Function(String, String)? add,
}) => PhonebookContactSync.importContacts(
phonebook: book,
contacts: contacts,
accountId: accountId,
lookup:
lookup ??
(phone) async {
lookups.add(phone);
final id = accounts[phone];
return id == null ? null : PhoneLookupResult(id: id);
},
add:
add ??
(phone, name) async {
additions.add('$phone:$name');
return const AddContactResult(AddContactStatus.added);
},
isCurrent: () => current,
requestDelay: Duration.zero,
);
test(
'adds registered numbers once, skips existing and absent accounts',
() async {
expect(
await sync({
'+79000000002': 'Do not rename',
'8 (900) 000-00-03': 'New',
'+79000000003': 'Duplicate',
'+79000000004': 'No ИКАР',
'123': 'Invalid',
}),
1,
);
expect(lookups, ['+79000000003', '+79000000004']);
expect(additions, ['+79000000003:New']);
},
);
test('skips own account and existing contacts with hidden numbers', () async {
accounts = {'+79000000003': 2, '+79000000004': 1};
expect(await sync({'+79000000003': 'Hidden', '+79000000004': 'Self'}), 0);
expect(additions, isEmpty);
});
test(
'a later pass discovers new phone entries and newly registered users',
() async {
expect(await sync({'+79000000004': 'Later'}), 0);
accounts['+79000000004'] = 4;
expect(await sync({'+79000000003': 'New', '+79000000004': 'Later'}), 2);
},
);
test(
'account switch during lookup prevents adding to another account',
() async {
expect(
await sync(
{'+79000000003': 'New'},
lookup: (_) async {
current = false;
return const PhoneLookupResult(id: 3);
},
),
0,
);
expect(additions, isEmpty);
},
);
test('lookup failure stops the pass and can be retried', () async {
await expectLater(
sync(
{'+79000000003': 'New'},
lookup: (_) async {
throw StateError('offline');
},
),
throwsStateError,
);
expect(additions, isEmpty);
expect(await sync({'+79000000003': 'New'}), 1);
});
test('add failure stops further requests and remains retryable', () async {
await expectLater(
sync({
'+79000000003': 'New',
'+79000000004': 'Next',
}, add: (_, _) async => const AddContactResult(AddContactStatus.error)),
throwsStateError,
);
expect(lookups, ['+79000000003']);
expect(await sync({'+79000000003': 'New'}), 1);
});
test('registration disappearing before add is not counted', () async {
expect(
await sync(
{'+79000000003': 'New'},
add: (_, _) async => const AddContactResult(AddContactStatus.notFound),
),
0,
);
});
test('empty phonebook sends no requests', () async {
expect(await sync({}), 0);
expect(lookups, isEmpty);
expect(additions, isEmpty);
});
}