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'); }); }); }