Files
doormile_milderapp/test/activity_list_test.dart
2026-08-11 13:16:33 +05:30

200 lines
7.2 KiB
Dart

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/views/Dashboard/activity/activity_page.dart';
import 'package:miler/views/Dashboard/home/homepage.dart';
import 'package:miler/views/Dashboard/profile/Profilepage.dart';
import 'package:miler/views/helpers/constants/Colorconstants.dart';
/// ── A day's work is a list, not a stack of cards ──
///
/// Every finished stop was a filled, rounded card with 12pt of air under it,
/// and inside each one a *second*, white panel holding the three figures. So the
/// page came down the screen as grey slabs with white slabs punched into them —
/// the card-inside-card shape, repeated once per stop — and on top of that every
/// row opened with a 40pt green disc that was identical on all of them.
///
/// Finished stops are all the same kind of thing, arriving in one order, read by
/// scanning down. That is a list, and a list is separated by rules.
void main() {
String day(DateTime t) =>
'${t.year}-${t.month.toString().padLeft(2, '0')}-'
'${t.day.toString().padLeft(2, '0')}';
Map<String, dynamic> finished(
String id,
String name,
String address, {
required String type,
double cash = 0,
int minsAgo = 30,
}) {
final now = DateTime.now();
final at = now.subtract(Duration(minutes: minsAgo));
return {
'orderid': id,
'type': type,
'pickupcustomer': name,
'pickupaddress': address,
'orderstatus': 'picked',
'completedday': day(now),
'completedat': at.toIso8601String(),
'startedat': at.subtract(const Duration(minutes: 14)).toIso8601String(),
if (cash > 0) 'collectionamt': '$cash',
'proof': {if (cash > 0) 'amountcollected': cash},
};
}
Future<void> pumpActivity(WidgetTester tester) async {
SharedPreferences.setMockInitialValues({
'userId': 1,
'completed_bookings': jsonEncode([
finished(
'DM240817',
'Sundar Textiles',
'78, Cross Cut Road, Gandhipuram, Coimbatore',
type: 'combined',
cash: 2450,
minsAgo: 22,
),
finished(
'DM240816',
'Green Leaf Grocers',
'29, Kovaipudur Main Road, Coimbatore',
type: 'delivery',
minsAgo: 68,
),
]),
});
tester.view.physicalSize = const Size(390 * 3, 844 * 3);
tester.view.devicePixelRatio = 3.0;
addTearDown(tester.view.reset);
await tester.pumpWidget(
ScreenUtilInit(
designSize: const Size(390, 844),
builder: (_, _) => const MaterialApp(home: ActivityPage()),
),
);
await tester.pumpAndSettle(const Duration(seconds: 2));
}
testWidgets('a finished stop is not a card', (tester) async {
await pumpActivity(tester);
expect(find.text('Sundar Textiles'), findsOneWidget);
// `cardSurface` was the row fill and `pureSurface` the fill of the figure
// panel nested inside it. Neither may come back: on a white page a filled
// row is a box round a list item, and a filled panel inside a filled row is
// the shape this page was rebuilt to remove.
final fills = tester
.widgetList<Container>(find.byType(Container))
.map((c) => c.decoration)
.whereType<BoxDecoration>()
.map((d) => d.color)
.toList();
expect(fills, isNot(contains(ColorConstants.cardSurface)));
});
testWidgets('the figures line up across rows, not just within one', (
tester,
) async {
await pumpActivity(tester);
// The point of three fixed columns is comparing one stop against the next.
// While every row sat in its own padded card that only held *inside* a row;
// sharing the page margin is what makes column two of one stop sit directly
// above column two of the one below.
final captions = tester.widgetList<Text>(find.text('COLLECTED')).toList();
expect(captions.length, 2);
final rects = [
for (var i = 0; i < 2; i++) tester.getRect(find.text('COLLECTED').at(i)),
];
expect(rects[0].left, closeTo(rects[1].left, 0.5));
// Column one starts flush with the stop name above it — no card inset.
final time = tester.getRect(find.text('TIME').first);
final name = tester.getRect(find.text('Sundar Textiles'));
expect(time.left, closeTo(name.left, 0.5));
});
testWidgets('the stop type is a dotted word, not a filled tag', (
tester,
) async {
await pumpActivity(tester);
// Two tinted rectangles under every address — the type and the order id —
// were the loudest things on a row whose subject is the figures below them.
expect(find.text('Pickup & Delivery'), findsOneWidget);
// `P&D` is `chipLabel`, which only ever reached this page through the
// filled tag. (`badgeLabel` still appears inside the collapsed detail,
// which `AnimatedCrossFade` builds either way — that one is a field value,
// not a mark.)
expect(find.text('P&D'), findsNothing);
final label = tester.widget<Text>(find.text('Pickup & Delivery'));
expect(label.style!.color, ColorConstants.combinedAccent);
// The reference stays copyable, in grey, without claiming any rank.
final id = tester.widget<Text>(find.text('#DM240817'));
expect(id.style!.color, ColorConstants.secondaryText);
});
testWidgets('column captions are readable, not disabled-grey', (
tester,
) async {
await pumpActivity(tester);
// #C7C7CC is a disabled-control colour. It measured about 1.9:1 on the
// white page, which made the three words naming the columns the least
// readable text on a screen used outdoors.
for (final caption in const ['TIME', 'RIDDEN', 'COLLECTED']) {
final text = tester.widget<Text>(find.text(caption).first);
expect(text.style!.color, ColorConstants.secondaryText);
expect(text.style!.color, isNot(ColorConstants.disabledFill));
}
});
testWidgets('the four tabs agree on what colour the paper is', (
tester,
) async {
// Account was on `surface` (#FCF9F8, a warm off-white) while Home and
// Activity were on `pureSurface`. Bookings hides its background under
// cards; Account is bare rows, so the whole tab read a shade dirtier.
Color? bgOf(Widget page) {
final scaffolds = <Scaffold>[];
void visit(Element e) {
final w = e.widget;
if (w is Scaffold) scaffolds.add(w);
e.visitChildren(visit);
}
WidgetsBinding.instance.rootElement!.visitChildren(visit);
return scaffolds.isEmpty ? null : scaffolds.first.backgroundColor;
}
SharedPreferences.setMockInitialValues({'userId': 1});
tester.view.physicalSize = const Size(390 * 3, 844 * 3);
tester.view.devicePixelRatio = 3.0;
addTearDown(tester.view.reset);
for (final page in <Widget>[const ActivityPage(), const ProfilePage()]) {
await tester.pumpWidget(
ScreenUtilInit(
designSize: const Size(390, 844),
builder: (_, _) => MaterialApp(home: page),
),
);
await tester.pump();
expect(bgOf(page), ColorConstants.pureSurface);
}
});
}