// Author: fruit.com.cn import 'package:flutter_test/flutter_test.dart'; import 'package:fruitshorts/core/data/models/order.dart'; import 'package:fruitshorts/core/data/models/product.dart'; import 'package:fruitshorts/core/data/remote/api_exception.dart'; import 'package:fruitshorts/core/data/repositories/store_repository.dart'; import 'package:fruitshorts/core/data/services/store_controller.dart'; void main() { test('should_expose_coin_packs_when_store_loads', () async { final repository = _FakeStoreRepository( products: [_product('550 Coins', coinAmount: 500, bonusCoin: 50)], ); final controller = StoreController( repository, type: StoreController.coinPackType, ); await controller.load(); expect(repository.requestedTypes, [StoreController.coinPackType]); expect(controller.products.single.name, '550 Coins'); expect(controller.error, isNull); }); test('should_create_order_and_keep_purchase_when_buying', () async { final repository = _FakeStoreRepository( products: [_product('550 Coins')], order: const AppOrder( id: '99', orderNo: 'ORD1', productName: '550 Coins', coinAmount: 550, status: 'CREATED', ), ); final controller = StoreController( repository, type: StoreController.coinPackType, ); await controller.load(); final order = await controller.buy(controller.products.single); expect(repository.orderedProductIds, ['2111012753262120962']); expect(order?.orderNo, 'ORD1'); expect(controller.purchaseError, isNull); expect(controller.purchasingProductId, isNull); }); test('should_expose_server_message_when_order_is_rejected', () async { final repository = _FakeStoreRepository( products: [_product('550 Coins')], orderError: const ApiException(400, 'Product is offline'), ); final controller = StoreController( repository, type: StoreController.coinPackType, ); await controller.load(); final order = await controller.buy(controller.products.single); expect(order, isNull); expect(controller.purchaseError, 'Product is offline'); }); } AppProduct _product(String name, {int coinAmount = 550, int bonusCoin = 0}) => AppProduct( id: '2111012753262120962', code: 'coin_550', name: name, type: StoreController.coinPackType, coinAmount: coinAmount, bonusCoin: bonusCoin, totalCoin: coinAmount + bonusCoin, displayPrice: 'Rp 15.000', vipDays: 0, ); class _FakeStoreRepository implements StoreRepository { _FakeStoreRepository({ this.products = const [], this.order, this.orderError, }); final List products; final AppOrder? order; final ApiException? orderError; final List requestedTypes = []; final List orderedProductIds = []; @override Future> fetchProducts({String? type}) async { requestedTypes.add(type); return products; } @override Future createOrder(String productId) async { orderedProductIds.add(productId); if (orderError != null) throw orderError!; return order!; } }