production
This commit is contained in:
161
test/arrived_stays_on_home_test.dart
Normal file
161
test/arrived_stays_on_home_test.dart
Normal file
@@ -0,0 +1,161 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:miler/data/service_profile.dart';
|
||||
import 'package:miler/views/Dashboard/home/trip.dart';
|
||||
import 'package:miler/views/Dashboard/home/trip_card.dart';
|
||||
|
||||
/// ─────────────────────────────────────────────────────────────────────────
|
||||
/// A STOP HE IS STANDING AT MUST NOT LEAVE THE SCREEN
|
||||
///
|
||||
/// Reported from a live run: the rider marked **Arrived**, the console updated
|
||||
/// correctly — and the stop vanished off Home. Deliveries did not have it
|
||||
/// either, and could not: arrival is a *pre-pickup* rung, and the delivery tab
|
||||
/// only takes work once it is collected. The stop existed in neither place.
|
||||
///
|
||||
/// ── What caused it ──
|
||||
///
|
||||
/// Nothing on the backend. [StopState.arrived] and [StopState.active] used to
|
||||
/// be one value, and `TripCard._showsOnHome` — like a dozen other sites — asked
|
||||
/// `state == StopState.active` to mean *is he at the counter*. Splitting the
|
||||
/// two apart so the row could say **Arrived** instead of **Active** left every
|
||||
/// one of those comparisons answering `false` for the new rung.
|
||||
///
|
||||
/// The visibility filter was the one the rider could see. The others were just
|
||||
/// as broken and quieter: the selection bar offered *Accept* for a stop he was
|
||||
/// already at, the card stopped building its **Mark as picked** button, and the
|
||||
/// group he was working no longer opened by default.
|
||||
///
|
||||
/// These pin the rung end to end — the predicate that now answers the question
|
||||
/// once ([StopStateX.isAtSource]), and the screen behaviour that regressed.
|
||||
/// ─────────────────────────────────────────────────────────────────────────
|
||||
void main() {
|
||||
tearDown(() => ServiceProfile.setActive(ServiceProfile.parcel));
|
||||
|
||||
Map<String, dynamic> meal(String id, String who, {String? status}) => {
|
||||
'orderid': id,
|
||||
'type': 'delivery',
|
||||
'step': int.parse(id),
|
||||
'pickupcustomer': who,
|
||||
'kitchenid': 'K1',
|
||||
'kitchenname': 'Vidhya Kitchen',
|
||||
'sourcename': 'Vidhya Kitchen',
|
||||
'pickupcontactno': '9787698259',
|
||||
'pickupaddress': '4 Cross, RS Puram, Coimbatore',
|
||||
'dropaddress': '12 SNS Colony, Peelamedu, Coimbatore 641004',
|
||||
'Quantity': '1',
|
||||
if (status != null) 'orderstatus': status,
|
||||
};
|
||||
|
||||
Future<void> pumpHome(
|
||||
WidgetTester tester,
|
||||
List<Map<String, dynamic>> stops,
|
||||
) async {
|
||||
ServiceProfile.setActive(ServiceProfile.milkMan);
|
||||
tester.view.physicalSize = const Size(390 * 3, 2600 * 3);
|
||||
tester.view.devicePixelRatio = 3.0;
|
||||
addTearDown(tester.view.reset);
|
||||
|
||||
await tester.pumpWidget(
|
||||
ScreenUtilInit(
|
||||
designSize: const Size(390, 844),
|
||||
builder: (_, _) => MaterialApp(
|
||||
home: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: TripCard(
|
||||
trip: Trip.fromStops(id: 'run', stops: stops),
|
||||
acceptedIds: const {},
|
||||
selectedIds: const {},
|
||||
onToggleSelect: (_) {},
|
||||
onSelectAll: (_) {},
|
||||
onStopTap: (_) {},
|
||||
onCallStop: (_) {},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
// Not `pumpAndSettle`: an arrived row is a **live** row, and [LiveMark]
|
||||
// pulses for as long as it is on screen — settling waits for an animation
|
||||
// that is never going to stop. Two pumps lay the frame out and let the
|
||||
// pulse start, which is all these assertions need.
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
}
|
||||
|
||||
group('1 · the predicate that answers it once', () {
|
||||
test('arrived and active both mean "he is at the source"', () {
|
||||
expect(StopState.arrived.isAtSource, isTrue);
|
||||
expect(StopState.active.isAtSource, isTrue);
|
||||
});
|
||||
|
||||
test('and nothing else does', () {
|
||||
for (final other in const [
|
||||
StopState.pending,
|
||||
StopState.accepted,
|
||||
StopState.collected,
|
||||
StopState.done,
|
||||
StopState.skipped,
|
||||
StopState.rejected,
|
||||
]) {
|
||||
expect(
|
||||
other.isAtSource,
|
||||
isFalse,
|
||||
reason: '$other must not read as standing at the counter',
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test('an arrived stop is committed work, not an open offer', () {
|
||||
// It rode in on `active` and was dropped by the same split. A rider who
|
||||
// has reported an arrival has plainly committed to the stop.
|
||||
expect(StopState.arrived.isCommitted, isTrue);
|
||||
expect(StopState.pending.isCommitted, isFalse);
|
||||
});
|
||||
});
|
||||
|
||||
group('2 · the screen behaviour that regressed', () {
|
||||
testWidgets('an arrived stop stays on Home', (tester) async {
|
||||
await pumpHome(tester, [
|
||||
meal('1', 'Joe Mathew', status: 'arrived'),
|
||||
meal('2', 'Arun Prakash'),
|
||||
]);
|
||||
|
||||
expect(
|
||||
find.text('Joe Mathew'),
|
||||
findsOneWidget,
|
||||
reason:
|
||||
'the rider is standing at this counter — it cannot leave Home, '
|
||||
'and Deliveries will not take it until it is collected',
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('it is still there beside an untouched stop', (tester) async {
|
||||
// Guards the opposite overcorrection: making arrived visible must not
|
||||
// have cost the ordinary rows their place in the run.
|
||||
await pumpHome(tester, [
|
||||
meal('1', 'Joe Mathew', status: 'arrived'),
|
||||
meal('2', 'Arun Prakash'),
|
||||
]);
|
||||
|
||||
expect(find.text('Joe Mathew'), findsOneWidget);
|
||||
expect(find.text('Arun Prakash'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('a collected stop still leaves — that one is not a bug', (
|
||||
tester,
|
||||
) async {
|
||||
// The filter's real job, asserted so a fix for the disappearance cannot
|
||||
// quietly turn into "nothing ever leaves Home".
|
||||
await pumpHome(tester, [
|
||||
meal('1', 'Joe Mathew', status: 'picked'),
|
||||
meal('2', 'Arun Prakash'),
|
||||
]);
|
||||
|
||||
expect(find.text('Joe Mathew'), findsNothing);
|
||||
expect(find.text('Arun Prakash'), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user