mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
Allow overriding contact name
This commit is contained in:
@@ -4,6 +4,7 @@ import 'package:geolocator/geolocator.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:latlong2/latlong.dart';
|
||||
import 'package:meshcore_sar_app/models/contact.dart';
|
||||
import 'package:meshcore_sar_app/models/contact_group.dart';
|
||||
import 'package:meshcore_sar_app/providers/contacts_provider.dart';
|
||||
import 'package:meshcore_sar_app/services/cayenne_lpp_parser.dart';
|
||||
import 'package:meshcore_sar_app/utils/fast_gps_packet.dart';
|
||||
@@ -427,6 +428,46 @@ void main() {
|
||||
expect(reloaded.advertLocation!.longitude, closeTo(13.9999, 0.0001));
|
||||
},
|
||||
);
|
||||
|
||||
test('prefers a local name override and preserves it across refreshes', () {
|
||||
provider.setContactNameOverride(publicKeyHex(publicKey), 'Rescue One');
|
||||
|
||||
final renamed = provider.findContactByKey(publicKey)!;
|
||||
expect(renamed.nameOverride, 'Rescue One');
|
||||
expect(renamed.displayName, 'Rescue One');
|
||||
|
||||
provider.addOrUpdateContact(
|
||||
Contact(
|
||||
publicKey: publicKey,
|
||||
type: ContactType.chat,
|
||||
flags: 0,
|
||||
outPathLen: 0,
|
||||
outPath: Uint8List(64),
|
||||
advName: 'Updated Advertised Name',
|
||||
lastAdvert: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
advLat: (46.0569 * 1e6).toInt(),
|
||||
advLon: (14.5058 * 1e6).toInt(),
|
||||
lastMod: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
),
|
||||
);
|
||||
|
||||
final refreshed = provider.findContactByKey(publicKey)!;
|
||||
expect(refreshed.nameOverride, 'Rescue One');
|
||||
expect(refreshed.displayName, 'Rescue One');
|
||||
expect(refreshed.advName, 'Updated Advertised Name');
|
||||
});
|
||||
|
||||
test('persists a local name override across reloads', () async {
|
||||
provider.setContactNameOverride(publicKeyHex(publicKey), 'Rescue One');
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
|
||||
final reloadedProvider = ContactsProvider();
|
||||
await reloadedProvider.initializeEarly();
|
||||
|
||||
final reloaded = reloadedProvider.findContactByKey(publicKey)!;
|
||||
expect(reloaded.nameOverride, 'Rescue One');
|
||||
expect(reloaded.displayName, 'Rescue One');
|
||||
});
|
||||
});
|
||||
|
||||
group('ContactsProvider route updates', () {
|
||||
@@ -733,5 +774,45 @@ void main() {
|
||||
expect(restored.savedGroupsForSection('rooms').first.query, 'ops');
|
||||
expect(restored.savedGroupsForSection('rooms').first.label, 'ops');
|
||||
});
|
||||
|
||||
test('replaces persisted auto groups for a section', () async {
|
||||
await provider.replaceAutoGroupsForSection('repeaters', [
|
||||
SavedContactGroup(
|
||||
id: '${ContactsProvider.autoGroupIdPrefix}repeaters_al',
|
||||
sectionKey: 'repeaters',
|
||||
label: 'AL-',
|
||||
query: 'AL-',
|
||||
createdAt: DateTime(2026, 3, 10, 12),
|
||||
matchPrefixes: const ['AL-'],
|
||||
isAutoGroup: true,
|
||||
),
|
||||
SavedContactGroup(
|
||||
id: '${ContactsProvider.autoGroupIdPrefix}repeaters_others',
|
||||
sectionKey: 'repeaters',
|
||||
label: 'Others',
|
||||
query: 'Others',
|
||||
createdAt: DateTime(2026, 3, 10, 12),
|
||||
matchPrefixes: const ['CR-', 'DE-'],
|
||||
isAutoGroup: true,
|
||||
),
|
||||
]);
|
||||
|
||||
final restored = ContactsProvider();
|
||||
await restored.initializeEarly();
|
||||
|
||||
expect(restored.savedGroupsForSection('repeaters'), hasLength(2));
|
||||
expect(
|
||||
restored.savedGroupsForSection('repeaters').first.matchPrefixes,
|
||||
isNotEmpty,
|
||||
);
|
||||
expect(
|
||||
restored.savedGroupsForSection('repeaters').first.isAutoGroup,
|
||||
isTrue,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
String publicKeyHex(Uint8List publicKey) {
|
||||
return publicKey.map((b) => b.toRadixString(16).padLeft(2, '0')).join('');
|
||||
}
|
||||
|
||||
@@ -131,6 +131,108 @@ void main() {
|
||||
expect(snapshot.location.longitude, closeTo(14.5058, 0.000001));
|
||||
});
|
||||
|
||||
test('dedupes repeated incoming contact messages with same text', () {
|
||||
final provider = MessagesProvider();
|
||||
final sender = Uint8List.fromList([0, 1, 2, 3, 4, 5]);
|
||||
|
||||
provider.addMessage(
|
||||
Message(
|
||||
id: 'dup-1',
|
||||
messageType: MessageType.contact,
|
||||
pathLen: 1,
|
||||
textType: MessageTextType.plain,
|
||||
senderTimestamp: 1700001000,
|
||||
text: 'same payload',
|
||||
receivedAt: DateTime.now(),
|
||||
senderPublicKeyPrefix: sender,
|
||||
),
|
||||
);
|
||||
provider.addMessage(
|
||||
Message(
|
||||
id: 'dup-2',
|
||||
messageType: MessageType.contact,
|
||||
pathLen: 1,
|
||||
textType: MessageTextType.plain,
|
||||
senderTimestamp: 1700001999,
|
||||
text: 'same payload',
|
||||
receivedAt: DateTime.now(),
|
||||
senderPublicKeyPrefix: sender,
|
||||
),
|
||||
);
|
||||
|
||||
expect(provider.messages, hasLength(1));
|
||||
expect(provider.messages.single.id, equals('dup-1'));
|
||||
});
|
||||
|
||||
test('keeps separate incoming messages when text differs', () {
|
||||
final provider = MessagesProvider();
|
||||
final sender = Uint8List.fromList([0, 1, 2, 3, 4, 5]);
|
||||
|
||||
provider.addMessage(
|
||||
Message(
|
||||
id: 'unique-1',
|
||||
messageType: MessageType.contact,
|
||||
pathLen: 1,
|
||||
textType: MessageTextType.plain,
|
||||
senderTimestamp: 1700002000,
|
||||
text: 'same payload',
|
||||
receivedAt: DateTime.now(),
|
||||
senderPublicKeyPrefix: sender,
|
||||
),
|
||||
);
|
||||
provider.addMessage(
|
||||
Message(
|
||||
id: 'unique-2',
|
||||
messageType: MessageType.contact,
|
||||
pathLen: 1,
|
||||
textType: MessageTextType.plain,
|
||||
senderTimestamp: 1700002999,
|
||||
text: 'different payload',
|
||||
receivedAt: DateTime.now(),
|
||||
senderPublicKeyPrefix: sender,
|
||||
),
|
||||
);
|
||||
|
||||
expect(provider.messages, hasLength(2));
|
||||
});
|
||||
|
||||
test('removed SAR markers stay hidden after provider restore', () async {
|
||||
final provider = MessagesProvider();
|
||||
final message = Message(
|
||||
id: 'sar-hidden',
|
||||
messageType: MessageType.channel,
|
||||
channelIdx: 0,
|
||||
pathLen: 0,
|
||||
textType: MessageTextType.plain,
|
||||
senderTimestamp: 1700000003,
|
||||
text: 'S:🧑:0:46.0569,14.5058:Hidden marker',
|
||||
receivedAt: DateTime.now(),
|
||||
senderPublicKeyPrefix: Uint8List.fromList([0, 1, 2, 3, 4, 5]),
|
||||
);
|
||||
|
||||
provider.addMessage(message);
|
||||
expect(
|
||||
provider.sarMarkers.map((marker) => marker.id),
|
||||
contains(message.id),
|
||||
);
|
||||
|
||||
await provider.removeSarMarker(message.id);
|
||||
expect(provider.sarMarkers, isEmpty);
|
||||
|
||||
final restoredProvider = MessagesProvider();
|
||||
await restoredProvider.initialize();
|
||||
|
||||
expect(
|
||||
restoredProvider.messages.map((stored) => stored.id),
|
||||
contains(message.id),
|
||||
);
|
||||
expect(
|
||||
restoredProvider.sarMarkers.map((marker) => marker.id),
|
||||
isNot(contains(message.id)),
|
||||
);
|
||||
expect(restoredProvider.removedSarMarkerIds, contains(message.id));
|
||||
});
|
||||
|
||||
test('tracks and persists media transfer counts and downloaders', () async {
|
||||
final provider = MessagesProvider();
|
||||
final voiceEnvelope = VoiceEnvelope(
|
||||
|
||||
Reference in New Issue
Block a user