diff --git a/lib/content_views/messages_page.dart b/lib/content_views/messages_page.dart index 7dd39ca..4dc5686 100644 --- a/lib/content_views/messages_page.dart +++ b/lib/content_views/messages_page.dart @@ -204,6 +204,7 @@ class _MessagesPageState extends State with ProducerMixin { if (unreadChatMessages.isNotEmpty) { List chatMessageIds = []; for (var message in unreadChatMessages) { + // Der Server erwartet seine Nachrichten-ID, nicht die lokale ObjectBox-ID. chatMessageIds.add(message.externalId.toString()); } diff --git a/lib/content_views/task_list_page.dart b/lib/content_views/task_list_page.dart index 9f1837b..3388ee7 100644 --- a/lib/content_views/task_list_page.dart +++ b/lib/content_views/task_list_page.dart @@ -1287,7 +1287,7 @@ class _HeaderWidgetState extends State<_HeaderWidget> with ProducerMixin { child: const Center( child: Text( textAlign: TextAlign.center, - "Liste der Aufgaben", + "Workflow", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white), ), ), diff --git a/lib/tools/app_localizations.dart b/lib/tools/app_localizations.dart index 52929d3..a376339 100644 --- a/lib/tools/app_localizations.dart +++ b/lib/tools/app_localizations.dart @@ -145,7 +145,7 @@ class AppLocalizations { 'unknown': 'Unbekannt', // Aufgabenliste - 'task_list': 'Liste der Aufgaben', + 'task_list': 'Workflow', 'commission_number_short': 'Komm-#', 'photos_taken': 'Fotos aufgenommen', 'signature_captured': 'Unterschrift erfasst', @@ -287,7 +287,7 @@ class AppLocalizations { 'unknown': 'Unknown', // Task List - 'task_list': 'Task List', + 'task_list': 'Workflow', 'commission_number_short': 'Comm-#', 'photos_taken': 'Photos taken', 'signature_captured': 'Signature captured', @@ -418,7 +418,7 @@ class AppLocalizations { 'unknown': 'Desconocido', // Task List - 'task_list': 'Lista de Tareas', + 'task_list': 'Workflow', 'commission_number_short': 'Núm. Com.', 'photos_taken': 'Fotos tomadas', 'signature_captured': 'Firma capturada', @@ -539,7 +539,7 @@ class AppLocalizations { 'unknown': 'Inconnu', // Task List - 'task_list': 'Liste des Tâches', + 'task_list': 'Workflow', 'commission_number_short': 'N° Comm.', 'photos_taken': 'Photos prises', 'signature_captured': 'Signature capturée', @@ -660,7 +660,7 @@ class AppLocalizations { 'unknown': 'Nieznany', // Task List - 'task_list': 'Lista Zadań', + 'task_list': 'Workflow', 'commission_number_short': 'Nr Zlec.', 'photos_taken': 'Zrobione zdjęcia', 'signature_captured': 'Podpis zapisany', @@ -781,7 +781,7 @@ class AppLocalizations { 'unknown': 'Неизвестно', // Task List - 'task_list': 'Список Задач', + 'task_list': 'Workflow', 'commission_number_short': '№ Комм.', 'photos_taken': 'Фотографии сделаны', 'signature_captured': 'Подпись сохранена', @@ -902,7 +902,7 @@ class AppLocalizations { 'unknown': 'Bilinmiyor', // Task List - 'task_list': 'Görev Listesi', + 'task_list': 'Workflow', 'commission_number_short': 'Kom. No.', 'photos_taken': 'Fotoğraflar çekildi', 'signature_captured': 'İmza kaydedildi', @@ -1023,7 +1023,7 @@ class AppLocalizations { 'unknown': 'Teadmata', // Task List - 'task_list': 'Ülesannete Nimekiri', + 'task_list': 'Workflow', 'commission_number_short': 'Kom. Nr.', 'photos_taken': 'Fotod tehtud', 'signature_captured': 'Allkiri salvestatud', @@ -1144,7 +1144,7 @@ class AppLocalizations { 'unknown': 'Nezināms', // Task List - 'task_list': 'Uzdevumu Saraksts', + 'task_list': 'Workflow', 'commission_number_short': 'Kom. Nr.', 'photos_taken': 'Fotogrāfijas uzņemtas', 'signature_captured': 'Paraksts saglabāts', @@ -1265,7 +1265,7 @@ class AppLocalizations { 'unknown': 'Nežinoma', // Task List - 'task_list': 'Užduočių Sąrašas', + 'task_list': 'Workflow', 'commission_number_short': 'Kom. Nr.', 'photos_taken': 'Nuotraukos padarytos', 'signature_captured': 'Parašas užfiksuotas', diff --git a/test/widget/messages_page_test.dart b/test/widget/messages_page_test.dart new file mode 100644 index 0000000..cd72b6b --- /dev/null +++ b/test/widget/messages_page_test.dart @@ -0,0 +1,130 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:dart_mq/dart_mq.dart'; +import 'package:flat_buffers/flat_buffers.dart' as fb; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:objectbox/internal.dart' show EntityDefinition; +import 'package:stadtbote/content_views/messages_page.dart'; +import 'package:stadtbote/main.dart'; +import 'package:stadtbote/model/chat_message.dart'; +import 'package:stadtbote/model/session_status.dart'; +import 'package:stadtbote/objectbox.g.dart'; +import 'package:stadtbote/tools/constants.dart'; +import 'package:stadtbote/tools/messages/publish_payload_message.dart'; + +void main() { + setUp(() { + MQClient.initialize(); + MQClient.instance.declareQueue(Constants.messageTopicPublishPayload); + }); + + tearDown(() { + MQClient.instance.close(); + }); + + testWidgets('bestätigt die Server-ID auch nach der lokalen ID-Vergabe', ( + tester, + ) async { + final message = ChatMessage.fromJson({ + 'id': 6094830, + 'time': 1791536566, + 'from': 'NL', + 'subj': 'Test1', + 'text': 'Test2', + }); + final store = _MessageStore(); + final definition = + getObjectBoxModel().bindings[ChatMessage]! + as EntityDefinition; + + // Die nativen Datenbankzugriffe werden ersetzt; die generierte + // ObjectBox-Serialisierung und der Nachrichtenversand laufen unverändert. + definition.setId(message, 2); + final builder = fb.Builder(); + definition.objectToFB(message, builder); + final restored = definition.objectFromFB( + store, + ByteData.sublistView(builder.buffer), + ); + expect(restored.id, 2); + expect(restored.externalId, 6094830); + expect(restored.read, isFalse); + + store.messages = _MessageBox(restored); + MyApp.objectBoxStore = store; + + await tester.pumpWidget( + const MaterialApp(home: Scaffold(body: MessagesPage())), + ); + await tester.pumpAndSettle(); + + final published = + MQClient.instance + .getLatestMessage(Constants.messageTopicPublishPayload)! + .payload + as PublishPayloadMessage; + expect(published.topic, 'mssg_received'); + expect(published.acknowledgeRequired, isFalse); + expect(jsonDecode(jsonEncode(published.message)), { + 'ids': ['6094830'], + 'time': isA(), + }); + expect(restored.read, isTrue); + expect(find.text('Test1\nTest2', findRichText: true), findsOneWidget); + }); +} + +class _MessageStore extends Fake implements Store { + late final _MessageBox messages; + + @override + Box box() { + if (T == ChatMessage) return messages as Box; + if (T == SessionStatus) return _SessionBox() as Box; + throw StateError('Unerwarteter Entity-Typ: $T'); + } +} + +class _SessionBox extends Fake implements Box { + @override + List getAll() => []; +} + +class _MessageBox extends Fake implements Box { + final ChatMessage message; + + _MessageBox(this.message); + + @override + List getAll() => [message]; + + @override + QueryBuilder query([Condition? qc]) => + _UnreadQueryBuilder(message); + + @override + int put(ChatMessage object, {PutMode mode = PutMode.put}) => object.id; +} + +class _UnreadQueryBuilder extends Fake implements QueryBuilder { + final ChatMessage message; + + _UnreadQueryBuilder(this.message); + + @override + Query build() => _UnreadQuery(message); +} + +class _UnreadQuery extends Fake implements Query { + final ChatMessage message; + + _UnreadQuery(this.message); + + @override + List find() => [if (!message.read) message]; + + @override + void close() {} +}