import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:miler/data/service_profile.dart'; import 'package:miler/views/Dashboard/activity/activity_page.dart'; import 'package:miler/views/Dashboard/activity/delivery_details_page.dart'; import 'package:miler/data/accepted_store.dart'; /// ───────────────────────────────────────────────────────────────────────── /// ACTIVITY AND THE RECORD, ACROSS THE PHONES THIS SHIPS TO /// /// `trip_brief_layout_test` does this for Home and is the reason Home's /// overflows get caught; the history half of the app had no equivalent, so a /// row that fits a 390pt reference device was the only thing anyone checked. /// /// Both screens changed in the same pass — the Activity row lost its footer /// band and gained the reference on its measurements line, and the record's /// Route section now hangs an address on *each* end — and both changes put more /// on a line rather than less. That is exactly the shape of edit that overflows /// a narrow phone, so it is the shape that needs a sweep. /// /// One assertion only: **nothing throws.** A `RenderFlex` overflow is an /// exception in a test binding, and this is the cheapest honest way to ask /// "does it fit?" across a matrix without pinning pixel values that legitimate /// design changes would have to churn. /// ───────────────────────────────────────────────────────────────────────── void main() { /// The four the brief names. 320 is the narrowest Android still in the /// field; 412 is a Pixel-class device and was in none of the app's existing /// sweeps. const widths = [320.0, 375.0, 390.0, 412.0]; /// 2.0 is the top of Android's font-size slider. const textScales = [1.0, 1.3, 2.0]; final today = DateTime.now(); final at = DateTime(today.year, today.month, today.day, 11, 42); /// A worst case on purpose: a long customer name, a long kitchen name, a /// 21-character booking reference and a cash figure — every field that /// competes for the same line, all at once. Map record(String id) => { 'orderid': id, 'bookingno': id, 'type': 'delivery', 'pickupcustomer': 'Venkataraman Subramanian', 'name': 'Venkataraman Subramanian', 'sourcename': 'DailyGrubs RS Puram Central Kitchen', 'kitchenname': 'DailyGrubs RS Puram Central Kitchen', 'pickupaddress': '4 Cross, RS Puram, Coimbatore 641002', 'dropaddress': '12, SNS Colony, Peelamedu, Coimbatore 641004', 'deliveryaddress': '12, SNS Colony, Peelamedu, Coimbatore 641004', 'orderstatus': 'delivered', 'completedday': '${at.year}-${at.month.toString().padLeft(2, '0')}-' '${at.day.toString().padLeft(2, '0')}', 'completedat': at.toIso8601String(), 'startedat': at.subtract(const Duration(minutes: 87)).toIso8601String(), 'arrivedat': at.subtract(const Duration(minutes: 5)).toIso8601String(), 'kms': '14.6', 'collectionamt': '123456', 'proof': {'collected': 2, 'amountcollected': 123456.0}, }; setUp(() => ServiceProfile.setActive(ServiceProfile.milkMan)); tearDown(() => ServiceProfile.setActive(ServiceProfile.parcel)); Future sized( WidgetTester tester, double width, double scale, Widget child, { double height = 844, }) async { tester.view.physicalSize = Size(width * 3, height * 3); tester.view.devicePixelRatio = 3.0; addTearDown(tester.view.reset); await tester.pumpWidget( ScreenUtilInit( designSize: const Size(390, 844), builder: (_, _) => MaterialApp( home: MediaQuery( data: MediaQueryData(textScaler: TextScaler.linear(scale)), child: child, ), ), ), ); await tester.pumpAndSettle(const Duration(seconds: 2)); } for (final width in widths) { for (final scale in textScales) { testWidgets('the activity list fits ${width.toInt()}pt / ${scale}x', ( tester, ) async { SharedPreferences.setMockInitialValues({'userId': 1, 'userid': 1}); await debugSeedStore( 'completed_bookings', jsonEncode([ record('DM-BK-16DA518D-6381'), record('DM-BK-16DA518D-6382'), ]), ); await sized(tester, width, scale, const ActivityPage()); expect( tester.takeException(), isNull, reason: 'the activity list overflowed at ${width}pt / ${scale}x', ); }); testWidgets('the delivery record fits ${width.toInt()}pt / ${scale}x', ( tester, ) async { SharedPreferences.setMockInitialValues({'userId': 1, 'userid': 1}); // Tall, because the record is several screens and its `ListView` is // lazy — a short viewport never builds the sections being swept. await sized( tester, width, scale, DeliveryDetailsPage(stop: record('DM-BK-16DA518D-6381')), height: 2600, ); expect( tester.takeException(), isNull, reason: 'the delivery record overflowed at ${width}pt / ${scale}x', ); }); } } }