From 92d3009eb444a320f4394357c01b9367e8c61ca7 Mon Sep 17 00:00:00 2001 From: Serge Tarkovski Date: Sat, 25 Apr 2026 01:32:43 +0300 Subject: [PATCH] Fix swapped url/desc args in GPX export and add ContactLocalization unit tests --- lib/utils/gpx_export.dart | 6 +- test/l10n/contact_localization_test.dart | 105 +++++++++++++++++++++++ 2 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 test/l10n/contact_localization_test.dart diff --git a/lib/utils/gpx_export.dart b/lib/utils/gpx_export.dart index 1b82a72d..e3a42898 100644 --- a/lib/utils/gpx_export.dart +++ b/lib/utils/gpx_export.dart @@ -72,8 +72,8 @@ class GpxExport { contact.name, contact.latitude!, contact.longitude!, - "Type: ${contact.typeLabelRaw}\nPublic Key: ${contact.publicKeyHex}", url, + "Type: ${contact.typeLabelRaw}\nPublic Key: ${contact.publicKeyHex}", ); } } @@ -91,8 +91,8 @@ class GpxExport { contact.name, contact.latitude!, contact.longitude!, - "Type: ${contact.typeLabelRaw}\nPublic Key: ${contact.publicKeyHex}", url, + "Type: ${contact.typeLabelRaw}\nPublic Key: ${contact.publicKeyHex}", ); } } @@ -110,8 +110,8 @@ class GpxExport { contact.name, contact.latitude ?? 0.0, contact.longitude ?? 0.0, - "Type: ${contact.typeLabelRaw}\nPublic Key: ${contact.publicKeyHex}", url, + "Type: ${contact.typeLabelRaw}\nPublic Key: ${contact.publicKeyHex}", ); } } diff --git a/test/l10n/contact_localization_test.dart b/test/l10n/contact_localization_test.dart new file mode 100644 index 00000000..87df23a7 --- /dev/null +++ b/test/l10n/contact_localization_test.dart @@ -0,0 +1,105 @@ +import 'dart:typed_data'; + +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:meshcore_open/connector/meshcore_protocol.dart'; +import 'package:meshcore_open/l10n/app_localizations.dart'; +import 'package:meshcore_open/l10n/contact_localization.dart'; +import 'package:meshcore_open/models/contact.dart'; + +Contact _contact({ + int type = advTypeChat, + int pathLength = 0, + int? pathOverride, +}) { + return Contact( + publicKey: Uint8List.fromList(List.generate(32, (i) => i + 1)), + name: 'Node', + type: type, + pathLength: pathLength, + path: Uint8List(0), + pathOverride: pathOverride, + lastSeen: DateTime.fromMillisecondsSinceEpoch(0), + ); +} + +void main() { + late AppLocalizations l10n; + + setUpAll(() async { + l10n = await AppLocalizations.delegate.load(const Locale('en')); + }); + + group('Contact.typeLabel', () { + test('chat', () { + expect(_contact(type: advTypeChat).typeLabel(l10n), 'Chat'); + }); + + test('repeater', () { + expect( + _contact(type: advTypeRepeater).typeLabel(l10n), + 'Repeater', + ); + }); + + test('room', () { + expect(_contact(type: advTypeRoom).typeLabel(l10n), 'Room'); + }); + + test('sensor', () { + expect(_contact(type: advTypeSensor).typeLabel(l10n), 'Sensor'); + }); + + test('unknown type falls back', () { + expect(_contact(type: 99).typeLabel(l10n), 'Unknown'); + }); + }); + + group('Contact.pathLabel (override)', () { + test('override < 0 -> flood (forced)', () { + expect( + _contact(pathOverride: -1).pathLabel(l10n), + 'Flood (forced)', + ); + }); + + test('override == 0 -> direct (forced)', () { + expect( + _contact(pathOverride: 0).pathLabel(l10n), + 'Direct (forced)', + ); + }); + + test('override > 0 -> hops (forced)', () { + expect( + _contact(pathOverride: 3).pathLabel(l10n), + '3 hops (forced)', + ); + }); + + test('override takes precedence over pathLength', () { + expect( + _contact(pathLength: 5, pathOverride: -1).pathLabel(l10n), + 'Flood (forced)', + ); + }); + }); + + group('Contact.pathLabel (auto)', () { + test('pathLength < 0 -> flood', () { + expect(_contact(pathLength: -1).pathLabel(l10n), 'Flood'); + }); + + test('pathLength == 0 -> direct', () { + expect(_contact(pathLength: 0).pathLabel(l10n), 'Direct'); + }); + + test('pathLength == 1 -> singular hop', () { + expect(_contact(pathLength: 1).pathLabel(l10n), '1 hop'); + }); + + test('pathLength > 1 -> plural hops', () { + expect(_contact(pathLength: 4).pathLabel(l10n), '4 hops'); + }); + }); +}