166 lines
4.8 KiB
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);
|
|
},
|
|
);
|
|
}
|