Files
doormile_milderapp/test/deliveries_shots_test.dart
2026-08-28 15:07:30 +05:30

221 lines
6.6 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@Tags(['shots'])
library;
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_test/flutter_test.dart';
import 'support/golden_fonts.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:miler/data/service_profile.dart';
import 'package:miler/views/Dashboard/home/trip.dart';
import 'package:miler/views/Dashboard/home/trip_progress_rail.dart';
// `card.dart` is a `part of` this library, so [PickupCard] comes through it.
import 'package:miler/views/Dashboard/pickups/pickups.dart';
import 'package:miler/views/helpers/constants/Colorconstants.dart';
import 'package:miler/views/helpers/constants/Font_constant.dart';
/// Visual harness for the Deliveries tab's two public pieces.
///
/// `_MyPickupsState` cannot be pumped — Get, SharedPreferences, Geolocator and
/// a 3s poll — and the queue's three quieter tiers (`_NextCard`, `_LaterRow`,
/// `_SkippedRow`) are private to `card.dart`. What is reachable is exactly the
/// pair the redesign is about: [TripProgressRail], which is the head of the
/// screen, and [PickupCard], which is the one live card under it.
///
/// The rail is shot at four route lengths because the documented gap against it
/// is that "a 21-stop route overflows it" — a claim about layout, which is
/// answerable by looking. Run with `--update-goldens`.
void main() {
setUpAll(() async {
// Same reasoning as `home_shots_test`: a golden rendered without the app's
// own family is a picture of the fallback, and Poppins ships one file per
// weight so each has to be registered under the family by hand.
await loadGoldenFonts();
});
tearDown(() {
Get.reset();
ServiceProfile.setActive(ServiceProfile.parcel);
});
Map<String, dynamic> drop(
String id,
String customer, {
String status = 'picked',
String label = '',
}) => {
'orderid': id,
'tripid': 'T1',
'type': 'delivery',
'pickupcustomer': customer,
'name': customer,
'sourcename': 'DailyGrubs RS Puram Kitchen',
'kitchenid': 'K1',
'kitchenname': 'DailyGrubs RS Puram Kitchen',
'pickupaddress': '4 Cross, RS Puram, Coimbatore 641002',
'dropaddress': '12, SNS Colony, Peelamedu, Coimbatore 641004',
'deliveryaddress': '12, SNS Colony, Peelamedu, Coimbatore 641004',
'orderstatus': status,
'pickupcontactno': '9787698259',
'deliverycontactno': '9787698259',
if (label.isNotEmpty) 'baglabel': label,
'Quantity': 1,
'pickuplat': 11.0168,
'pickuplon': 76.9558,
'droplat': 11.0208,
'droplon': 76.9598,
};
Future<void> frame(
WidgetTester tester,
String name,
Widget child, {
double height = 400,
double width = 390,
}) async {
ServiceProfile.setActive(ServiceProfile.milkMan);
SharedPreferences.setMockInitialValues({'userid': 1});
tester.view.physicalSize = Size(width * 3, height * 3);
tester.view.devicePixelRatio = 3.0;
addTearDown(tester.view.reset);
await tester.pumpWidget(
ScreenUtilInit(
// Design size == surface, so `.w`/`.h` are both exactly 1 and the shot
// does not lie about spacing. See the note in `home_shots_test`.
designSize: Size(width, height),
builder: (_, _) => MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: ColorConstants.daylightSurface,
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: child,
),
),
),
),
),
);
await tester.pumpAndSettle();
await expectLater(
find.byType(MaterialApp),
matchesGoldenFile('shots/deliveries_$name.png'),
);
}
/// A route of [total] stops with [done] delivered and the rider standing at
/// the next one — the shape the rail is actually asked to draw mid-round.
List<StopProgress> route(int total, {int done = 0}) => [
for (var i = 0; i < total; i++)
if (i < done)
StopProgress.done
else if (i == done)
StopProgress.current
else
StopProgress.pending,
];
group('the route rail', () {
testWidgets('a short round lays out across the full width', (tester) async {
await frame(
tester,
'rail_short',
TripProgressRail(
progress: route(5, done: 2),
slotLabel: 'Trip 1 · 10:00 AM – 1:00 PM',
remaining: const Duration(minutes: 74),
),
height: 150,
);
});
testWidgets('the documented 21-stop round', (tester) async {
await frame(
tester,
'rail_21',
TripProgressRail(
progress: route(21, done: 6),
slotLabel: 'Trip 1 · 10:00 AM – 1:00 PM',
remaining: const Duration(minutes: 110),
),
height: 150,
);
});
testWidgets('nothing delivered yet — the whole load still aboard', (
tester,
) async {
await frame(
tester,
'rail_21_fresh',
TripProgressRail(
progress: route(21),
slotLabel: 'Trip 1 · 10:00 AM – 1:00 PM',
remaining: const Duration(minutes: 130),
),
height: 150,
);
});
testWidgets('a 320pt phone at 1.3x text scale', (tester) async {
await frame(
tester,
'rail_21_small',
MediaQuery(
data: const MediaQueryData(textScaler: TextScaler.linear(1.3)),
child: TripProgressRail(
progress: route(21, done: 6),
slotLabel: 'Trip 1 · 10:00 AM – 1:00 PM',
remaining: const Duration(minutes: 110),
),
),
height: 170,
width: 320,
);
});
});
group('the live card', () {
testWidgets('picked, waiting to be taken out', (tester) async {
await frame(
tester,
'card_picked',
PickupCard(
item: drop('D1', 'Joe Mathew', label: 'DG-8'),
displayStep: 7,
distanceMeters: 1100,
label: 'DG-8',
collectedIds: const {'D1'},
),
height: 320,
);
});
testWidgets('active — the rider has set off', (tester) async {
await frame(
tester,
'card_active',
PickupCard(
item: drop('D1', 'Joe Mathew', label: 'DG-8'),
displayStep: 7,
distanceMeters: 1100,
label: 'DG-8',
collectedIds: const {'D1'},
outForDeliveryIds: const {'D1'},
),
height: 320,
);
});
});
}