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.
146 lines
4.5 KiB
Dart
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,
|
|
);
|
|
});
|
|
}
|