Files
kooltab/test/inventory_view_model_test.dart
T
2026-10-08 04:12:36 +02:00

90 lines
2.3 KiB
Dart

import 'dart:async';
import 'package:flutter_test/flutter_test.dart';
import 'package:kooltap/models/product.dart';
import 'package:kooltap/services/product_service.dart';
import 'package:kooltap/viewmodels/inventory_view_model.dart';
import 'package:mocktail/mocktail.dart';
class MockProductService extends Mock implements ProductService {}
void main() {
late MockProductService mockService;
late StreamController<List<Product>> products;
late InventoryViewModel viewModel;
const beer = Product(
id: 'prod-1',
name: 'Beer',
category: 'Drinks',
stockQuantity: 20,
lowStockThreshold: 5,
priceInCents: 400,
);
setUp(() {
mockService = MockProductService();
products = StreamController<List<Product>>.broadcast();
when(() => mockService.watchProducts()).thenAnswer((_) => products.stream);
viewModel = InventoryViewModel(productService: mockService);
});
tearDown(() async {
viewModel.dispose();
await products.close();
});
group('InventoryViewModel', () {
test('is loading until the first emission', () async {
viewModel.ensureLoaded();
expect(viewModel.isLoading, true);
products.add([beer]);
await pumpEventQueue();
expect(viewModel.isLoading, false);
expect(viewModel.products, [beer]);
});
test('follows stock changes from the database', () async {
viewModel.ensureLoaded();
products.add([beer]);
await pumpEventQueue();
products.add([beer.copyWith(stockQuantity: 19)]);
await pumpEventQueue();
expect(viewModel.products.single.stockQuantity, 19);
});
test('subscribes only once', () async {
viewModel.ensureLoaded();
viewModel.ensureLoaded();
verify(() => mockService.watchProducts()).called(1);
});
test('notifies listeners on every emission', () async {
var notifyCount = 0;
viewModel.addListener(() => notifyCount++);
viewModel.ensureLoaded();
products
..add([beer])
..add([]);
await pumpEventQueue();
expect(notifyCount, 2);
});
test('exposes a load error when the stream fails', () async {
viewModel.ensureLoaded();
products.addError(StateError('database closed'));
await pumpEventQueue();
expect(viewModel.loadError, isNotNull);
});
});
}