// Author: fruit.com.cn import 'package:flutter_test/flutter_test.dart'; import 'package:fruitshorts/core/data/models/reward.dart'; import 'package:fruitshorts/core/data/repositories/reward_repository.dart'; import 'package:fruitshorts/core/data/services/reward_controller.dart'; void main() { test('should_refresh_balance_when_check_in_succeeds', () async { final repository = _RewardRepository(); final controller = RewardController(repository); await controller.load('id'); final result = await controller.checkIn(); expect(result?.rewardCoin, 35); expect(controller.overview?.coinBalance, 35); expect(repository.overviewCalls, 2); }); test('should_mark_claim_in_flight_when_task_is_claimed', () async { final repository = _RewardRepository(); final controller = RewardController(repository); final future = controller.claim('task-1'); expect(controller.claimingTaskId, 'task-1'); await future; expect(controller.claimingTaskId, isNull); expect(repository.claimedTaskId, 'task-1'); }); } class _RewardRepository implements RewardRepository { int overviewCalls = 0; String? claimedTaskId; @override Future fetchOverview(String locale) async { overviewCalls += 1; return RewardOverview( serverDate: '2026-11-05', timezone: 'Asia/Jakarta', coinBalance: overviewCalls > 1 ? 35 : 0, checkin: const RewardCheckinState( taskId: '1', checkedInToday: false, streak: 0, currentDay: 1, ), ); } @override Future checkIn() async { return const RewardActionResult( rewardCoin: 35, coinBalance: 35, alreadyCompleted: false, ); } @override Future claim(String taskId) async { claimedTaskId = taskId; await Future.delayed(Duration.zero); return const RewardActionResult( rewardCoin: 20, coinBalance: 55, alreadyCompleted: false, ); } }