Files
IKAR/test/add_contact_phone_test.dart

166 lines
4.8 KiB
Dart

import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:ikar/backend/api.dart';
import 'package:ikar/backend/modules/contacts.dart';
import 'package:ikar/core/config/countries.dart';
import 'package:ikar/core/protocol/opcode_map.dart';
import 'package:ikar/core/protocol/packet.dart';
import 'package:ikar/frontend/screens/auth/phone_input_formatter.dart';
class _ContactApi extends Api {
_ContactApi(this.error);
final PacketError error;
Map<dynamic, dynamic>? sent;
@override
Future<Packet> sendRequest(
int opcode,
Map<dynamic, dynamic> payload, {
void Function()? beforeSend,
bool silent = false,
}) async {
beforeSend?.call();
expect(opcode, Opcode.contactAddByPhone);
sent = payload;
throw error;
}
}
String formattedDigits(String raw, {String country = 'RU'}) {
final input = FilteringTextInputFormatter.digitsOnly.formatEditUpdate(
TextEditingValue.empty,
TextEditingValue(text: raw),
);
return PhoneInputFormatter(countriesByCode[country]!)
.formatEditUpdate(TextEditingValue.empty, input)
.text
.replaceAll(RegExp(r'\D'), '');
}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
for (final phone in [
'+7 (900) 000-00-01',
'79000000001',
'8 900 000 00 01',
'9000000001',
]) {
test('contact paste preserves subscriber digits: $phone', () async {
final digits = formattedDigits(phone);
expect(digits, '9000000001');
final api = _ContactApi(
const PacketError('missing', errorKey: 'user.not.found'),
);
addTearDown(api.dispose);
final result = await ContactsModule.addContactByPhone(
api,
phone: '+7$digits',
firstName: 'Test',
);
expect(api.sent?['phone'], '+79000000001');
expect(result.status, AddContactStatus.notFound);
});
}
test('international paste removes selected calling code', () {
expect(formattedDigits('+44 7700 900123', country: 'GB'), '7700900123');
});
for (final entry in {
'8 (900) 000-00-01': '+79000000001',
'9000000001': '+9000000001',
'+44 7700 900123': '+447700900123',
}.entries) {
test('backend normalizes contact phone ${entry.key}', () async {
final api = _ContactApi(
const PacketError('missing', errorKey: 'user.not.found'),
);
addTearDown(api.dispose);
final result = await ContactsModule.addContactByPhone(
api,
phone: entry.key,
firstName: 'Test',
);
expect(api.sent?['phone'], entry.value);
expect(result.status, AddContactStatus.notFound);
});
}
for (final phone in ['12345', '1234567890123456']) {
test(
'invalid contact phone is rejected before requesting $phone',
() async {
final api = _ContactApi(
const PacketError('missing', errorKey: 'user.not.found'),
);
addTearDown(api.dispose);
final result = await ContactsModule.addContactByPhone(
api,
phone: phone,
firstName: 'Test',
);
expect(api.sent, isNull);
expect(result.status, AddContactStatus.error);
},
);
}
test('replacing a selected formatted number preserves its final digit', () {
final formatter = PhoneInputFormatter(countriesByCode['RU']!);
final formatted = formatter.formatEditUpdate(
TextEditingValue.empty,
const TextEditingValue(text: '9000000001'),
);
final old = formatted.copyWith(
selection: TextSelection(
baseOffset: 0,
extentOffset: formatted.text.length,
),
);
final filtered = FilteringTextInputFormatter.digitsOnly.formatEditUpdate(
old,
const TextEditingValue(text: '+7 (900) 000-00-02'),
);
expect(
formatter
.formatEditUpdate(old, filtered)
.text
.replaceAll(RegExp(r'\D'), ''),
'9000000002',
);
});
test('oversized invalid paste is rejected without truncation', () {
expect(formattedDigits('123456789012345'), isEmpty);
});
test('typing an extra digit does not reinterpret the completed number', () {
final formatter = PhoneInputFormatter(countriesByCode['RU']!);
final old = formatter.formatEditUpdate(
TextEditingValue.empty,
const TextEditingValue(text: '7900000001'),
);
expect(
formatter.formatEditUpdate(old, old.copyWith(text: '${old.text}2')),
old,
);
});
test(
'unrelated not found error is not reported as absent ИКАР user',
() async {
final api = _ContactApi(
const PacketError('endpoint not found', errorKey: 'method.not.found'),
);
addTearDown(api.dispose);
final result = await ContactsModule.addContactByPhone(
api,
phone: '+79000000001',
firstName: 'Test',
);
expect(result.status, AddContactStatus.error);
},
);
}