fix(#284): summarise GIF notifications via GifHelper, not a duplicate regex

Notifications summarised a GIF as "Sent a GIF" using their own hand-rolled
`^g:[A-Za-z0-9_-]+$` regex rather than GifHelper. #282 changed the payload to
`https://giphy.com/gifs/<id>`, which that regex does not match, so GIF
notifications regressed to dumping the raw URL into the tray.

Detection now goes through `GifHelper.parseGif`, matching how the adjacent
reaction case already delegates to ReactionHelper. That restores the summary
and covers every form the app can send, including replies (`@[Name] ` +
payload), which the old regex never matched even for legacy `g:<id>`.

Verified no other hand-rolled `^g:`/`^m:`/`^s:`/`^r:` payload regexes remain
outside their owning helpers, so this class of drift is closed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull/328/head
Strycher 3 days ago
parent d6d5dbf846
commit f6681b47aa

@ -4,6 +4,7 @@ import 'dart:ui';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import '../helpers/gif_helper.dart';
import '../helpers/reaction_helper.dart'; import '../helpers/reaction_helper.dart';
import '../l10n/app_localizations.dart'; import '../l10n/app_localizations.dart';
import '../utils/platform_info.dart'; import '../utils/platform_info.dart';
@ -154,7 +155,7 @@ class NotificationService {
if (reaction != null) { if (reaction != null) {
return 'Reacted ${reaction.emoji}'; return 'Reacted ${reaction.emoji}';
} }
if (RegExp(r'^g:[A-Za-z0-9_-]+$').hasMatch(trimmed)) { if (GifHelper.parseGif(trimmed) != null) {
return 'Sent a GIF'; return 'Sent a GIF';
} }
return text; return text;

@ -0,0 +1,67 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:meshcore_open/helpers/gif_helper.dart';
import 'package:meshcore_open/services/notification_service.dart';
// #284: notifications summarised a GIF as "Sent a GIF" using their own
// hand-rolled `^g:<id>$` regex. #282 changed the payload to a Giphy URL, which
// that regex does not match, so notifications regressed to dumping the raw URL.
// Detection must go through GifHelper.parseGif so every payload form the app
// can actually send is summarised, and so the regex cannot drift again.
void main() {
const gifId = 'zaMiq1BvCdAVIiu3Mb';
group('GIF payloads are summarised, not dumped raw', () {
test('the current URL payload summarises', () {
expect(
NotificationService.formatNotificationText(GifHelper.encodeGif(gifId)),
'Sent a GIF',
);
});
test('a reply carrying a GIF summarises', () {
expect(
NotificationService.formatNotificationText(
'@[Some Node] ${GifHelper.encodeGif(gifId)}',
),
'Sent a GIF',
);
});
test('a legacy g:<id> payload still summarises', () {
expect(
NotificationService.formatNotificationText('g:$gifId'),
'Sent a GIF',
);
});
test('a legacy g:<id> reply still summarises', () {
expect(
NotificationService.formatNotificationText('@[Some Node] g:$gifId'),
'Sent a GIF',
);
});
});
group('everything else is untouched', () {
test('a reaction still summarises', () {
expect(
NotificationService.formatNotificationText('r:abcd:00'),
startsWith('Reacted '),
);
});
test('ordinary text passes through unchanged', () {
expect(
NotificationService.formatNotificationText('hey are you there'),
'hey are you there',
);
});
test('a non-GIF URL is not mistaken for a GIF', () {
expect(
NotificationService.formatNotificationText('https://example.com/page'),
'https://example.com/page',
);
});
});
}
Loading…
Cancel
Save

Powered by TurnKey Linux.