VHS-Karten integriert, Bildzoom ergänzt und Chat-IDs korrigiert

Unterschriftenerfassung dauerhaft auf Deutsch anzeigen, lokale VHS-Buildkonfiguration und Regressionstests ergänzen sowie Version auf 357.0.0+357 anheben.
This commit is contained in:
Sven committed 2026-10-07 10:41:41 +02:00
1 parent c0b667c4ee
commit 5e7babf265
26 files changed
+752 -93

No files matched your search

+86
View File
@@ -0,0 +1,86 @@
import 'package:flat_buffers/flat_buffers.dart' as fb;
import 'package:flutter_test/flutter_test.dart';
import 'package:objectbox/internal.dart' show EntityDefinition;
import 'package:stadtbote/model/chat_message.dart';
import 'package:stadtbote/objectbox.g.dart';
void main() {
group('ChatMessage IDs', () {
test('initialisiert ausgehende Nachrichten vollständig', () {
final message = _outgoingMessage();
expect(message.id, 0);
expect(message.toJson(), {
'id': 42,
'time': 1791366832,
'from': 'courier-123',
'subj': '',
'text': 'Auftrag erledigt',
'read': true,
});
});
test('serialisiert ausgehende Nachrichten für ObjectBox ohne Fehler', () {
final message = _outgoingMessage();
final definition = getObjectBoxModel().bindings[ChatMessage]!
as EntityDefinition<ChatMessage>;
final builder = fb.Builder();
expect(definition.objectToFB(message, builder), 0);
final buffer = fb.BufferContext.fromBytes(builder.buffer);
final root = buffer.derefObject(0);
const intReader = fb.Int64Reader();
const stringReader = fb.StringReader();
expect(intReader.vTableGet(buffer, root, 4, -1), 0);
expect(intReader.vTableGet(buffer, root, 6, -1), 42);
expect(intReader.vTableGet(buffer, root, 8, -1), 1791366832);
expect(stringReader.vTableGet(buffer, root, 10, ''), 'courier-123');
expect(stringReader.vTableGet(buffer, root, 12, 'missing'), '');
expect(stringReader.vTableGet(buffer, root, 14, ''), 'Auftrag erledigt');
expect(const fb.BoolReader().vTableGet(buffer, root, 16, false), isTrue);
});
test('verwendet nach lokaler ID-Vergabe weiterhin die Nachrichten-ID', () {
final message = _outgoingMessage();
final definition = getObjectBoxModel().bindings[ChatMessage]!
as EntityDefinition<ChatMessage>;
definition.setId(message, 99);
expect(message.id, 99);
expect(message.externalId, 42);
expect(message.toJson()['id'], 42);
});
test('übernimmt empfangene Server-IDs getrennt von der lokalen ID', () {
final message = ChatMessage.fromJson({
'id': 21891302,
'time': 1791366832,
'from': 'Zentrale',
'subj': 'Rückfrage',
'text': 'Bitte melden',
});
expect(message.id, 0);
expect(message.externalId, 21891302);
expect(message.read, isFalse);
expect(message.toJson(), {
'id': 21891302,
'time': 1791366832,
'from': 'Zentrale',
'subj': 'Rückfrage',
'text': 'Bitte melden',
'read': false,
});
});
});
}
ChatMessage _outgoingMessage() => ChatMessage.outgoing(
externalId: 42,
time: 1791366832,
from: 'courier-123',
text: 'Auftrag erledigt',
);
+51
View File
@@ -0,0 +1,51 @@
import 'dart:convert';
import 'package:flutter_test/flutter_test.dart';
import 'package:stadtbote/model/job.dart';
void main() {
group('Job map_url', () {
test('erhält die Server-URL einschließlich Query und Fragment', () {
const mapUrl = 'https://vhs.example.invalid/map?job=21891302#courier';
final payload = _jobPayload()..['map_url'] = mapUrl;
final job = Job.fromJson(payload);
final serialized =
jsonDecode(jsonEncode(job.toJson())) as Map<String, dynamic>;
final restored = Job.fromJson(serialized);
expect(job.mapUrl, mapUrl);
expect(serialized['map_url'], mapUrl);
expect(restored.mapUrl, mapUrl);
expect(restored.externalId, 21891302);
});
test('liest ältere Aufträge ohne map_url weiterhin ein', () {
final job = Job.fromJson(_jobPayload());
final restored = Job.fromJson(job.toJson());
expect(job.mapUrl, isNull);
expect(restored.mapUrl, isNull);
expect(restored.externalId, 21891302);
});
test('akzeptiert eine explizit fehlende map_url', () {
final payload = _jobPayload()..['map_url'] = null;
expect(Job.fromJson(payload).mapUrl, isNull);
});
});
}
Map<String, dynamic> _jobPayload() => {
'id': 21891302,
'ver': '0',
'state': 0,
'ordertime': 1791285073,
'offs_warn': 0,
'global': false,
'vht_id': 2,
'rem': '',
'delayOrderTime': 0,
'tours': <Map<String, dynamic>>[],
};