Files
votianlt/app/test/views/completed_station_test.dart
T
Sven 5e6044e4b1 fix: Stationsabschluss absichern und Kundenformulare anpassen
Sperrt nachträgliche Aufgabenabschlüsse in App und Backend und zeigt erledigte Aufträge trotz offener optionaler Aufgaben grün an. Ergänzt Regressionstests, die Anredeauswahl und optionale Steuerangaben für Kunden. Enthält App-Version 0.9.25, Backend-Version 0.9.26 und das aktualisierte Frontend-Bundle.
2026-10-06 15:09:51 +02:00

146 lines
4.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:votianlt_app/app_theme.dart';
import 'package:votianlt_app/cargo_items_view.dart';
import 'package:votianlt_app/jobs_view.dart';
import 'package:votianlt_app/models/job.dart';
import 'package:votianlt_app/models/job_progress.dart';
import 'package:votianlt_app/task_view.dart';
Job jobWithOptionalTask({
bool closedStation = true,
String status = 'IN_PROGRESS',
}) => Job.fromJson({
'id': 'job-1',
'jobNumber': 'TEST-1',
'status': status,
'completedStationOrders': closedStation ? [0] : [],
'deliveryStations': [
{
'stationOrder': 0,
'tasks': [
{
'id': 'optional',
'jobId': 'job-1',
'optional': true,
'completed': false,
'description': 'Optionale Bestätigung',
'taskOrder': 0,
'taskSpecificData': {
'taskType': 'CONFIRMATION',
'buttonText': 'Jetzt bestätigen',
},
},
],
},
{'stationOrder': 1, 'tasks': []},
],
});
void main() {
for (final status in ['IN_PROGRESS', 'COMPLETED']) {
testWidgets(
'optional task cannot open a dialog after station closure ($status)',
(tester) async {
final job = jobWithOptionalTask(status: status);
await tester.pumpWidget(
MaterialApp(home: TaskView(job: job, stationOrder: 0)),
);
await tester.pump();
final task = find.text('Optionale Bestätigung');
expect(task, findsOneWidget);
final tile = tester.widget<InkWell>(
find.ancestor(of: task, matching: find.byType(InkWell)).first,
);
expect(tile.onTap, isNull);
await tester.tap(task);
await tester.pump();
expect(find.byType(AlertDialog), findsNothing);
expect(find.text('Station abgeschlossen'), findsOneWidget);
await tester.pumpWidget(const SizedBox.shrink());
},
);
}
testWidgets('optional task remains executable at an open station', (
tester,
) async {
await tester.pumpWidget(
MaterialApp(
home: TaskView(
job: jobWithOptionalTask(closedStation: false),
stationOrder: 0,
),
),
);
await tester.pump();
await tester.tap(find.text('Optionale Bestätigung'));
await tester.pump();
expect(find.byType(AlertDialog), findsOneWidget);
expect(find.text('Jetzt bestätigen'), findsOneWidget);
await tester.pumpWidget(const SizedBox.shrink());
});
testWidgets(
'an already open dialog cannot complete a task after the job closes',
(tester) async {
Widget view(Job job) => MaterialApp(
home: TaskView(
key: const ValueKey('task-view'),
job: job,
stationOrder: 0,
),
);
await tester.pumpWidget(view(jobWithOptionalTask(closedStation: false)));
await tester.pump();
await tester.tap(find.text('Optionale Bestätigung'));
await tester.pump();
expect(find.byType(AlertDialog), findsOneWidget);
await tester.pumpWidget(view(jobWithOptionalTask(status: 'COMPLETED')));
await tester.pump();
await tester.tap(find.text('Jetzt bestätigen'));
await tester.pumpAndSettle();
expect(find.byType(AlertDialog), findsNothing);
final taskCard = tester.widget<Card>(
find
.ancestor(
of: find.text('Optionale Bestätigung'),
matching: find.byType(Card),
)
.first,
);
expect(
taskCard.elevation,
0,
); // still open and locked, never marked completed
expect(find.text('Station abgeschlossen'), findsOneWidget);
await tester.pumpWidget(const SizedBox.shrink());
},
);
test('completed job card is green with optional tasks still open', () {
final job = jobWithOptionalTask(status: 'COMPLETED');
expect(jobCardBackgroundColor(JobProgress(job)), AppColors.successSoft);
expect(job.tasks.single.completed, isFalse);
});
test('offline final station completion makes the job card green', () {
final job = jobWithOptionalTask();
expect(
jobCardBackgroundColor(JobProgress(job, localCompletedStations: {1})),
AppColors.successSoft,
);
expect(jobCardBackgroundColor(JobProgress(job)), AppColors.warningSoft);
expect(
deliveryStationCardBackgroundColor(
job.deliveryStations.first,
{},
isClosed: true,
),
AppColors.successSoft,
);
});
}