import 'package:flutter_test/flutter_test.dart'; import 'package:kooltab2/models/product.dart'; import 'package:kooltab2/models/tab_item.dart'; import 'package:kooltab2/services/bar_tab_service.dart'; import 'package:kooltab2/services/product_service.dart'; import 'package:kooltab2/viewmodels/bar_screen_view_model.dart'; import 'package:kooltab2/viewmodels/inventory_view_model.dart'; import 'package:mocktail/mocktail.dart'; class MockBarTabService extends Mock implements BarTabService {} class MockProductService extends Mock implements ProductService {} void main() { late MockBarTabService barTabService; late MockProductService productService; late InventoryViewModel inventory; late BarScreenViewModel viewModel; setUp(() { barTabService = MockBarTabService(); productService = MockProductService(); inventory = InventoryViewModel(productService: productService); viewModel = BarScreenViewModel( barTabService: barTabService, inventory: inventory, ); }); test('propagates an insufficient-stock error from the transaction', () async { const item = TabItem( id: 'item-1', tabId: 'tab-1', productId: 'prod-1', productName: 'Chips', quantity: 20, unitPriceInCents: 150, ); when( () => barTabService.adjustTabItemQuantity(tabItemId: 'item-1', delta: 1), ).thenAnswer((_) async => throw const InsufficientStockException()); await expectLater( viewModel.changeItemQuantity(item, 1), throwsA(isA()), ); expect(viewModel.errorMessage, isNull); verify( () => barTabService.adjustTabItemQuantity(tabItemId: 'item-1', delta: 1), ).called(1); }); test('updates inventory when a tab is deleted', () async { final product = Product( id: 'prod-1', name: 'Chips', category: 'Snacks', stockQuantity: 8, lowStockThreshold: 2, priceInCents: 150, ); const item = TabItem( id: 'item-1', tabId: 'tab-1', productId: 'prod-1', productName: 'Chips', quantity: 3, unitPriceInCents: 150, ); when(() => productService.getProducts()).thenAnswer((_) async => [product]); await inventory.load(); when( () => barTabService.deleteTab('tab-1'), ).thenAnswer((_) async => [item]); when(() => barTabService.getOpenTabs()).thenAnswer((_) async => []); await viewModel.deleteTab('tab-1'); expect(inventory.products.first.stockQuantity, 11); verify(() => barTabService.deleteTab('tab-1')).called(1); verify(() => barTabService.getOpenTabs()).called(1); }); }