- Leer-Ansichten (Auswählen, Sortieren, Beladen, Ausliefern) nennen den gewählten Tag statt immer „heute": „Für den 02.09.2026 ist keine Tour zugewiesen." (TourDayText). - TourBloc: Loads/Refreshes laufen nebenläufig; bei schnellem Datumswechsel konnte die langsamere Antwort des vorigen Tages die Tour des gewählten Tages überschreiben. Jetzt schreibt nur die jüngste Anfrage ihr Ergebnis. - Kalender reicht 90 statt 14 Tage zurück (z. B. nachimportierte Touren vom Monatsanfang). - Test: neuer Fahrer startet auf „heute", auch wenn der vorige einen anderen Tag gewählt hatte. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
99 lines
3.3 KiB
Dart
99 lines
3.3 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'package:hl_lieferservice/data/cache/attachment_cache.dart';
|
|
import 'package:hl_lieferservice/domain/entity/tour.dart';
|
|
import 'package:hl_lieferservice/domain/entity/tour_details.dart';
|
|
import 'package:hl_lieferservice/domain/repository/tour_repository.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/bloc/tour_bloc.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/bloc/tour_event.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/bloc/tour_state.dart';
|
|
import 'package:hl_lieferservice/feature/delivery/model/tour_day_text.dart';
|
|
import 'package:hl_lieferservice/widget/operations/bloc/operation_bloc.dart';
|
|
|
|
/// Antwortet pro angefragtem Datum erst, wenn der Test es freigibt.
|
|
class _SlowTours implements TourRepository {
|
|
final pending = <DateTime?, Completer<TourDetails?>>{};
|
|
|
|
@override
|
|
Future<TourDetails?> getMyTourDetails({DateTime? date}) =>
|
|
(pending[date] = Completer<TourDetails?>()).future;
|
|
|
|
@override
|
|
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
|
}
|
|
|
|
class _NoCache implements AttachmentCache {
|
|
@override
|
|
Future<void> retainOnly(Set<String> ids) async {}
|
|
|
|
@override
|
|
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
|
}
|
|
|
|
TourDetails _tourAm(DateTime date) => TourDetails(
|
|
tour: Tour(id: 't-$date', accountId: 414, date: date, syncedAt: date),
|
|
deliveries: const [],
|
|
customers: const {},
|
|
contacts: const {},
|
|
articles: const {},
|
|
warehouses: const {},
|
|
notesByDeliveryId: const {},
|
|
creditsByDeliveryId: const {},
|
|
paymentsByDeliveryId: const {},
|
|
services: const [],
|
|
serviceValuesByDeliveryId: const {},
|
|
contactSourcesByDeliveryId: const {},
|
|
contactChannelsBySourceId: const {},
|
|
);
|
|
|
|
void main() {
|
|
group('TourDayText', () {
|
|
final now = DateTime(2026, 9, 25, 16, 30);
|
|
|
|
test('ohne Auswahl und am selben Tag: heute', () {
|
|
expect(TourDayText.of(null, now: now).afterFor, 'heute');
|
|
expect(TourDayText.of(DateTime(2026, 9, 25), now: now).when, 'heute');
|
|
});
|
|
|
|
test('morgen und gestern', () {
|
|
expect(TourDayText.of(DateTime(2026, 9, 26), now: now).when, 'morgen');
|
|
expect(TourDayText.of(DateTime(2026, 9, 24), now: now).when, 'gestern');
|
|
});
|
|
|
|
test('anderer Tag mit Datum und passender Präposition', () {
|
|
final t = TourDayText.of(DateTime(2026, 9, 2), now: now);
|
|
expect(t.afterFor, 'den 02.09.2026');
|
|
expect(t.when, 'am 02.09.2026');
|
|
});
|
|
});
|
|
|
|
test('langsame Antwort eines älteren Tages überschreibt nicht die neue Wahl',
|
|
() async {
|
|
final repo = _SlowTours();
|
|
final bloc = TourBloc(
|
|
tourRepository: repo,
|
|
opBloc: OperationBloc(),
|
|
attachmentCache: _NoCache(),
|
|
);
|
|
final erster = DateTime(2026, 9, 2);
|
|
final zweiter = DateTime(2026, 9, 25);
|
|
|
|
bloc.add(LoadTour.forDate(erster));
|
|
await Future<void>.delayed(Duration.zero);
|
|
bloc.add(LoadTour.forDate(zweiter));
|
|
await Future<void>.delayed(Duration.zero);
|
|
|
|
// Neuere Anfrage antwortet zuerst, die ältere danach.
|
|
repo.pending[zweiter]!.complete(_tourAm(zweiter));
|
|
await Future<void>.delayed(Duration.zero);
|
|
repo.pending[erster]!.complete(_tourAm(erster));
|
|
await Future<void>.delayed(Duration.zero);
|
|
|
|
final state = bloc.state as TourLoaded;
|
|
expect(state.details.tour.date, zweiter);
|
|
await bloc.close();
|
|
});
|
|
}
|