import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:ikar/backend/modules/messages.dart'; import 'package:ikar/core/config/app_phonebook_names.dart'; import 'package:ikar/core/contacts/device_contacts_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; const phone = 79000000007; const channel = MethodChannel('github.com/QuisApp/flutter_contacts'); List> book(String name) => [ Contact(id: '7', displayName: name, phones: [Phone('+79000000007')]).toJson(), ]; void main() { TestWidgetsFlutterBinding.ensureInitialized(); late Future>> Function() read; setUp(() { SharedPreferences.setMockInitialValues({}); ContactCache.resetMemoryForTesting(); DeviceContactsService.resetMemoryForTesting(); AppPhonebookNames.current.value = true; read = () async => book('Имя из контактов'); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, (call) { expect(call.method, 'select'); return read(); }); ContactCache.putPhone(7, phone); ContactCache.put(7, 'Серверное имя'); }); tearDown(() { TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger .setMockMethodCallHandler(channel, null); ContactCache.resetMemoryForTesting(); DeviceContactsService.resetMemoryForTesting(); }); testWidgets('chat name stays local throughout a delayed phonebook refresh', ( tester, ) async { expect(await DeviceContactsService.readBookForTesting(), isTrue); final pending = Completer>>(); read = () => pending.future; final refresh = DeviceContactsService.readBookForTesting(); await tester.pump(); // A server response and widget rebuild arrive while the native reader waits. ContactCache.put(7, 'Обновлённое серверное имя'); await tester.pumpWidget(MaterialApp(home: Text(ContactCache.get(7)!))); expect(find.text('Имя из контактов'), findsOneWidget); expect(DeviceContactsService.isLoaded, isTrue); expect(DeviceContactsService.phonebook['+79000000007'], 'Имя из контактов'); await tester.pump(const Duration(seconds: 1)); expect(ContactCache.get(7), 'Имя из контактов'); pending.complete(book('Имя из контактов')); await refresh; await tester.pumpWidget(MaterialApp(home: Text(ContactCache.get(7)!))); expect(find.text('Имя из контактов'), findsOneWidget); expect(find.text('Обновлённое серверное имя'), findsNothing); await tester.pump(const Duration(seconds: 3)); expect(ContactCache.get(7), 'Имя из контактов'); }); test('a failed refresh keeps the last successfully loaded names', () async { await DeviceContactsService.readBookForTesting(); read = () async => throw PlatformException(code: 'READ_FAILED'); expect(await DeviceContactsService.readBookForTesting(), isFalse); expect(ContactCache.get(7), 'Имя из контактов'); expect(DeviceContactsService.isLoaded, isTrue); expect(DeviceContactsService.knownNumbers, 1); }); test('a successful refresh applies renamed and deleted contacts', () async { await DeviceContactsService.readBookForTesting(); read = () async => book('Новое имя'); expect(await DeviceContactsService.readBookForTesting(), isTrue); expect(ContactCache.get(7), 'Новое имя'); read = () async => []; expect(await DeviceContactsService.readBookForTesting(), isTrue); expect(DeviceContactsService.knownNumbers, 0); expect(DeviceContactsService.phonebook, isEmpty); expect(ContactCache.get(7), 'Серверное имя'); }); }