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

73 lines
2.7 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:miler/data/rider_tier.dart';
/// The ladder behind the Rewards page. Modelled on Uber Pro: points earned over
/// a fixed period decide the status, and the screen's job is to answer "how far
/// is the next one" in points a rider can act on today.
void main() {
group('standing', () {
test('starts at the bottom rung', () {
final s = TierStanding.of(0);
expect(s.tier, RiderTier.blue);
expect(s.nextTier, RiderTier.silver);
expect(s.pointsToNext, kTierThresholds[RiderTier.silver]);
expect(s.progressToNext, 0);
});
test('lands on the highest threshold passed, not the nearest', () {
expect(TierStanding.of(149).tier, RiderTier.blue);
expect(TierStanding.of(150).tier, RiderTier.silver);
expect(TierStanding.of(399).tier, RiderTier.silver);
expect(TierStanding.of(400).tier, RiderTier.gold);
});
// A rider one point into Gold should see an empty bar to Platinum, not a
// bar already half full because his lifetime number is big.
test('progress is measured across the current band', () {
final justIn = TierStanding.of(400);
expect(justIn.tier, RiderTier.gold);
expect(justIn.progressToNext, 0);
final halfway = TierStanding.of(600); // 400 → 800
expect(halfway.progressToNext, closeTo(0.5, 0.001));
});
test('the top of the ladder has nothing left to chase', () {
final s = TierStanding.of(5000);
expect(s.tier, RiderTier.platinum);
expect(s.nextTier, isNull);
expect(s.pointsToNext, isNull);
expect(s.progressToNext, 1);
});
test('every tier knows the one above it, and the last one does not', () {
expect(RiderTier.blue.next, RiderTier.silver);
expect(RiderTier.gold.next, RiderTier.platinum);
expect(RiderTier.platinum.next, isNull);
});
});
group('reward period', () {
test('is the calendar month, whole and inclusive', () {
final p = RewardPeriod.current(DateTime(2026, 8, 5));
expect(p.start, DateTime(2026, 8, 1));
expect(p.end, DateTime(2026, 8, 31));
expect(p.label, 'August 2026');
});
test('counts today as a day left, and never goes negative', () {
final p = RewardPeriod.current(DateTime(2026, 8, 30));
expect(p.daysLeft(DateTime(2026, 8, 30)), 2);
expect(p.daysLeft(DateTime(2026, 8, 31)), 1);
expect(p.daysLeft(DateTime(2026, 9, 4)), 0);
});
test('handles a December period rolling into the new year', () {
final p = RewardPeriod.current(DateTime(2026, 12, 10));
expect(p.end, DateTime(2026, 12, 31));
expect(p.label, 'December 2026');
});
});
}