From 798b35127f84c054907c528d584c6b1a685ad267 Mon Sep 17 00:00:00 2001 From: Andrea Bizzotto Date: Mon, 27 Jun 2022 12:03:42 +0100 Subject: [PATCH] autoDispose the addToCartControllerProvider + tests --- .../lib/src/features/cart/domain/item.dart | 12 +++ .../add_to_cart/add_to_cart_controller.dart | 4 +- .../add_to_cart_controller_test.dart | 74 +++++++++++++++++++ ecommerce_app/test/src/mocks.dart | 3 + 4 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 ecommerce_app/test/src/features/cart/presentation/add_to_cart/add_to_cart_controller_test.dart diff --git a/ecommerce_app/lib/src/features/cart/domain/item.dart b/ecommerce_app/lib/src/features/cart/domain/item.dart index fc62db7c..043c9981 100644 --- a/ecommerce_app/lib/src/features/cart/domain/item.dart +++ b/ecommerce_app/lib/src/features/cart/domain/item.dart @@ -8,4 +8,16 @@ class Item { }); final ProductID productId; final int quantity; + + @override + bool operator ==(Object other) { + if (identical(this, other)) return true; + + return other is Item && + other.productId == productId && + other.quantity == quantity; + } + + @override + int get hashCode => productId.hashCode ^ quantity.hashCode; } diff --git a/ecommerce_app/lib/src/features/cart/presentation/add_to_cart/add_to_cart_controller.dart b/ecommerce_app/lib/src/features/cart/presentation/add_to_cart/add_to_cart_controller.dart index 4c7822dc..dc35fbfc 100644 --- a/ecommerce_app/lib/src/features/cart/presentation/add_to_cart/add_to_cart_controller.dart +++ b/ecommerce_app/lib/src/features/cart/presentation/add_to_cart/add_to_cart_controller.dart @@ -23,9 +23,9 @@ class AddToCartController extends StateNotifier> { } } -// TODO: Should this use autoDispose? final addToCartControllerProvider = - StateNotifierProvider>((ref) { + StateNotifierProvider.autoDispose>( + (ref) { return AddToCartController( cartService: ref.watch(cartServiceProvider), ); diff --git a/ecommerce_app/test/src/features/cart/presentation/add_to_cart/add_to_cart_controller_test.dart b/ecommerce_app/test/src/features/cart/presentation/add_to_cart/add_to_cart_controller_test.dart new file mode 100644 index 00000000..847eaa3a --- /dev/null +++ b/ecommerce_app/test/src/features/cart/presentation/add_to_cart/add_to_cart_controller_test.dart @@ -0,0 +1,74 @@ +import 'package:ecommerce_app/src/features/cart/domain/item.dart'; +import 'package:ecommerce_app/src/features/cart/presentation/add_to_cart/add_to_cart_controller.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mocktail/mocktail.dart'; + +import '../../../../mocks.dart'; + +void main() { + const productId = '1'; + group('addItem', () { + test('item added with quantity = 2, success', () async { + // setup + const quantity = 2; + const item = Item(productId: productId, quantity: quantity); + final cartService = MockCartService(); + when(() => cartService.addItem(item)).thenAnswer( + (_) => Future.value(null), + ); + // run & verify + final controller = AddToCartController(cartService: cartService); + expect( + controller.state, + const AsyncData(1), + ); + controller.updateQuantity(quantity); + expect( + controller.state, + const AsyncData(2), + ); + // * if desired, use expectLater and emitsInOrder here to check that + // * addItems emits two values + await controller.addItem(productId); + verify(() => cartService.addItem(item)).called(1); + // check that quantity goes back to 1 after adding an item + expect( + controller.state, + const AsyncData(1), + ); + }); + + test('item added with quantity = 2, failure', () async { + const quantity = 2; + const item = Item(productId: productId, quantity: quantity); + final cartService = MockCartService(); + when(() => cartService.addItem(item)) + .thenThrow((_) => Exception('Connection failed')); + final controller = AddToCartController(cartService: cartService); + expect( + controller.state, + const AsyncData(1), + ); + controller.updateQuantity(quantity); + expect( + controller.state, + const AsyncData(2), + ); + // * if desired, use expectLater and emitsInOrder here to check that + // * addItems emits two values + await controller.addItem(productId); + verify(() => cartService.addItem(item)).called(1); + // check that quantity goes back to 1 after adding an item + expect( + controller.state, + predicate>( + (value) { + expect(value.hasError, true); + return true; + }, + ), + ); + }); + }); +} diff --git a/ecommerce_app/test/src/mocks.dart b/ecommerce_app/test/src/mocks.dart index 23595384..33213297 100644 --- a/ecommerce_app/test/src/mocks.dart +++ b/ecommerce_app/test/src/mocks.dart @@ -1,4 +1,5 @@ import 'package:ecommerce_app/src/features/authentication/data/fake_auth_repository.dart'; +import 'package:ecommerce_app/src/features/cart/application/cart_service.dart'; import 'package:ecommerce_app/src/features/cart/data/local/local_cart_repository.dart'; import 'package:ecommerce_app/src/features/cart/data/remote/remote_cart_repository.dart'; import 'package:mocktail/mocktail.dart'; @@ -8,3 +9,5 @@ class MockAuthRepository extends Mock implements FakeAuthRepository {} class MockRemoteCartRepository extends Mock implements RemoteCartRepository {} class MockLocalCartRepository extends Mock implements LocalCartRepository {} + +class MockCartService extends Mock implements CartService {}