diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 6d39cb4..44cb3c7 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -33,10 +33,10 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be - path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 - shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 - sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d + flutter_secure_storage: 2c2ff13db9e0a5647389bff88b0ecac56e3f3418 + path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564 + shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 + sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 diff --git a/lib/core/constant/strings.dart b/lib/core/constant/strings.dart index a10cbd6..a940cae 100644 --- a/lib/core/constant/strings.dart +++ b/lib/core/constant/strings.dart @@ -2,8 +2,8 @@ const String appTitle = 'EShop'; // Networking and APIs -// const String baseUrl = 'https://e-commerce-mock-api-webservice.onrender.com'; -const String baseUrl = 'http://192.168.1.43:4000'; +const String baseUrl = 'https://e-commerce-mock-api-d8zv.onrender.com'; +// const String baseUrl = 'http://192.168.1.43:4000'; const String defaultApiKey = ''; const String defaultSources = ''; diff --git a/lib/core/constant/validators.dart b/lib/core/constant/validators.dart new file mode 100644 index 0000000..d186c83 --- /dev/null +++ b/lib/core/constant/validators.dart @@ -0,0 +1,27 @@ +class Validators { + static String? validateField(String? value, String fieldName) { + if (value == null || value.isEmpty) { + return "$fieldName can't be empty"; + } + return null; + } + + static String? validateEmail(String? value) { + if (value == null || value.isEmpty) { + return "Email can't be empty"; + } + final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'); + if (!emailRegex.hasMatch(value)) { + return "Invalid email format"; + } + return null; + } + + static String? validatePasswordMatch(String? value, String otherValue) { + if (value != otherValue) { + return "Passwords do not match"; + } + return null; + } + +} diff --git a/lib/core/services/services_locator.dart b/lib/core/services/services_locator.dart index 63baabc..0d516e5 100644 --- a/lib/core/services/services_locator.dart +++ b/lib/core/services/services_locator.dart @@ -1,8 +1,8 @@ -import 'package:eshop/domain/usecases/delivery_info/clear_local_delivery_info_usecase.dart'; +import 'package:eshop/domain/usecases/delivery_info/delete_local_delivery_info_usecase.dart'; import 'package:eshop/domain/usecases/delivery_info/edit_delivery_info_usecase.dart'; import 'package:eshop/domain/usecases/delivery_info/get_selected_delivery_info_usecase.dart'; import 'package:eshop/domain/usecases/delivery_info/select_delivery_info_usecase.dart'; -import 'package:eshop/domain/usecases/order/clear_local_order_usecase.dart'; +import 'package:eshop/domain/usecases/order/delete_local_order_usecase.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:get_it/get_it.dart'; import 'package:http/http.dart' as http; @@ -34,20 +34,20 @@ import '../../domain/repositories/order_repository.dart'; import '../../domain/repositories/product_repository.dart'; import '../../domain/repositories/user_repository.dart'; import '../../domain/usecases/cart/add_cart_item_usecase.dart'; -import '../../domain/usecases/cart/clear_cart_usecase.dart'; -import '../../domain/usecases/cart/get_cached_cart_usecase.dart'; -import '../../domain/usecases/cart/sync_cart_usecase.dart'; +import '../../domain/usecases/cart/delete_cart_usecase.dart'; +import '../../domain/usecases/cart/get_local_cart_items_usecase.dart'; +import '../../domain/usecases/cart/get_remote_cart_items_usecase.dart'; import '../../domain/usecases/category/filter_category_usecase.dart'; -import '../../domain/usecases/category/get_cached_category_usecase.dart'; +import '../../domain/usecases/category/get_local_category_usecase.dart'; import '../../domain/usecases/category/get_remote_category_usecase.dart'; import '../../domain/usecases/delivery_info/add_dilivey_info_usecase.dart'; -import '../../domain/usecases/delivery_info/get_cached_delivery_info_usecase.dart'; +import '../../domain/usecases/delivery_info/get_local_delivery_info_usecase.dart'; import '../../domain/usecases/delivery_info/get_remote_delivery_info_usecase.dart'; import '../../domain/usecases/order/add_order_usecase.dart'; -import '../../domain/usecases/order/get_cached_orders_usecase.dart'; +import '../../domain/usecases/order/get_local_orders_usecase.dart'; import '../../domain/usecases/order/get_remote_orders_usecase.dart'; import '../../domain/usecases/product/get_product_usecase.dart'; -import '../../domain/usecases/user/get_cached_user_usecase.dart'; +import '../../domain/usecases/user/get_local_user_usecase.dart'; import '../../domain/usecases/user/sign_in_usecase.dart'; import '../../domain/usecases/user/sign_out_usecase.dart'; import '../../domain/usecases/user/sign_up_usecase.dart'; @@ -94,7 +94,7 @@ Future init() async { ); // Use cases sl.registerLazySingleton(() => GetRemoteCategoryUseCase(sl())); - sl.registerLazySingleton(() => GetCachedCategoryUseCase(sl())); + sl.registerLazySingleton(() => GetLocalCategoryUseCase(sl())); sl.registerLazySingleton(() => FilterCategoryUseCase(sl())); // Repository sl.registerLazySingleton( @@ -118,10 +118,10 @@ Future init() async { () => CartBloc(sl(), sl(), sl(), sl()), ); // Use cases - sl.registerLazySingleton(() => GetCachedCartUseCase(sl())); + sl.registerLazySingleton(() => GetLocalCartItemsUseCase(sl())); sl.registerLazySingleton(() => AddCartUseCase(sl())); - sl.registerLazySingleton(() => SyncCartUseCase(sl())); - sl.registerLazySingleton(() => ClearCartUseCase(sl())); + sl.registerLazySingleton(() => GetRemoteCardItemsUseCase(sl())); + sl.registerLazySingleton(() => DeleteCartUseCase(sl())); // Repository sl.registerLazySingleton( () => CartRepositoryImpl( @@ -149,12 +149,12 @@ Future init() async { ); // Use cases sl.registerLazySingleton(() => GetRemoteDeliveryInfoUseCase(sl())); - sl.registerLazySingleton(() => GetCachedDeliveryInfoUseCase(sl())); + sl.registerLazySingleton(() => GetLocalDeliveryInfoUseCase(sl())); sl.registerLazySingleton(() => AddDeliveryInfoUseCase(sl())); sl.registerLazySingleton(() => EditDeliveryInfoUseCase(sl())); sl.registerLazySingleton(() => SelectDeliveryInfoUseCase(sl())); sl.registerLazySingleton(() => GetSelectedDeliveryInfoInfoUseCase(sl())); - sl.registerLazySingleton(() => ClearLocalDeliveryInfoUseCase(sl())); + sl.registerLazySingleton(() => DeleteLocalDeliveryInfoUseCase(sl())); // Repository sl.registerLazySingleton( () => DeliveryInfoRepositoryImpl( @@ -183,8 +183,8 @@ Future init() async { // Use cases sl.registerLazySingleton(() => AddOrderUseCase(sl())); sl.registerLazySingleton(() => GetRemoteOrdersUseCase(sl())); - sl.registerLazySingleton(() => GetCachedOrdersUseCase(sl())); - sl.registerLazySingleton(() => ClearLocalOrdersUseCase(sl())); + sl.registerLazySingleton(() => GetLocalOrdersUseCase(sl())); + sl.registerLazySingleton(() => DeleteLocalOrdersUseCase(sl())); // Repository sl.registerLazySingleton( () => OrderRepositoryImpl( @@ -208,7 +208,7 @@ Future init() async { () => UserBloc(sl(), sl(), sl(), sl()), ); // Use cases - sl.registerLazySingleton(() => GetCachedUserUseCase(sl())); + sl.registerLazySingleton(() => GetLocalUserUseCase(sl())); sl.registerLazySingleton(() => SignInUseCase(sl())); sl.registerLazySingleton(() => SignUpUseCase(sl())); sl.registerLazySingleton(() => SignOutUseCase(sl())); @@ -240,4 +240,4 @@ Future init() async { sl.registerLazySingleton(() => secureStorage); sl.registerLazySingleton(() => http.Client()); sl.registerLazySingleton(() => InternetConnectionChecker()); -} +} \ No newline at end of file diff --git a/lib/core/theme/app_theme.dart b/lib/core/theme/app_theme.dart index 4df6e95..1f03377 100644 --- a/lib/core/theme/app_theme.dart +++ b/lib/core/theme/app_theme.dart @@ -10,9 +10,9 @@ class AppTheme { visualDensity: VisualDensity.adaptivePlatformDensity, scaffoldBackgroundColor: kBackgroundColor, appBarTheme: AppBarTheme( - backgroundColor: Colors.white, - foregroundColor: kLightSecondaryColor, - elevation: 0, + backgroundColor: kLightPrimaryColor, + foregroundColor: kBackgroundColor, + // elevation: 0, ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom(foregroundColor: kLightSecondaryColor)), diff --git a/lib/data/data_sources/local/cart_local_data_source.dart b/lib/data/data_sources/local/cart_local_data_source.dart index 7485f04..5cc771a 100644 --- a/lib/data/data_sources/local/cart_local_data_source.dart +++ b/lib/data/data_sources/local/cart_local_data_source.dart @@ -7,7 +7,8 @@ abstract class CartLocalDataSource { Future> getCart(); Future saveCart(List cart); Future saveCartItem(CartItemModel cartItem); - Future clearCart(); + Future deleteCartItem(CartItemModel cartItem); + Future deleteCart(); } const cachedCart = 'CACHED_CART'; @@ -53,7 +54,25 @@ class CartLocalDataSourceImpl implements CartLocalDataSource { } @override - Future clearCart()async { + Future deleteCart() async { return sharedPreferences.remove(cachedCart); } + + @override + Future deleteCartItem(CartItemModel cartItem) async { + final jsonString = sharedPreferences.getString(cachedCart); + if (jsonString != null) { + final List cart = + cartItemModelListFromLocalJson(jsonString); + cart.removeWhere((element) => + element.product.id == cartItem.product.id && + element.priceTag.id == cartItem.priceTag.id); + return sharedPreferences.setString( + cachedCart, + cartItemModelToJson(cart), + ); + } else { + throw CacheFailure(); + } + } } diff --git a/lib/data/data_sources/remote/cart_remote_data_source.dart b/lib/data/data_sources/remote/cart_remote_data_source.dart index b8f18c2..a6590f4 100644 --- a/lib/data/data_sources/remote/cart_remote_data_source.dart +++ b/lib/data/data_sources/remote/cart_remote_data_source.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:eshop/core/usecases/usecase.dart'; import 'package:http/http.dart' as http; import '../../../../core/error/exceptions.dart'; @@ -9,6 +10,8 @@ import '../../models/cart/cart_item_model.dart'; abstract class CartRemoteDataSource { Future addToCart(CartItemModel cartItem, String token); Future> syncCart(List cart, String token); + Future deleteCartItem(CartItemModel cart, String token); + Future deleteCart(String token); } class CartRemoteDataSourceSourceImpl implements CartRemoteDataSource { @@ -54,4 +57,16 @@ class CartRemoteDataSourceSourceImpl implements CartRemoteDataSource { throw ServerException(); } } + + @override + Future deleteCartItem(CartItemModel cart, String token) async { + // TODO: implement deleteCartItem + throw UnimplementedError(); + } + + @override + Future deleteCart(String token) async { + // TODO: implement deleteCart + throw UnimplementedError(); + } } diff --git a/lib/data/models/order/order_details_model.dart b/lib/data/models/order/order_details_model.dart index a18046f..8520dea 100644 --- a/lib/data/models/order/order_details_model.dart +++ b/lib/data/models/order/order_details_model.dart @@ -59,10 +59,11 @@ class OrderDetailsModel extends OrderDetails { factory OrderDetailsModel.fromEntity(OrderDetails entity) => OrderDetailsModel( - id: entity.id, - orderItems: entity.orderItems - .map((orderItem) => OrderItemModel.fromEntity(orderItem)) - .toList(), - deliveryInfo: DeliveryInfoModel.fromEntity(entity.deliveryInfo), - discount: entity.discount); + id: entity.id, + orderItems: entity.orderItems + .map((orderItem) => OrderItemModel.fromEntity(orderItem)) + .toList(), + deliveryInfo: DeliveryInfoModel.fromEntity(entity.deliveryInfo), + discount: entity.discount, + ); } diff --git a/lib/data/repositories/cart_repository_impl.dart b/lib/data/repositories/cart_repository_impl.dart index c55b513..897b5b5 100644 --- a/lib/data/repositories/cart_repository_impl.dart +++ b/lib/data/repositories/cart_repository_impl.dart @@ -1,4 +1,5 @@ import 'package:dartz/dartz.dart'; +import 'package:eshop/core/usecases/usecase.dart'; import '../../../../core/error/failures.dart'; import '../../core/network/network_info.dart'; @@ -23,71 +24,106 @@ class CartRepositoryImpl implements CartRepository { }); @override - Future> addToCart(CartItem params) async { - if (await userLocalDataSource.isTokenAvailable()) { - await localDataSource.saveCartItem(CartItemModel.fromParent(params)); - final String token = await userLocalDataSource.getToken(); - final remoteProduct = await remoteDataSource.addToCart( - CartItemModel.fromParent(params), - token, - ); - return Right(remoteProduct); - } else { - await localDataSource.saveCartItem(CartItemModel.fromParent(params)); - return Right(params); + Future>> getLocalCartItems() async { + try { + final localProducts = await localDataSource.getCart(); + return Right(localProducts); + } on Failure catch (failure) { + return Left(failure); } } @override - Future> deleteFormCart() { - // TODO: implement deleteFormCart - throw UnimplementedError(); - } + Future>> getRemoteCartItems() async { + if (!await networkInfo.isConnected) { + return Left(NetworkFailure()); + } + if (!await userLocalDataSource.isTokenAvailable()) { + return Left(AuthenticationFailure()); + } - @override - Future>> getCachedCart() async { + List localCartItems = []; try { - final localProducts = await localDataSource.getCart(); - return Right(localProducts); + localCartItems = await localDataSource.getCart(); + } on Failure { + localCartItems = []; + } + + try { + final String token = await userLocalDataSource.getToken(); + final syncedResult = await remoteDataSource.syncCart( + localCartItems, + token, + ); + await localDataSource.saveCart(syncedResult); + return Right(syncedResult); } on Failure catch (failure) { return Left(failure); } } @override - Future>> syncCart() async { - if (await networkInfo.isConnected) { - if (await userLocalDataSource.isTokenAvailable()) { - List localCartItems = []; - try { - localCartItems = await localDataSource.getCart(); - } on Failure catch (_) {} - try { - final String token = await userLocalDataSource.getToken(); - final syncedResult = await remoteDataSource.syncCart( - localCartItems, - token, - ); - await localDataSource.saveCart(syncedResult); - return Right(syncedResult); - } on Failure catch (failure) { - return Left(failure); - } - } else { - return Left(NetworkFailure()); - } - } else { - return Left(NetworkFailure()); + Future> addCartItem(CartItem params) async { + final token = await userLocalDataSource.getToken(); + // Check if the token is empty or if the network is not connected + // If so, save the cart item locally and return it + // Otherwise, proceed with the remote data source + if (token.isEmpty || !await networkInfo.isConnected) { + await localDataSource.saveCartItem(CartItemModel.fromParent(params)); + return Right(params); + } + + // Proceed with the remote data source + // and save the cart item locally + // after receiving the response + final cartItemModel = CartItemModel.fromParent(params); + final remoteResponse = await remoteDataSource.addToCart( + cartItemModel, + token, + ); + await localDataSource.saveCartItem(remoteResponse); + return Right(remoteResponse); + } + + @override + Future> deleteCartItem(CartItem params) async { + final token = await userLocalDataSource.getToken(); + final cartItem = CartItemModel.fromParent(params); + // Check if the token is empty or if the network is not connected + // If so, delete the cart item locally and return true + // Otherwise, proceed with the remote data source + // and delete the cart item locally after receiving the response + if (token.isEmpty || !await networkInfo.isConnected) { + localDataSource.deleteCartItem(cartItem); + return Right(cartItem); } + + // Proceed with the remote data source + // and delete the cart item locally after receiving the response + final remoteResponse = await remoteDataSource.deleteCartItem( + cartItem, + token, + ); + await localDataSource.deleteCartItem(remoteResponse); + return Right(remoteResponse); } @override - Future> clearCart() async { - bool result = await localDataSource.clearCart(); - if (result) { - return Right(result); - } else { - return Left(CacheFailure()); + Future> deleteCart() async { + final token = await userLocalDataSource.getToken(); + // Check if the token is empty or if the network is not connected + // If so, delete the cart locally and return true + // Otherwise, proceed with the remote data source + // and delete the cart locally after receiving the response + if (token.isEmpty || !await networkInfo.isConnected) { + localDataSource.deleteCart(); + return Right(NoParams()); } + + // Proceed with the remote data source + // and delete the cart locally after receiving the response + final remoteResponse = await remoteDataSource.deleteCart(token); + await localDataSource.deleteCart(); + return Right(remoteResponse); } } diff --git a/lib/data/repositories/category_repository_impl.dart b/lib/data/repositories/category_repository_impl.dart index add25c8..9c4cc74 100644 --- a/lib/data/repositories/category_repository_impl.dart +++ b/lib/data/repositories/category_repository_impl.dart @@ -8,7 +8,6 @@ import '../../domain/repositories/category_repository.dart'; import '../data_sources/local/category_local_data_source.dart'; import '../data_sources/remote/category_remote_data_source.dart'; - class CategoryRepositoryImpl implements CategoryRepository { final CategoryRemoteDataSource remoteDataSource; final CategoryLocalDataSource localDataSource; @@ -22,21 +21,20 @@ class CategoryRepositoryImpl implements CategoryRepository { @override Future>> getRemoteCategories() async { - if (await networkInfo.isConnected) { - try { - final remoteProducts = await remoteDataSource.getCategories(); - localDataSource.saveCategories(remoteProducts); - return Right(remoteProducts); - } on Failure catch (failure) { - return Left(failure); - } - } else { + if (!await networkInfo.isConnected) { return Left(NetworkFailure()); } + try { + final remoteProducts = await remoteDataSource.getCategories(); + localDataSource.saveCategories(remoteProducts); + return Right(remoteProducts); + } on Failure catch (failure) { + return Left(failure); + } } @override - Future>> getCachedCategories() async { + Future>> getLocalCategories() async { try { final localProducts = await localDataSource.getCategories(); return Right(localProducts); diff --git a/lib/data/repositories/delivery_info_impl.dart b/lib/data/repositories/delivery_info_impl.dart index 05d7aa1..a66cd7f 100644 --- a/lib/data/repositories/delivery_info_impl.dart +++ b/lib/data/repositories/delivery_info_impl.dart @@ -25,28 +25,28 @@ class DeliveryInfoRepositoryImpl implements DeliveryInfoRepository { @override Future>> getRemoteDeliveryInfo() async { - if (await networkInfo.isConnected) { - if (await userLocalDataSource.isTokenAvailable()) { - try { - final String token = await userLocalDataSource.getToken(); - final result = await remoteDataSource.getDeliveryInfo( - token, - ); - await localDataSource.saveDeliveryInfo(result); - return Right(result); - } on Failure catch (failure) { - return Left(failure); - } - } else { - return Left(AuthenticationFailure()); - } - } else { + if (!await networkInfo.isConnected) { return Left(NetworkFailure()); } + final token = await userLocalDataSource.getToken(); + if (token.isEmpty) { + return Left(AuthenticationFailure()); + } + + try { + final String token = await userLocalDataSource.getToken(); + final result = await remoteDataSource.getDeliveryInfo( + token, + ); + await localDataSource.saveDeliveryInfo(result); + return Right(result); + } on Failure catch (failure) { + return Left(failure); + } } @override - Future>> getCachedDeliveryInfo() async { + Future>> getLocalDeliveryInfo() async { try { final result = await localDataSource.getDeliveryInfo(); return Right(result); @@ -57,43 +57,45 @@ class DeliveryInfoRepositoryImpl implements DeliveryInfoRepository { @override Future> addDeliveryInfo(params) async { - if (await userLocalDataSource.isTokenAvailable()) { - try { - final String token = await userLocalDataSource.getToken(); - final DeliveryInfoModel deliveryInfo = - await remoteDataSource.addDeliveryInfo( - params, - token, - ); - await localDataSource.updateDeliveryInfo(deliveryInfo); - return Right(deliveryInfo); - } on Failure catch (failure) { - return Left(failure); - } - } else { + if (!await networkInfo.isConnected) { + return Left(NetworkFailure()); + } + final token = await userLocalDataSource.getToken(); + if (token.isEmpty) { return Left(AuthenticationFailure()); } + try { + final deliveryInfo = await remoteDataSource.addDeliveryInfo( + params, + token, + ); + await localDataSource.updateDeliveryInfo(deliveryInfo); + return Right(deliveryInfo); + } on Failure catch (failure) { + return Left(failure); + } } @override Future> editDeliveryInfo( DeliveryInfoModel params) async { - if (await userLocalDataSource.isTokenAvailable()) { - try { - final String token = await userLocalDataSource.getToken(); - final DeliveryInfoModel deliveryInfo = - await remoteDataSource.editDeliveryInfo( - params, - token, - ); - await localDataSource.updateDeliveryInfo(deliveryInfo); - return Right(deliveryInfo); - } on Failure catch (failure) { - return Left(failure); - } - } else { + if (!await networkInfo.isConnected) { + return Left(NetworkFailure()); + } + final token = await userLocalDataSource.getToken(); + if (token.isEmpty) { return Left(AuthenticationFailure()); } + try { + final deliveryInfo = await remoteDataSource.editDeliveryInfo( + params, + token, + ); + await localDataSource.updateDeliveryInfo(deliveryInfo); + return Right(deliveryInfo); + } on Failure catch (failure) { + return Left(failure); + } } @override @@ -119,7 +121,7 @@ class DeliveryInfoRepositoryImpl implements DeliveryInfoRepository { } @override - Future> clearLocalDeliveryInfo() async { + Future> deleteLocalDeliveryInfo() async { try { await localDataSource.clearDeliveryInfo(); return Right(NoParams()); diff --git a/lib/data/repositories/order_repository_impl.dart b/lib/data/repositories/order_repository_impl.dart index 73d7fec..d66e4fc 100644 --- a/lib/data/repositories/order_repository_impl.dart +++ b/lib/data/repositories/order_repository_impl.dart @@ -25,42 +25,43 @@ class OrderRepositoryImpl implements OrderRepository { @override Future> addOrder(OrderDetails params) async { - if (await userLocalDataSource.isTokenAvailable()) { - final String token = await userLocalDataSource.getToken(); - final remoteProduct = await remoteDataSource.addOrder( - OrderDetailsModel.fromEntity(params), - token, - ); - return Right(remoteProduct); - } else { + if(!await networkInfo.isConnected) { return Left(NetworkFailure()); } + final token = await userLocalDataSource.getToken(); + if (token.isEmpty) { + return Left(AuthenticationFailure()); + } + + final remoteProduct = await remoteDataSource.addOrder( + OrderDetailsModel.fromEntity(params), + token, + ); + return Right(remoteProduct); } @override Future>> getRemoteOrders() async { - if (await networkInfo.isConnected) { - if (await userLocalDataSource.isTokenAvailable()) { - try { - final String token = await userLocalDataSource.getToken(); - final remoteProduct = await remoteDataSource.getOrders( - token, - ); - await localDataSource.saveOrders(remoteProduct); - return Right(remoteProduct); - } on Failure catch (failure) { - return Left(failure); - } - } else { - return Left(AuthenticationFailure()); - } - } else { + if (!await networkInfo.isConnected) { return Left(NetworkFailure()); } + final token = await userLocalDataSource.getToken(); + if (token.isEmpty) { + return Left(AuthenticationFailure()); + } + try { + final remoteProduct = await remoteDataSource.getOrders( + token, + ); + await localDataSource.saveOrders(remoteProduct); + return Right(remoteProduct); + } on Failure catch (failure) { + return Left(failure); + } } @override - Future>> getCachedOrders() async { + Future>> getLocalOrders() async { try { final localOrders = await localDataSource.getOrders(); return Right(localOrders); @@ -70,7 +71,7 @@ class OrderRepositoryImpl implements OrderRepository { } @override - Future> clearLocalOrders() async { + Future> deleteLocalOrders() async { try { await localDataSource.clearOrder(); return Right(NoParams()); diff --git a/lib/data/repositories/product_repository_impl.dart b/lib/data/repositories/product_repository_impl.dart index 2bd78af..1955e51 100644 --- a/lib/data/repositories/product_repository_impl.dart +++ b/lib/data/repositories/product_repository_impl.dart @@ -8,9 +8,6 @@ import '../../domain/repositories/product_repository.dart'; import '../../domain/usecases/product/get_product_usecase.dart'; import '../data_sources/local/product_local_data_source.dart'; import '../data_sources/remote/product_remote_data_source.dart'; -import '../models/product/product_response_model.dart'; - -typedef _ConcreteOrProductChooser = Future Function(); class ProductRepositoryImpl implements ProductRepository { final ProductRemoteDataSource remoteDataSource; @@ -24,30 +21,28 @@ class ProductRepositoryImpl implements ProductRepository { }); @override - Future> getProducts(FilterProductParams params) async { - return await _getProduct(() { - return remoteDataSource.getProducts(params); - }); + Future> getRemoteProducts( + FilterProductParams params) async { + if (!await networkInfo.isConnected) { + return Left(NetworkFailure()); + } + try { + final remoteProducts = await remoteDataSource.getProducts(params); + localDataSource.saveProducts(remoteProducts); + return Right(remoteProducts); + } on ServerException { + return Left(ServerFailure()); + } } - Future> _getProduct( - _ConcreteOrProductChooser getConcreteOrProducts, - ) async { - if (await networkInfo.isConnected) { - try { - final remoteProducts = await getConcreteOrProducts(); - localDataSource.saveProducts(remoteProducts as ProductResponseModel); - return Right(remoteProducts); - } on ServerException { - return Left(ServerFailure()); - } - } else { - try { - final localProducts = await localDataSource.getLastProducts(); - return Right(localProducts); - } on CacheException { - return Left(CacheFailure()); - } + @override + Future> getLocalProducts( + FilterProductParams params) async { + try { + final localProducts = await localDataSource.getLastProducts(); + return Right(localProducts); + } on CacheException { + return Left(CacheFailure()); } } } diff --git a/lib/data/repositories/user_repository_impl.dart b/lib/data/repositories/user_repository_impl.dart index c7368fa..95813a7 100644 --- a/lib/data/repositories/user_repository_impl.dart +++ b/lib/data/repositories/user_repository_impl.dart @@ -9,8 +9,6 @@ import '../data_sources/local/user_local_data_source.dart'; import '../data_sources/remote/user_remote_data_source.dart'; import '../models/user/authentication_response_model.dart'; -typedef _DataSourceChooser = Future Function(); - class UserRepositoryImpl implements UserRepository { final UserRemoteDataSource remoteDataSource; final UserLocalDataSource localDataSource; @@ -24,25 +22,31 @@ class UserRepositoryImpl implements UserRepository { @override Future> signIn(params) async { - return await _authenticate(() { - return remoteDataSource.signIn(params); - }); + if (!await networkInfo.isConnected) { + return Left(NetworkFailure()); + } + try { + final remoteResponse = await remoteDataSource.signIn(params); + await localDataSource.saveToken(remoteResponse.token); + await localDataSource.saveUser(remoteResponse.user); + return Right(remoteResponse.user); + } on Failure catch (failure) { + return Left(failure); + } } @override Future> signUp(params) async { - return await _authenticate(() { - return remoteDataSource.signUp(params); - }); - } - - @override - Future> getCachedUser() async { + if (!await networkInfo.isConnected) { + return Left(NetworkFailure()); + } try { - final user = await localDataSource.getUser(); - return Right(user); - } on CacheFailure { - return Left(CacheFailure()); + final remoteResponse = await remoteDataSource.signUp(params); + await localDataSource.saveToken(remoteResponse.token); + await localDataSource.saveUser(remoteResponse.user); + return Right(remoteResponse.user); + } on Failure catch (failure) { + return Left(failure); } } @@ -56,21 +60,13 @@ class UserRepositoryImpl implements UserRepository { } } - Future> _authenticate( - _DataSourceChooser getDataSource, - ) async { - if (await networkInfo.isConnected) { - try { - final remoteResponse = await getDataSource(); - localDataSource.saveToken(remoteResponse.token); - localDataSource.saveUser(remoteResponse.user); - return Right(remoteResponse.user); - } on Failure catch (failure) { - return Left(failure); - } - } else { - return Left(NetworkFailure()); + @override + Future> getLocalUser() async { + try { + final user = await localDataSource.getUser(); + return Right(user); + } on CacheFailure { + return Left(CacheFailure()); } } - } diff --git a/lib/domain/entities/cart/cart.dart b/lib/domain/entities/cart/cart.dart index 2c5e8fd..b9d9951 100644 --- a/lib/domain/entities/cart/cart.dart +++ b/lib/domain/entities/cart/cart.dart @@ -1,7 +1,11 @@ -import 'cart_item.dart'; +import 'package:equatable/equatable.dart'; +import 'package:eshop/domain/entities/cart/cart_item.dart'; -class Cart { +class Cart extends Equatable { final List items; - Cart({required this.items}); + const Cart({required this.items}); + + @override + List get props => [items]; } diff --git a/lib/domain/entities/cart/cart_item.dart b/lib/domain/entities/cart/cart_item.dart index 49999ff..f51707d 100644 --- a/lib/domain/entities/cart/cart_item.dart +++ b/lib/domain/entities/cart/cart_item.dart @@ -1,15 +1,18 @@ import 'package:equatable/equatable.dart'; - -import '../product/price_tag.dart'; -import '../product/product.dart'; +import 'package:eshop/domain/entities/product/price_tag.dart'; +import 'package:eshop/domain/entities/product/product.dart'; class CartItem extends Equatable { final String? id; final Product product; final PriceTag priceTag; - const CartItem({this.id, required this.product, required this.priceTag}); + const CartItem({ + this.id, + required this.product, + required this.priceTag, + }); @override - List get props => [id]; + List get props => [id, product, priceTag]; } diff --git a/lib/domain/entities/category/category.dart b/lib/domain/entities/category/category.dart index f5502d4..17d229d 100644 --- a/lib/domain/entities/category/category.dart +++ b/lib/domain/entities/category/category.dart @@ -12,5 +12,5 @@ class Category extends Equatable { }); @override - List get props => [id]; + List get props => [id, name, image]; } diff --git a/lib/domain/entities/category/category_response.dart b/lib/domain/entities/category/category_response.dart index 6865923..6446a22 100644 --- a/lib/domain/entities/category/category_response.dart +++ b/lib/domain/entities/category/category_response.dart @@ -1,7 +1,11 @@ -import 'category.dart'; +import 'package:equatable/equatable.dart'; +import 'package:eshop/domain/entities/category/category.dart'; -class CategoryResponse { +class CategoryResponse extends Equatable { final List categories; - CategoryResponse({required this.categories}); + const CategoryResponse({required this.categories}); + + @override + List get props => [categories]; } diff --git a/lib/domain/entities/order/order_details.dart b/lib/domain/entities/order/order_details.dart index 8484ab6..7bf0366 100644 --- a/lib/domain/entities/order/order_details.dart +++ b/lib/domain/entities/order/order_details.dart @@ -1,7 +1,6 @@ import 'package:equatable/equatable.dart'; - -import '../user/delivery_info.dart'; -import 'order_item.dart'; +import 'package:eshop/domain/entities/order/order_item.dart'; +import 'package:eshop/domain/entities/user/delivery_info.dart'; class OrderDetails extends Equatable { final String id; @@ -19,5 +18,8 @@ class OrderDetails extends Equatable { @override List get props => [ id, + orderItems, + deliveryInfo, + discount, ]; } diff --git a/lib/domain/entities/order/order_item.dart b/lib/domain/entities/order/order_item.dart index 54d94e1..57287b4 100644 --- a/lib/domain/entities/order/order_item.dart +++ b/lib/domain/entities/order/order_item.dart @@ -1,7 +1,6 @@ import 'package:equatable/equatable.dart'; - -import '../product/price_tag.dart'; -import '../product/product.dart'; +import 'package:eshop/domain/entities/product/price_tag.dart'; +import 'package:eshop/domain/entities/product/product.dart'; class OrderItem extends Equatable { final String id; @@ -21,5 +20,9 @@ class OrderItem extends Equatable { @override List get props => [ id, + product, + priceTag, + price, + quantity, ]; } diff --git a/lib/domain/entities/product/pagination_meta_data.dart b/lib/domain/entities/product/pagination_meta_data.dart index 9d683a1..477b2e0 100644 --- a/lib/domain/entities/product/pagination_meta_data.dart +++ b/lib/domain/entities/product/pagination_meta_data.dart @@ -1,12 +1,20 @@ -class PaginationMetaData { +import 'package:equatable/equatable.dart'; + +class PaginationMetaData extends Equatable { final int limit; final int pageSize; final int total; - PaginationMetaData({ + const PaginationMetaData({ required this.limit, required this.pageSize, required this.total, }); + @override + List get props => [ + limit, + pageSize, + total, + ]; } \ No newline at end of file diff --git a/lib/domain/entities/product/price_tag.dart b/lib/domain/entities/product/price_tag.dart index 27b5e61..983b344 100644 --- a/lib/domain/entities/product/price_tag.dart +++ b/lib/domain/entities/product/price_tag.dart @@ -1,11 +1,20 @@ -class PriceTag { +import 'package:equatable/equatable.dart'; + +class PriceTag extends Equatable { final String id; final String name; final num price; - PriceTag({ + const PriceTag({ required this.id, required this.name, required this.price, }); + + @override + List get props => [ + id, + name, + price, + ]; } diff --git a/lib/domain/entities/product/product.dart b/lib/domain/entities/product/product.dart index 7cfe01b..b3e4eb7 100644 --- a/lib/domain/entities/product/product.dart +++ b/lib/domain/entities/product/product.dart @@ -1,7 +1,6 @@ import 'package:equatable/equatable.dart'; - -import '../category/category.dart'; -import 'price_tag.dart'; +import 'package:eshop/domain/entities/category/category.dart'; +import 'package:eshop/domain/entities/product/price_tag.dart'; class Product extends Equatable { final String id; @@ -25,5 +24,14 @@ class Product extends Equatable { }); @override - List get props => [id]; -} \ No newline at end of file + List get props => [ + id, + name, + description, + priceTags, + categories, + images, + createdAt, + updatedAt, + ]; +} diff --git a/lib/domain/entities/product/product_response.dart b/lib/domain/entities/product/product_response.dart index a5b12a6..a599c0e 100644 --- a/lib/domain/entities/product/product_response.dart +++ b/lib/domain/entities/product/product_response.dart @@ -1,9 +1,19 @@ -import 'pagination_meta_data.dart'; -import 'product.dart'; +import 'package:equatable/equatable.dart'; +import 'package:eshop/domain/entities/product/pagination_meta_data.dart'; +import 'package:eshop/domain/entities/product/product.dart'; -class ProductResponse { +class ProductResponse extends Equatable { final List products; final PaginationMetaData paginationMetaData; - ProductResponse({required this.products, required this.paginationMetaData}); -} \ No newline at end of file + const ProductResponse({ + required this.products, + required this.paginationMetaData, + }); + + @override + List get props => [ + products, + paginationMetaData, + ]; +} diff --git a/lib/domain/entities/user/delivery_info.dart b/lib/domain/entities/user/delivery_info.dart index 37c004f..8cbaea7 100644 --- a/lib/domain/entities/user/delivery_info.dart +++ b/lib/domain/entities/user/delivery_info.dart @@ -22,5 +22,14 @@ class DeliveryInfo extends Equatable { }); @override - List get props => [id]; + List get props => [ + id, + firstName, + lastName, + addressLineOne, + addressLineTwo, + city, + zipCode, + contactNumber, + ]; } diff --git a/lib/domain/entities/user/user.dart b/lib/domain/entities/user/user.dart index a53b15c..77c0411 100644 --- a/lib/domain/entities/user/user.dart +++ b/lib/domain/entities/user/user.dart @@ -16,10 +16,11 @@ class User extends Equatable { }); @override - List get props => [ - id, - firstName, - lastName, - email, - ]; -} \ No newline at end of file + List get props => [ + id, + firstName, + lastName, + email, + image, + ]; +} diff --git a/lib/domain/repositories/cart_repository.dart b/lib/domain/repositories/cart_repository.dart index 2b9658b..1d184ce 100644 --- a/lib/domain/repositories/cart_repository.dart +++ b/lib/domain/repositories/cart_repository.dart @@ -1,12 +1,14 @@ import 'package:dartz/dartz.dart'; +import 'package:eshop/core/usecases/usecase.dart'; import '../../../../core/error/failures.dart'; +import '../../data/models/cart/cart_item_model.dart'; import '../entities/cart/cart_item.dart'; abstract class CartRepository { - Future>> getCachedCart(); - Future>> syncCart(); - Future> addToCart(CartItem params); - Future> deleteFormCart(); - Future> clearCart(); -} \ No newline at end of file + Future>> getLocalCartItems(); + Future>> getRemoteCartItems(); + Future> addCartItem(CartItem params); + Future> deleteCartItem(CartItem params); + Future> deleteCart(); +} diff --git a/lib/domain/repositories/category_repository.dart b/lib/domain/repositories/category_repository.dart index 38b0553..37e737f 100644 --- a/lib/domain/repositories/category_repository.dart +++ b/lib/domain/repositories/category_repository.dart @@ -5,6 +5,6 @@ import '../entities/category/category.dart'; abstract class CategoryRepository { Future>> getRemoteCategories(); - Future>> getCachedCategories(); + Future>> getLocalCategories(); Future>> filterCachedCategories(String keyword); } diff --git a/lib/domain/repositories/delivery_info_repository.dart b/lib/domain/repositories/delivery_info_repository.dart index 22944e5..b2f5d0b 100644 --- a/lib/domain/repositories/delivery_info_repository.dart +++ b/lib/domain/repositories/delivery_info_repository.dart @@ -7,10 +7,10 @@ import '../entities/user/delivery_info.dart'; abstract class DeliveryInfoRepository { Future>> getRemoteDeliveryInfo(); - Future>> getCachedDeliveryInfo(); + Future>> getLocalDeliveryInfo(); Future> addDeliveryInfo(DeliveryInfoModel param); Future> editDeliveryInfo(DeliveryInfoModel param); Future> selectDeliveryInfo(DeliveryInfo param); Future> getSelectedDeliveryInfo(); - Future> clearLocalDeliveryInfo(); + Future> deleteLocalDeliveryInfo(); } diff --git a/lib/domain/repositories/order_repository.dart b/lib/domain/repositories/order_repository.dart index e4329b6..f929a31 100644 --- a/lib/domain/repositories/order_repository.dart +++ b/lib/domain/repositories/order_repository.dart @@ -7,6 +7,6 @@ import '../entities/order/order_details.dart'; abstract class OrderRepository { Future> addOrder(OrderDetails params); Future>> getRemoteOrders(); - Future>> getCachedOrders(); - Future> clearLocalOrders(); + Future>> getLocalOrders(); + Future> deleteLocalOrders(); } \ No newline at end of file diff --git a/lib/domain/repositories/product_repository.dart b/lib/domain/repositories/product_repository.dart index 66ab8c9..b987b44 100644 --- a/lib/domain/repositories/product_repository.dart +++ b/lib/domain/repositories/product_repository.dart @@ -5,5 +5,10 @@ import '../entities/product/product_response.dart'; import '../usecases/product/get_product_usecase.dart'; abstract class ProductRepository { - Future> getProducts(FilterProductParams params); -} \ No newline at end of file + Future> getRemoteProducts( + FilterProductParams params, + ); + Future> getLocalProducts( + FilterProductParams params, + ); +} diff --git a/lib/domain/repositories/user_repository.dart b/lib/domain/repositories/user_repository.dart index 4d2e915..e40e581 100644 --- a/lib/domain/repositories/user_repository.dart +++ b/lib/domain/repositories/user_repository.dart @@ -10,5 +10,5 @@ abstract class UserRepository { Future> signIn(SignInParams params); Future> signUp(SignUpParams params); Future> signOut(); - Future> getCachedUser(); + Future> getLocalUser(); } diff --git a/lib/domain/usecases/cart/add_cart_item_usecase.dart b/lib/domain/usecases/cart/add_cart_item_usecase.dart index 44f559e..0956eba 100644 --- a/lib/domain/usecases/cart/add_cart_item_usecase.dart +++ b/lib/domain/usecases/cart/add_cart_item_usecase.dart @@ -11,6 +11,6 @@ class AddCartUseCase implements UseCase { @override Future> call(CartItem params) async { - return await repository.addToCart(params); + return await repository.addCartItem(params); } } diff --git a/lib/domain/usecases/cart/clear_cart_usecase.dart b/lib/domain/usecases/cart/delete_cart_usecase.dart similarity index 53% rename from lib/domain/usecases/cart/clear_cart_usecase.dart rename to lib/domain/usecases/cart/delete_cart_usecase.dart index 56b2f5a..7c15183 100644 --- a/lib/domain/usecases/cart/clear_cart_usecase.dart +++ b/lib/domain/usecases/cart/delete_cart_usecase.dart @@ -4,12 +4,12 @@ import '../../../../../core/error/failures.dart'; import '../../../../../core/usecases/usecase.dart'; import '../../repositories/cart_repository.dart'; -class ClearCartUseCase implements UseCase { +class DeleteCartUseCase implements UseCase { final CartRepository repository; - ClearCartUseCase(this.repository); + DeleteCartUseCase(this.repository); @override - Future> call(NoParams params) async { - return await repository.clearCart(); + Future> call(NoParams params) async { + return await repository.deleteCart(); } } diff --git a/lib/domain/usecases/cart/get_cached_cart_usecase.dart b/lib/domain/usecases/cart/get_local_cart_items_usecase.dart similarity index 67% rename from lib/domain/usecases/cart/get_cached_cart_usecase.dart rename to lib/domain/usecases/cart/get_local_cart_items_usecase.dart index b6000d5..7a3991d 100644 --- a/lib/domain/usecases/cart/get_cached_cart_usecase.dart +++ b/lib/domain/usecases/cart/get_local_cart_items_usecase.dart @@ -5,12 +5,12 @@ import '../../../../../core/usecases/usecase.dart'; import '../../entities/cart/cart_item.dart'; import '../../repositories/cart_repository.dart'; -class GetCachedCartUseCase implements UseCase, NoParams> { +class GetLocalCartItemsUseCase implements UseCase, NoParams> { final CartRepository repository; - GetCachedCartUseCase(this.repository); + GetLocalCartItemsUseCase(this.repository); @override Future>> call(NoParams params) async { - return await repository.getCachedCart(); + return await repository.getLocalCartItems(); } } diff --git a/lib/domain/usecases/cart/sync_cart_usecase.dart b/lib/domain/usecases/cart/get_remote_cart_items_usecase.dart similarity index 67% rename from lib/domain/usecases/cart/sync_cart_usecase.dart rename to lib/domain/usecases/cart/get_remote_cart_items_usecase.dart index f2b374a..fdfcdfa 100644 --- a/lib/domain/usecases/cart/sync_cart_usecase.dart +++ b/lib/domain/usecases/cart/get_remote_cart_items_usecase.dart @@ -5,12 +5,12 @@ import '../../../../../core/usecases/usecase.dart'; import '../../entities/cart/cart_item.dart'; import '../../repositories/cart_repository.dart'; -class SyncCartUseCase implements UseCase, NoParams> { +class GetRemoteCardItemsUseCase implements UseCase, NoParams> { final CartRepository repository; - SyncCartUseCase(this.repository); + GetRemoteCardItemsUseCase(this.repository); @override Future>> call(NoParams params) async { - return await repository.syncCart(); + return await repository.getRemoteCartItems(); } } diff --git a/lib/domain/usecases/category/get_cached_category_usecase.dart b/lib/domain/usecases/category/get_local_category_usecase.dart similarity index 68% rename from lib/domain/usecases/category/get_cached_category_usecase.dart rename to lib/domain/usecases/category/get_local_category_usecase.dart index 56897f3..f5c9b9e 100644 --- a/lib/domain/usecases/category/get_cached_category_usecase.dart +++ b/lib/domain/usecases/category/get_local_category_usecase.dart @@ -5,12 +5,12 @@ import '../../../../../core/usecases/usecase.dart'; import '../../entities/category/category.dart'; import '../../repositories/category_repository.dart'; -class GetCachedCategoryUseCase implements UseCase, NoParams> { +class GetLocalCategoryUseCase implements UseCase, NoParams> { final CategoryRepository repository; - GetCachedCategoryUseCase(this.repository); + GetLocalCategoryUseCase(this.repository); @override Future>> call(NoParams params) async { - return await repository.getCachedCategories(); + return await repository.getLocalCategories(); } } diff --git a/lib/domain/usecases/delivery_info/clear_local_delivery_info_usecase.dart b/lib/domain/usecases/delivery_info/delete_local_delivery_info_usecase.dart similarity index 63% rename from lib/domain/usecases/delivery_info/clear_local_delivery_info_usecase.dart rename to lib/domain/usecases/delivery_info/delete_local_delivery_info_usecase.dart index 749e136..6135cd6 100644 --- a/lib/domain/usecases/delivery_info/clear_local_delivery_info_usecase.dart +++ b/lib/domain/usecases/delivery_info/delete_local_delivery_info_usecase.dart @@ -4,12 +4,12 @@ import '../../../core/error/failures.dart'; import '../../../core/usecases/usecase.dart'; import '../../repositories/delivery_info_repository.dart'; -class ClearLocalDeliveryInfoUseCase implements UseCase { +class DeleteLocalDeliveryInfoUseCase implements UseCase { final DeliveryInfoRepository repository; - ClearLocalDeliveryInfoUseCase(this.repository); + DeleteLocalDeliveryInfoUseCase(this.repository); @override Future> call(NoParams params) async { - return await repository.clearLocalDeliveryInfo(); + return await repository.deleteLocalDeliveryInfo(); } } diff --git a/lib/domain/usecases/delivery_info/get_cached_delivery_info_usecase.dart b/lib/domain/usecases/delivery_info/get_local_delivery_info_usecase.dart similarity index 66% rename from lib/domain/usecases/delivery_info/get_cached_delivery_info_usecase.dart rename to lib/domain/usecases/delivery_info/get_local_delivery_info_usecase.dart index a1295e2..bb9e3bb 100644 --- a/lib/domain/usecases/delivery_info/get_cached_delivery_info_usecase.dart +++ b/lib/domain/usecases/delivery_info/get_local_delivery_info_usecase.dart @@ -5,12 +5,12 @@ import '../../../core/usecases/usecase.dart'; import '../../entities/user/delivery_info.dart'; import '../../repositories/delivery_info_repository.dart'; -class GetCachedDeliveryInfoUseCase implements UseCase, NoParams> { +class GetLocalDeliveryInfoUseCase implements UseCase, NoParams> { final DeliveryInfoRepository repository; - GetCachedDeliveryInfoUseCase(this.repository); + GetLocalDeliveryInfoUseCase(this.repository); @override Future>> call(NoParams params) async { - return await repository.getCachedDeliveryInfo(); + return await repository.getLocalDeliveryInfo(); } } diff --git a/lib/domain/usecases/order/clear_local_order_usecase.dart b/lib/domain/usecases/order/delete_local_order_usecase.dart similarity index 64% rename from lib/domain/usecases/order/clear_local_order_usecase.dart rename to lib/domain/usecases/order/delete_local_order_usecase.dart index c1dc33d..f2a6283 100644 --- a/lib/domain/usecases/order/clear_local_order_usecase.dart +++ b/lib/domain/usecases/order/delete_local_order_usecase.dart @@ -4,12 +4,12 @@ import '../../../core/error/failures.dart'; import '../../../core/usecases/usecase.dart'; import '../../repositories/order_repository.dart'; -class ClearLocalOrdersUseCase implements UseCase { +class DeleteLocalOrdersUseCase implements UseCase { final OrderRepository repository; - ClearLocalOrdersUseCase(this.repository); + DeleteLocalOrdersUseCase(this.repository); @override Future> call(NoParams params) async { - return await repository.clearLocalOrders(); + return await repository.deleteLocalOrders(); } } diff --git a/lib/domain/usecases/order/get_cached_orders_usecase.dart b/lib/domain/usecases/order/get_local_orders_usecase.dart similarity index 67% rename from lib/domain/usecases/order/get_cached_orders_usecase.dart rename to lib/domain/usecases/order/get_local_orders_usecase.dart index 8fabc0d..75db538 100644 --- a/lib/domain/usecases/order/get_cached_orders_usecase.dart +++ b/lib/domain/usecases/order/get_local_orders_usecase.dart @@ -5,12 +5,12 @@ import '../../../core/usecases/usecase.dart'; import '../../entities/order/order_details.dart'; import '../../repositories/order_repository.dart'; -class GetCachedOrdersUseCase implements UseCase, NoParams> { +class GetLocalOrdersUseCase implements UseCase, NoParams> { final OrderRepository repository; - GetCachedOrdersUseCase(this.repository); + GetLocalOrdersUseCase(this.repository); @override Future>> call(NoParams params) async { - return await repository.getCachedOrders(); + return await repository.getLocalOrders(); } } diff --git a/lib/domain/usecases/product/get_product_usecase.dart b/lib/domain/usecases/product/get_product_usecase.dart index dfa29c4..3c721e7 100644 --- a/lib/domain/usecases/product/get_product_usecase.dart +++ b/lib/domain/usecases/product/get_product_usecase.dart @@ -14,7 +14,7 @@ class GetProductUseCase @override Future> call( FilterProductParams params) async { - return await repository.getProducts(params); + return await repository.getRemoteProducts(params); } } diff --git a/lib/domain/usecases/user/get_cached_user_usecase.dart b/lib/domain/usecases/user/get_local_user_usecase.dart similarity index 69% rename from lib/domain/usecases/user/get_cached_user_usecase.dart rename to lib/domain/usecases/user/get_local_user_usecase.dart index 8bc4c32..5f01225 100644 --- a/lib/domain/usecases/user/get_cached_user_usecase.dart +++ b/lib/domain/usecases/user/get_local_user_usecase.dart @@ -5,12 +5,12 @@ import '../../../../../core/usecases/usecase.dart'; import '../../entities/user/user.dart'; import '../../repositories/user_repository.dart'; -class GetCachedUserUseCase implements UseCase { +class GetLocalUserUseCase implements UseCase { final UserRepository repository; - GetCachedUserUseCase(this.repository); + GetLocalUserUseCase(this.repository); @override Future> call(NoParams params) async { - return await repository.getCachedUser(); + return await repository.getLocalUser(); } } diff --git a/lib/presentation/blocs/cart/cart_bloc.dart b/lib/presentation/blocs/cart/cart_bloc.dart index 1486c47..463a90c 100644 --- a/lib/presentation/blocs/cart/cart_bloc.dart +++ b/lib/presentation/blocs/cart/cart_bloc.dart @@ -5,18 +5,18 @@ import '../../../core/error/failures.dart'; import '../../../core/usecases/usecase.dart'; import '../../../domain/entities/cart/cart_item.dart'; import '../../../domain/usecases/cart/add_cart_item_usecase.dart'; -import '../../../domain/usecases/cart/clear_cart_usecase.dart'; -import '../../../domain/usecases/cart/get_cached_cart_usecase.dart'; -import '../../../domain/usecases/cart/sync_cart_usecase.dart'; +import '../../../domain/usecases/cart/delete_cart_usecase.dart'; +import '../../../domain/usecases/cart/get_local_cart_items_usecase.dart'; +import '../../../domain/usecases/cart/get_remote_cart_items_usecase.dart'; part 'cart_event.dart'; part 'cart_state.dart'; class CartBloc extends Bloc { - final GetCachedCartUseCase _getCachedCartUseCase; + final GetLocalCartItemsUseCase _getCachedCartUseCase; final AddCartUseCase _addCartUseCase; - final SyncCartUseCase _syncCartUseCase; - final ClearCartUseCase _clearCartUseCase; + final GetRemoteCardItemsUseCase _syncCartUseCase; + final DeleteCartUseCase _clearCartUseCase; CartBloc( this._getCachedCartUseCase, this._addCartUseCase, diff --git a/lib/presentation/blocs/category/category_bloc.dart b/lib/presentation/blocs/category/category_bloc.dart index f2d3252..52f9c93 100644 --- a/lib/presentation/blocs/category/category_bloc.dart +++ b/lib/presentation/blocs/category/category_bloc.dart @@ -6,7 +6,7 @@ import '../../../core/error/failures.dart'; import '../../../core/usecases/usecase.dart'; import '../../../domain/entities/category/category.dart'; import '../../../domain/usecases/category/filter_category_usecase.dart'; -import '../../../domain/usecases/category/get_cached_category_usecase.dart'; +import '../../../domain/usecases/category/get_local_category_usecase.dart'; import '../../../domain/usecases/category/get_remote_category_usecase.dart'; part 'category_event.dart'; @@ -14,7 +14,7 @@ part 'category_state.dart'; class CategoryBloc extends Bloc { final GetRemoteCategoryUseCase _getCategoryUseCase; - final GetCachedCategoryUseCase _getCashedCategoryUseCase; + final GetLocalCategoryUseCase _getCashedCategoryUseCase; final FilterCategoryUseCase _filterCategoryUseCase; CategoryBloc(this._getCategoryUseCase, this._getCashedCategoryUseCase, diff --git a/lib/presentation/blocs/delivery_info/delivery_info_fetch/delivery_info_fetch_cubit.dart b/lib/presentation/blocs/delivery_info/delivery_info_fetch/delivery_info_fetch_cubit.dart index b4d385e..d533e00 100644 --- a/lib/presentation/blocs/delivery_info/delivery_info_fetch/delivery_info_fetch_cubit.dart +++ b/lib/presentation/blocs/delivery_info/delivery_info_fetch/delivery_info_fetch_cubit.dart @@ -1,20 +1,20 @@ import 'package:bloc/bloc.dart'; -import 'package:eshop/domain/usecases/delivery_info/clear_local_delivery_info_usecase.dart'; +import 'package:eshop/domain/usecases/delivery_info/delete_local_delivery_info_usecase.dart'; import 'package:eshop/domain/usecases/delivery_info/get_selected_delivery_info_usecase.dart'; import 'package:flutter/cupertino.dart'; import '../../../../core/usecases/usecase.dart'; import '../../../../domain/entities/user/delivery_info.dart'; -import '../../../../domain/usecases/delivery_info/get_cached_delivery_info_usecase.dart'; +import '../../../../domain/usecases/delivery_info/get_local_delivery_info_usecase.dart'; import '../../../../domain/usecases/delivery_info/get_remote_delivery_info_usecase.dart'; part 'delivery_info_fetch_state.dart'; class DeliveryInfoFetchCubit extends Cubit { final GetRemoteDeliveryInfoUseCase _getRemoteDeliveryInfoUseCase; - final GetCachedDeliveryInfoUseCase _getCachedDeliveryInfoUseCase; + final GetLocalDeliveryInfoUseCase _getCachedDeliveryInfoUseCase; final GetSelectedDeliveryInfoInfoUseCase _getSelectedDeliveryInfoInfoUseCase; - final ClearLocalDeliveryInfoUseCase _clearLocalDeliveryInfoUseCase; + final DeleteLocalDeliveryInfoUseCase _clearLocalDeliveryInfoUseCase; DeliveryInfoFetchCubit( this._getRemoteDeliveryInfoUseCase, this._getCachedDeliveryInfoUseCase, diff --git a/lib/presentation/blocs/order/order_fetch/order_fetch_cubit.dart b/lib/presentation/blocs/order/order_fetch/order_fetch_cubit.dart index cc196a3..e0769be 100644 --- a/lib/presentation/blocs/order/order_fetch/order_fetch_cubit.dart +++ b/lib/presentation/blocs/order/order_fetch/order_fetch_cubit.dart @@ -1,18 +1,18 @@ import 'package:bloc/bloc.dart'; -import 'package:eshop/domain/usecases/order/clear_local_order_usecase.dart'; +import 'package:eshop/domain/usecases/order/delete_local_order_usecase.dart'; import 'package:flutter/cupertino.dart'; import '../../../../core/usecases/usecase.dart'; import '../../../../domain/entities/order/order_details.dart'; -import '../../../../domain/usecases/order/get_cached_orders_usecase.dart'; +import '../../../../domain/usecases/order/get_local_orders_usecase.dart'; import '../../../../domain/usecases/order/get_remote_orders_usecase.dart'; part 'order_fetch_state.dart'; class OrderFetchCubit extends Cubit { final GetRemoteOrdersUseCase _getOrdersUseCase; - final GetCachedOrdersUseCase _getCachedOrdersUseCase; - final ClearLocalOrdersUseCase _clearLocalOrdersUseCase; + final GetLocalOrdersUseCase _getCachedOrdersUseCase; + final DeleteLocalOrdersUseCase _clearLocalOrdersUseCase; OrderFetchCubit(this._getOrdersUseCase, this._getCachedOrdersUseCase, this._clearLocalOrdersUseCase) : super(const OrderFetchInitial([])); diff --git a/lib/presentation/blocs/user/user_bloc.dart b/lib/presentation/blocs/user/user_bloc.dart index 2c4a51e..e2f58ed 100644 --- a/lib/presentation/blocs/user/user_bloc.dart +++ b/lib/presentation/blocs/user/user_bloc.dart @@ -9,14 +9,14 @@ import 'package:flutter/cupertino.dart'; import '../../../core/error/failures.dart'; import '../../../core/usecases/usecase.dart'; import '../../../domain/entities/user/user.dart'; -import '../../../domain/usecases/user/get_cached_user_usecase.dart'; +import '../../../domain/usecases/user/get_local_user_usecase.dart'; import '../../../domain/usecases/user/sign_in_usecase.dart'; part 'user_event.dart'; part 'user_state.dart'; class UserBloc extends Bloc { - final GetCachedUserUseCase _getCachedUserUseCase; + final GetLocalUserUseCase _getCachedUserUseCase; final SignInUseCase _signInUseCase; final SignUpUseCase _signUpUseCase; final SignOutUseCase _signOutUseCase; diff --git a/lib/presentation/views/authentication/signin_view.dart b/lib/presentation/views/authentication/signin_view.dart index 3066117..10f4188 100644 --- a/lib/presentation/views/authentication/signin_view.dart +++ b/lib/presentation/views/authentication/signin_view.dart @@ -1,5 +1,4 @@ -import 'package:eshop/presentation/blocs/home/navbar_cubit.dart'; -import 'package:eshop/presentation/blocs/order/order_fetch/order_fetch_cubit.dart'; +import 'package:eshop/core/constant/validators.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; @@ -10,6 +9,8 @@ import '../../../core/router/app_router.dart'; import '../../../domain/usecases/user/sign_in_usecase.dart'; import '../../blocs/cart/cart_bloc.dart'; import '../../blocs/delivery_info/delivery_info_fetch/delivery_info_fetch_cubit.dart'; +import '../../blocs/home/navbar_cubit.dart'; +import '../../blocs/order/order_fetch/order_fetch_cubit.dart'; import '../../blocs/user/user_bloc.dart'; import '../../widgets/input_form_button.dart'; import '../../widgets/input_text_form_field.dart'; @@ -87,12 +88,8 @@ class _SignInViewState extends State { controller: emailController, textInputAction: TextInputAction.next, hint: 'Email', - validation: (String? val) { - if (val == null || val.isEmpty) { - return 'This field can\'t be empty'; - } - return null; - }, + validation: (String? val) => + Validators.validateField(val, "Email"), ), const SizedBox( height: 12, @@ -102,20 +99,9 @@ class _SignInViewState extends State { textInputAction: TextInputAction.go, hint: 'Password', isSecureField: true, - validation: (String? val) { - if (val == null || val.isEmpty) { - return 'This field can\'t be empty'; - } - return null; - }, - onFieldSubmitted: (_) { - if (_formKey.currentState!.validate()) { - context.read().add(SignInUser(SignInParams( - username: emailController.text, - password: passwordController.text, - ))); - } - }, + validation: (String? val) => + Validators.validateField(val, "Password"), + onFieldSubmitted: (_) => _onSignIn(context), ), const SizedBox( height: 10, @@ -139,14 +125,7 @@ class _SignInViewState extends State { ), InputFormButton( color: Colors.black87, - onClick: () { - if (_formKey.currentState!.validate()) { - context.read().add(SignInUser(SignInParams( - username: emailController.text, - password: passwordController.text, - ))); - } - }, + onClick: () => _onSignIn(context), titleText: 'Sign In', ), const SizedBox( @@ -195,4 +174,15 @@ class _SignInViewState extends State { ), ); } -} + + void _onSignIn(BuildContext context) { + if (_formKey.currentState!.validate()) { + context.read().add( + SignInUser(SignInParams( + username: emailController.text, + password: passwordController.text, + )), + ); + } + } +} \ No newline at end of file diff --git a/lib/presentation/views/authentication/signup_view.dart b/lib/presentation/views/authentication/signup_view.dart index 32eddba..553ea9e 100644 --- a/lib/presentation/views/authentication/signup_view.dart +++ b/lib/presentation/views/authentication/signup_view.dart @@ -1,8 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; +import 'package:sizer/sizer.dart'; +import '../../../core/constant/app_sizes.dart'; import '../../../core/constant/images.dart'; +import '../../../core/constant/validators.dart'; import '../../../core/error/failures.dart'; import '../../../core/router/app_router.dart'; import '../../../domain/usecases/user/sign_up_usecase.dart'; @@ -19,11 +22,11 @@ class SignUpScreen extends StatefulWidget { } class _SignUpScreenState extends State { - final TextEditingController firstNameController = TextEditingController(); - final TextEditingController lastNameController = TextEditingController(); - final TextEditingController emailController = TextEditingController(); - final TextEditingController passwordController = TextEditingController(); - final TextEditingController confirmPasswordController = + final TextEditingController _firstNameController = TextEditingController(); + final TextEditingController _lastNameController = TextEditingController(); + final TextEditingController _emailController = TextEditingController(); + final TextEditingController _passwordController = TextEditingController(); + final TextEditingController _confirmPasswordController = TextEditingController(); final _formKey = GlobalKey(); @@ -38,22 +41,24 @@ class _SignUpScreenState extends State { context.read().add(const GetCart()); Navigator.of(context).pushNamedAndRemoveUntil( AppRouter.home, - ModalRoute.withName(''), + (Route route) => false, ); } else if (state is UserLoggedFail) { + String errorMessage = "An error occurred. Please try again."; if (state.failure is CredentialFailure) { - EasyLoading.showError("Username/Password Wrong!"); - } else { - EasyLoading.showError("Error"); + errorMessage = "Incorrect username or password."; + } else if (state.failure is NetworkFailure) { + errorMessage = "Network error. Check your connection."; } + EasyLoading.showError(errorMessage); } }, child: Scaffold( body: SingleChildScrollView( - physics: const BouncingScrollPhysics(), + physics: const BouncingScrollPhysics(), child: SafeArea( child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20), + padding: const EdgeInsets.symmetric(horizontal: kPaddingMedium), child: Form( key: _formKey, child: Column( @@ -69,118 +74,74 @@ class _SignUpScreenState extends State { color: Colors.black, )), const SizedBox( - height: 20, + height: 10, ), const Text( "Please use your e-mail address to crate a new account", style: TextStyle(fontSize: 16, color: Colors.grey), textAlign: TextAlign.center, ), - const SizedBox( - height: 40, + SizedBox( + height: 6.h, ), InputTextFormField( - controller: firstNameController, + controller: _firstNameController, hint: 'First Name', textInputAction: TextInputAction.next, - validation: (String? val) { - if (val == null || val.isEmpty) { - return 'This field can\'t be empty'; - } - return null; - }, + validation: (String? val) => + Validators.validateField(val, "First name"), ), const SizedBox( height: 12, ), InputTextFormField( - controller: lastNameController, + controller: _lastNameController, hint: 'Last Name', textInputAction: TextInputAction.next, - validation: (String? val) { - if (val == null || val.isEmpty) { - return 'This field can\'t be empty'; - } - return null; - }, + validation: (String? val) => + Validators.validateField(val, "Last name"), ), const SizedBox( height: 12, ), InputTextFormField( - controller: emailController, + controller: _emailController, hint: 'Email', textInputAction: TextInputAction.next, - validation: (String? val) { - if (val == null || val.isEmpty) { - return 'This field can\'t be empty'; - } - return null; - }, + validation: (String? val) => Validators.validateEmail(val), ), const SizedBox( height: 12, ), InputTextFormField( - controller: passwordController, + controller: _passwordController, hint: 'Password', textInputAction: TextInputAction.next, isSecureField: true, - validation: (String? val) { - if (val == null || val.isEmpty) { - return 'This field can\'t be empty'; - } - return null; - }, + validation: (String? val) => + Validators.validateField(val, "Password"), ), const SizedBox( height: 12, ), InputTextFormField( - controller: confirmPasswordController, + controller: _confirmPasswordController, hint: 'Confirm Password', isSecureField: true, textInputAction: TextInputAction.go, - validation: (String? val) { - if (val == null || val.isEmpty) { - return 'This field can\'t be empty'; - } - return null; - }, - onFieldSubmitted: (_) { - if (_formKey.currentState!.validate()) { - if (passwordController.text != - confirmPasswordController.text) { - } else { - context.read().add(SignUpUser(SignUpParams( - firstName: firstNameController.text, - lastName: lastNameController.text, - email: emailController.text, - password: passwordController.text, - ))); - } - } - }, + validation: (String? val) => + Validators.validatePasswordMatch( + val, + _passwordController.text, + ), + onFieldSubmitted: (_) => _onSignUp(context), ), const SizedBox( - height: 40, + height: 24, ), InputFormButton( color: Colors.black87, - onClick: () { - if (_formKey.currentState!.validate()) { - if (passwordController.text != - confirmPasswordController.text) { - } else { - context.read().add(SignUpUser(SignUpParams( - firstName: firstNameController.text, - lastName: lastNameController.text, - email: emailController.text, - password: passwordController.text, - ))); - } - } - }, + onClick: () => _onSignUp(context), titleText: 'Sign Up', ), const SizedBox( @@ -204,4 +165,19 @@ class _SignUpScreenState extends State { )), ); } + + void _onSignUp(BuildContext context) { + if (_formKey.currentState!.validate()) { + if (_passwordController.text != _confirmPasswordController.text) { + EasyLoading.showError("Passwords do not match!"); + return; + } + context.read().add(SignUpUser(SignUpParams( + firstName: _firstNameController.text, + lastName: _lastNameController.text, + email: _emailController.text, + password: _passwordController.text, + ))); + } + } } diff --git a/lib/presentation/views/main/home/home_view.dart b/lib/presentation/views/main/home/home_view.dart index a911058..5991948 100644 --- a/lib/presentation/views/main/home/home_view.dart +++ b/lib/presentation/views/main/home/home_view.dart @@ -58,7 +58,8 @@ class _HomeViewState extends State { ), Padding( padding: const EdgeInsets.symmetric(horizontal: 20), - child: BlocBuilder(builder: (context, state) { + child: BlocBuilder( + builder: (context, state) { if (state is UserLogged) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 6), @@ -85,18 +86,19 @@ class _HomeViewState extends State { }, child: state.user.image != null ? CachedNetworkImage( - imageUrl: state.user.image!, - imageBuilder: (context, image) => CircleAvatar( - radius: 18.sp, - backgroundImage: image, - backgroundColor: Colors.transparent, - ), - ) + imageUrl: state.user.image!, + imageBuilder: (context, image) => + CircleAvatar( + radius: 18.sp, + backgroundImage: image, + backgroundColor: Colors.transparent, + ), + ) : CircleAvatar( - radius: 18.sp, - backgroundImage: AssetImage(kUserAvatar), - backgroundColor: Colors.transparent, - ), + radius: 18.sp, + backgroundImage: AssetImage(kUserAvatar), + backgroundColor: Colors.transparent, + ), ) ], ), @@ -106,7 +108,7 @@ class _HomeViewState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Column( + Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( @@ -115,12 +117,16 @@ class _HomeViewState extends State { Text( "Welcome,", style: TextStyle( - fontWeight: FontWeight.bold, fontSize: 36), + fontWeight: FontWeight.bold, + fontSize: 24.sp, + ), ), Text( "E-Shop mobile store", style: TextStyle( - fontWeight: FontWeight.normal, fontSize: 22), + fontWeight: FontWeight.normal, + fontSize: 18.sp, + ), ), ], ), @@ -156,10 +162,12 @@ class _HomeViewState extends State { return TextField( autofocus: false, controller: - context.read().searchController, + context.read().searchController, onChanged: (val) => setState(() {}), - onSubmitted: (val) => context.read().add( - GetProducts(FilterProductParams(keyword: val))), + onSubmitted: (val) => context + .read() + .add(GetProducts( + FilterProductParams(keyword: val))), decoration: InputDecoration( contentPadding: EdgeInsets.only( left: 16.sp, @@ -171,24 +179,25 @@ class _HomeViewState extends State { child: Icon(Icons.search), ), suffixIcon: context - .read() - .searchController - .text - .isNotEmpty + .read() + .searchController + .text + .isNotEmpty ? Padding( - padding: const EdgeInsets.only(right: 8), - child: IconButton( - onPressed: () { - context - .read() - .searchController - .clear(); - context - .read() - .update(keyword: ''); - }, - icon: const Icon(Icons.clear)), - ) + padding: + const EdgeInsets.only(right: 8), + child: IconButton( + onPressed: () { + context + .read() + .searchController + .clear(); + context + .read() + .update(keyword: ''); + }, + icon: const Icon(Icons.clear)), + ) : null, border: const OutlineInputBorder(), hintText: "Search Product", @@ -197,7 +206,8 @@ class _HomeViewState extends State { focusedBorder: OutlineInputBorder( borderSide: const BorderSide( color: Colors.white, width: 3.0), - borderRadius: BorderRadius.circular(16.sp)), + borderRadius: + BorderRadius.circular(16.sp)), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16.sp), borderSide: const BorderSide( @@ -225,13 +235,16 @@ class _HomeViewState extends State { .toString(), style: const TextStyle(color: Colors.black87), ), - isLabelVisible: - context.read().getFiltersCount() != 0, + isLabelVisible: context + .read() + .getFiltersCount() != + 0, backgroundColor: Theme.of(context).primaryColor, child: InputFormButton( color: Colors.black87, onClick: () { - Navigator.of(context).pushNamed(AppRouter.filter); + Navigator.of(context) + .pushNamed(AppRouter.filter); }, ), ); @@ -241,7 +254,9 @@ class _HomeViewState extends State { ], ), ), - SizedBox(height: 1.h,) + SizedBox( + height: 1.h, + ) ], ), ), diff --git a/lib/presentation/views/main/other/notification/notification_view.dart b/lib/presentation/views/main/other/notification/notification_view.dart index a57e56d..eebd3ac 100644 --- a/lib/presentation/views/main/other/notification/notification_view.dart +++ b/lib/presentation/views/main/other/notification/notification_view.dart @@ -1,3 +1,4 @@ +import 'package:eshop/presentation/views/main/other/notification/widgets/notification_card.dart'; import 'package:flutter/material.dart'; class NotificationView extends StatelessWidget { @@ -9,6 +10,13 @@ class NotificationView extends StatelessWidget { appBar: AppBar( title: const Text("Notifications"), ), + body: ListView.builder( + itemCount: 10, + padding: const EdgeInsets.all(16), + itemBuilder: (context, index) { + return NotificationCard(); + }, + ), ); } } diff --git a/lib/presentation/views/main/other/notification/widgets/notification_card.dart b/lib/presentation/views/main/other/notification/widgets/notification_card.dart new file mode 100644 index 0000000..de54211 --- /dev/null +++ b/lib/presentation/views/main/other/notification/widgets/notification_card.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; + +class NotificationCard extends StatelessWidget { + const NotificationCard({super.key}); + + @override + Widget build(BuildContext context) { + return Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: ListTile( + leading: const Icon(Icons.notifications), + title: const Text("Notification Title"), + subtitle: const Text("This is the notification message."), + trailing: const Icon(Icons.arrow_forward_ios), + onTap: () { + // Handle tap + }, + ), + ); + } +} diff --git a/test/data/datasources/local/cart_local_data_source_test.dart b/test/data/datasources/local/cart_local_data_source_test.dart index 71115c3..c131404 100644 --- a/test/data/datasources/local/cart_local_data_source_test.dart +++ b/test/data/datasources/local/cart_local_data_source_test.dart @@ -85,7 +85,7 @@ void main() { .thenAnswer((_) async => true); /// Act - final result = await dataSource.clearCart(); + final result = await dataSource.deleteCart(); /// Assert expect(result, isTrue); diff --git a/test/data/models/order/order_details_model_test.dart b/test/data/models/order/order_details_model_test.dart index baace5c..218a156 100644 --- a/test/data/models/order/order_details_model_test.dart +++ b/test/data/models/order/order_details_model_test.dart @@ -18,9 +18,7 @@ void main() { group('fromJson', () { test( - '''Should successfully deserialize a JSON map into a OrderDetailsMap - object and ensure that the resulting - object matches the expected tOrderDetails''', + 'Should successfully deserialize a JSON map into an OrderDetailsModel and match expected result', () async { /// Arrange final Map jsonMap = diff --git a/test/data/models/product/product_model_test.dart b/test/data/models/product/product_model_test.dart index 7bb89cf..8eb3a11 100644 --- a/test/data/models/product/product_model_test.dart +++ b/test/data/models/product/product_model_test.dart @@ -61,19 +61,36 @@ void main() { /// Assert final expectedMap = { - '_id': '1', - 'name': 'name', - 'description': 'description', - 'priceTags': [ - {'_id': '1', 'name': 'name', 'price': 100} + "_id": "64eb722a41cb9b05eb4420b7", + "name": "Asus Gaming Mouse", + "description": "Text description", + "priceTags": [ + { + "_id": "64eb728341cb9b05eb4420ba", + "name": "White", + "price": 50.99 + } ], - 'categories': [ - {'_id': '1', 'name': 'name', 'image': 'image'} + "categories": [ + { + "_id": "64cecb613357eaec7b1ab31b", + "name": "Headphone", + "image": "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg" + } ], - 'images': ['image'], - 'createdAt': '2000-01-01T00:00:00.000', - 'updatedAt': '2000-01-01T00:00:00.000' + "images": [ + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vxyyemcdwcuoooyejehj.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vqiw6cswpnzhgryd3s1l.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/tkanjwktt2t0qvybk5xf.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/yjxkgevogpaim02wonks.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/m2bb9pzzobynrpyo9ike.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/xhojjofgfyfpbjwo2vox.jpg" + ], + "createdAt": "2023-08-27T15:56:26.504Z", + "updatedAt": "2023-08-27T16:19:16.683Z" }; + + /// Assert expect(result, expectedMap); }, ); diff --git a/test/data/repositories/cart_repository_impl_test.dart b/test/data/repositories/cart_repository_impl_test.dart index ca98cc4..87866bc 100644 --- a/test/data/repositories/cart_repository_impl_test.dart +++ b/test/data/repositories/cart_repository_impl_test.dart @@ -75,7 +75,7 @@ void main() { .thenAnswer((invocation) => Future.value()); /// Act - repository.syncCart(); + repository.getRemoteCartItems(); /// Assert verify(() => mockNetworkInfo.isConnected); @@ -101,7 +101,7 @@ void main() { .thenAnswer((invocation) => Future.value()); /// Act - final actualResult = await repository.syncCart(); + final actualResult = await repository.getRemoteCartItems(); /// Assert actualResult.fold( @@ -127,7 +127,7 @@ void main() { .thenAnswer((invocation) => Future.value()); /// Act - await repository.syncCart(); + await repository.getRemoteCartItems(); /// Assert verify(() => mockLocalDataSource.saveCart([tCartItemModel])); @@ -150,7 +150,7 @@ void main() { .thenAnswer((invocation) => Future.value()); /// Act - final result = await repository.syncCart(); + final result = await repository.getRemoteCartItems(); /// Assert result.fold( @@ -175,7 +175,7 @@ void main() { .thenAnswer((invocation) => Future.value()); /// Act - final result = await repository.syncCart(); + final result = await repository.getRemoteCartItems(); /// Assert result.fold( @@ -195,7 +195,7 @@ void main() { .thenAnswer((_) async => [tCartItemModel]); /// Act - final actualResult = await repository.getCachedCart(); + final actualResult = await repository.getLocalCartItems(); /// Assert actualResult.fold( @@ -212,7 +212,7 @@ void main() { when(() => mockLocalDataSource.getCart()).thenThrow(CacheFailure()); /// Act - final actualResult = await repository.getCachedCart(); + final actualResult = await repository.getLocalCartItems(); /// Assert actualResult.fold( @@ -237,7 +237,7 @@ void main() { .thenAnswer((invocation) => Future.value()); /// Act - final actualResult = await repository.addToCart(tCartItemModel); + final actualResult = await repository.addCartItem(tCartItemModel); /// Assert actualResult.fold( @@ -253,7 +253,7 @@ void main() { 'should return last locally cached data when the cached data is present', () async { /// Act - final result = await repository.syncCart(); + final result = await repository.getRemoteCartItems(); /// Assert verifyZeroInteractions(mockRemoteDataSource); @@ -273,7 +273,7 @@ void main() { .thenAnswer((_) async => [tCartItemModel]); /// Act - final actualResult = await repository.getCachedCart(); + final actualResult = await repository.getLocalCartItems(); /// Assert actualResult.fold( @@ -290,7 +290,7 @@ void main() { when(() => mockLocalDataSource.getCart()).thenThrow(CacheFailure()); /// Act - final actualResult = await repository.getCachedCart(); + final actualResult = await repository.getLocalCartItems(); /// Assert actualResult.fold( diff --git a/test/data/repositories/category_repository_impl_test.dart b/test/data/repositories/category_repository_impl_test.dart index 904fe9d..598fdca 100644 --- a/test/data/repositories/category_repository_impl_test.dart +++ b/test/data/repositories/category_repository_impl_test.dart @@ -138,7 +138,7 @@ void main() { .thenAnswer((_) async => [tCategoryModel]); /// Act - final actualResult = await repository.getCachedCategories(); + final actualResult = await repository.getLocalCategories(); /// Assert actualResult.fold( @@ -156,7 +156,7 @@ void main() { .thenThrow(CacheFailure()); /// Act - final actualResult = await repository.getCachedCategories(); + final actualResult = await repository.getLocalCategories(); /// Assert actualResult.fold( @@ -192,7 +192,7 @@ void main() { .thenAnswer((_) async => [tCategoryModel]); /// Act - final actualResult = await repository.getCachedCategories(); + final actualResult = await repository.getLocalCategories(); /// Assert actualResult.fold( @@ -210,7 +210,7 @@ void main() { .thenThrow(CacheFailure()); /// Act - final actualResult = await repository.getCachedCategories(); + final actualResult = await repository.getLocalCategories(); /// Assert actualResult.fold( diff --git a/test/data/repositories/delivery_info_impl_test.dart b/test/data/repositories/delivery_info_impl_test.dart index 53b15b0..60223e0 100644 --- a/test/data/repositories/delivery_info_impl_test.dart +++ b/test/data/repositories/delivery_info_impl_test.dart @@ -168,7 +168,7 @@ void main() { .thenAnswer((_) async => [tDeliveryInfoModel]); /// Act - final actualResult = await repository.getCachedDeliveryInfo(); + final actualResult = await repository.getLocalDeliveryInfo(); /// Assert actualResult.fold( @@ -186,7 +186,7 @@ void main() { .thenThrow(CacheFailure()); /// Act - final actualResult = await repository.getCachedDeliveryInfo(); + final actualResult = await repository.getLocalDeliveryInfo(); /// Assert actualResult.fold( @@ -411,7 +411,7 @@ void main() { .thenAnswer((_) => Future.value()); /// Act - final result = await repository.clearLocalDeliveryInfo(); + final result = await repository.deleteLocalDeliveryInfo(); /// Assert result.fold( @@ -429,7 +429,7 @@ void main() { .thenAnswer((_) => Future.value()); /// Act - await repository.clearLocalDeliveryInfo(); + await repository.deleteLocalDeliveryInfo(); /// Assert verify(() => mockLocalDataSource.clearDeliveryInfo()); @@ -444,7 +444,7 @@ void main() { .thenThrow(CacheFailure()); /// Act - final result = await repository.clearLocalDeliveryInfo(); + final result = await repository.deleteLocalDeliveryInfo(); /// Assert result.fold( @@ -467,7 +467,7 @@ void main() { .thenAnswer((_) async => [tDeliveryInfoModel]); /// Act - final result = await repository.getCachedDeliveryInfo(); + final result = await repository.getLocalDeliveryInfo(); /// Assert verifyZeroInteractions(mockRemoteDataSource); @@ -487,7 +487,7 @@ void main() { .thenAnswer((_) async => [tDeliveryInfoModel]); /// Act - final actualResult = await repository.getCachedDeliveryInfo(); + final actualResult = await repository.getLocalDeliveryInfo(); /// Assert actualResult.fold( @@ -505,7 +505,7 @@ void main() { .thenThrow(CacheFailure()); /// Act - final actualResult = await repository.getCachedDeliveryInfo(); + final actualResult = await repository.getLocalDeliveryInfo(); /// Assert actualResult.fold( diff --git a/test/data/repositories/order_repository_impl_test.dart b/test/data/repositories/order_repository_impl_test.dart index 69ee2c2..6644039 100644 --- a/test/data/repositories/order_repository_impl_test.dart +++ b/test/data/repositories/order_repository_impl_test.dart @@ -161,7 +161,7 @@ void main() { .thenAnswer((_) async => [tOrderDetailsModel]); /// Act - final actualResult = await repository.getCachedOrders(); + final actualResult = await repository.getLocalOrders(); /// Assert actualResult.fold( @@ -178,7 +178,7 @@ void main() { when(() => mockLocalDataSource.getOrders()).thenThrow(CacheFailure()); /// Act - final actualResult = await repository.getCachedOrders(); + final actualResult = await repository.getLocalOrders(); /// Assert actualResult.fold( @@ -214,7 +214,7 @@ void main() { .thenAnswer((_) async => [tOrderDetailsModel]); /// Act - final actualResult = await repository.getCachedOrders(); + final actualResult = await repository.getLocalOrders(); /// Assert actualResult.fold( @@ -231,7 +231,7 @@ void main() { when(() => mockLocalDataSource.getOrders()).thenThrow(CacheFailure()); /// Act - final actualResult = await repository.getCachedOrders(); + final actualResult = await repository.getLocalOrders(); /// Assert actualResult.fold( @@ -253,7 +253,7 @@ void main() { .thenAnswer((_) async => [tOrderDetailsModel]); /// Act - final result = await repository.getCachedOrders(); + final result = await repository.getLocalOrders(); /// Assert verify(() => mockLocalDataSource.getOrders()); @@ -271,7 +271,7 @@ void main() { when(() => mockLocalDataSource.getOrders()).thenThrow(CacheFailure()); /// Act - final result = await repository.getCachedOrders(); + final result = await repository.getLocalOrders(); /// Assert verify(() => mockLocalDataSource.getOrders()); @@ -292,7 +292,7 @@ void main() { .thenAnswer((_) async => [tOrderDetailsModel]); /// Act - final result = await repository.getCachedOrders(); + final result = await repository.getLocalOrders(); /// Assert verify(() => mockLocalDataSource.getOrders()); @@ -310,7 +310,7 @@ void main() { when(() => mockLocalDataSource.getOrders()).thenThrow(CacheFailure()); /// Act - final result = await repository.getCachedOrders(); + final result = await repository.getLocalOrders(); /// Assert verify(() => mockLocalDataSource.getOrders()); @@ -334,7 +334,7 @@ void main() { .thenAnswer((_) async => Future.value()); /// Act - final result = await repository.clearLocalOrders(); + final result = await repository.deleteLocalOrders(); /// Assert result.fold( @@ -352,7 +352,7 @@ void main() { .thenAnswer((_) async => Future.value()); /// Act - await repository.clearLocalOrders(); + await repository.deleteLocalOrders(); /// Assert verify(() => mockLocalDataSource.clearOrder()); @@ -367,7 +367,7 @@ void main() { CacheFailure()); /// Act - final result = await repository.clearLocalOrders(); + final result = await repository.deleteLocalOrders(); /// Assert result.fold( @@ -386,7 +386,7 @@ void main() { .thenAnswer((_) async => Future.value()); /// Act - final result = await repository.clearLocalOrders(); + final result = await repository.deleteLocalOrders(); /// Assert result.fold( @@ -404,7 +404,7 @@ void main() { .thenAnswer((_) async => Future.value()); /// Act - await repository.clearLocalOrders(); + await repository.deleteLocalOrders(); /// Assert verify(() => mockLocalDataSource.clearOrder()); @@ -419,7 +419,7 @@ void main() { CacheFailure()); /// Act - final result = await repository.clearLocalOrders(); + final result = await repository.deleteLocalOrders(); /// Assert result.fold( diff --git a/test/data/repositories/product_repository_impl_test.dart b/test/data/repositories/product_repository_impl_test.dart index 0a97df6..d79dbeb 100644 --- a/test/data/repositories/product_repository_impl_test.dart +++ b/test/data/repositories/product_repository_impl_test.dart @@ -86,7 +86,7 @@ void main() { /// Act final actualResult = - await repository.getProducts(const FilterProductParams()); + await repository.getRemoteProducts(const FilterProductParams()); /// Assert actualResult.fold( @@ -111,7 +111,7 @@ void main() { .thenAnswer((invocation) => Future.value()); /// Act - await repository.getProducts(const FilterProductParams()); + await repository.getRemoteProducts(const FilterProductParams()); /// Assert verify(() => @@ -130,7 +130,7 @@ void main() { /// Act final result = - await repository.getProducts(const FilterProductParams()); + await repository.getRemoteProducts(const FilterProductParams()); /// Assert verify(() => @@ -140,43 +140,5 @@ void main() { }, ); }); - - runTestsOffline(() { - test( - 'should return last locally cached data when the cached data is present', - () async { - /// Arrange - when(() => mockLocalDataSource.getLastProducts()) - .thenAnswer((_) async => tProductResponseModel); - - /// Act - final result = - await repository.getProducts(const FilterProductParams()); - - /// Assert - verifyZeroInteractions(mockRemoteDataSource); - verify(() => mockLocalDataSource.getLastProducts()); - expect(result, equals(Right(tProductResponseModel))); - }, - ); - - test( - 'should return CacheFailure when there is no cached data present', - () async { - /// Arrange - when(() => mockLocalDataSource.getLastProducts()) - .thenThrow(CacheException()); - - /// Act - final result = - await repository.getProducts(const FilterProductParams()); - - /// Assert - verifyZeroInteractions(mockRemoteDataSource); - verify(() => mockLocalDataSource.getLastProducts()); - expect(result, equals(Left(CacheFailure()))); - }, - ); - }); }); } diff --git a/test/data/repositories/user_repository_impl_test.dart b/test/data/repositories/user_repository_impl_test.dart index 57e3b69..5bced31 100644 --- a/test/data/repositories/user_repository_impl_test.dart +++ b/test/data/repositories/user_repository_impl_test.dart @@ -222,7 +222,7 @@ void main() { .thenAnswer((_) async => Future.value(tUserModel)); /// Act - final actualResult = await repository.getCachedUser(); + final actualResult = await repository.getLocalUser(); /// Assert actualResult.fold( @@ -239,7 +239,7 @@ void main() { when(() => mockLocalDataSource.getUser()).thenThrow(CacheFailure()); /// Act - final actualResult = await repository.getCachedUser(); + final actualResult = await repository.getLocalUser(); /// Assert actualResult.fold( @@ -291,7 +291,7 @@ void main() { .thenAnswer((_) async => Future.value(tUserModel)); /// Act - final actualResult = await repository.getCachedUser(); + final actualResult = await repository.getLocalUser(); /// Assert actualResult.fold( @@ -308,7 +308,7 @@ void main() { when(() => mockLocalDataSource.getUser()).thenThrow(CacheFailure()); /// Act - final actualResult = await repository.getCachedUser(); + final actualResult = await repository.getLocalUser(); /// Assert actualResult.fold( diff --git a/test/domain/usecases/cart/add_cart_item_usecase_test.dart b/test/domain/usecases/cart/add_cart_item_usecase_test.dart index 862dbb1..d1bd290 100644 --- a/test/domain/usecases/cart/add_cart_item_usecase_test.dart +++ b/test/domain/usecases/cart/add_cart_item_usecase_test.dart @@ -22,7 +22,7 @@ void main() { 'Should get cart item from the repository when Cart Repository add data successfully', () async { /// Arrange - when(() => mockProductRepository.addToCart(tCartItemModel)) + when(() => mockProductRepository.addCartItem(tCartItemModel)) .thenAnswer((_) async => Right(tCartItemModel)); /// Act @@ -30,7 +30,7 @@ void main() { /// Assert expect(result, Right(tCartItemModel)); - verify(() => mockProductRepository.addToCart(tCartItemModel)); + verify(() => mockProductRepository.addCartItem(tCartItemModel)); verifyNoMoreInteractions(mockProductRepository); }, ); @@ -38,7 +38,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = NetworkFailure(); - when(() => mockProductRepository.addToCart(tCartItemModel)) + when(() => mockProductRepository.addCartItem(tCartItemModel)) .thenAnswer((_) async => Left(failure)); /// Act @@ -47,7 +47,7 @@ void main() { /// Assert expect(result, Left(failure)); verify( - () => mockProductRepository.addToCart(tCartItemModel)); + () => mockProductRepository.addCartItem(tCartItemModel)); verifyNoMoreInteractions(mockProductRepository); }); } diff --git a/test/domain/usecases/cart/clear_cart_usecase_test.dart b/test/domain/usecases/cart/delete_cart_usecase_test.dart similarity index 70% rename from test/domain/usecases/cart/clear_cart_usecase_test.dart rename to test/domain/usecases/cart/delete_cart_usecase_test.dart index 4dc19e6..345242c 100644 --- a/test/domain/usecases/cart/clear_cart_usecase_test.dart +++ b/test/domain/usecases/cart/delete_cart_usecase_test.dart @@ -2,34 +2,34 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/repositories/cart_repository.dart'; -import 'package:eshop/domain/usecases/cart/clear_cart_usecase.dart'; +import 'package:eshop/domain/usecases/cart/delete_cart_usecase.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; class MockCartRepository extends Mock implements CartRepository {} void main() { - late ClearCartUseCase usecase; + late DeleteCartUseCase usecase; late MockCartRepository mockProductRepository; setUp(() { mockProductRepository = MockCartRepository(); - usecase = ClearCartUseCase(mockProductRepository); + usecase = DeleteCartUseCase(mockProductRepository); }); test( 'Should get clea item from the repository when Cart Repository clear data successfully', () async { /// Arrange - when(() => mockProductRepository.clearCart()) - .thenAnswer((_) async => const Right(true)); + when(() => mockProductRepository.deleteCart()) + .thenAnswer((_) async => Right(NoParams())); /// Act final result = await usecase(NoParams()); /// Assert - expect(result, const Right(true)); - verify(() => mockProductRepository.clearCart()); + expect(result, Right(NoParams())); + verify(() => mockProductRepository.deleteCart()); verifyNoMoreInteractions(mockProductRepository); }, ); @@ -37,7 +37,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = NetworkFailure(); - when(() => mockProductRepository.clearCart()) + when(() => mockProductRepository.deleteCart()) .thenAnswer((_) async => Left(failure)); /// Act @@ -45,7 +45,7 @@ void main() { /// Assert expect(result, Left(failure)); - verify(() => mockProductRepository.clearCart()); + verify(() => mockProductRepository.deleteCart()); verifyNoMoreInteractions(mockProductRepository); }); } diff --git a/test/domain/usecases/cart/get_cached_cart_usecase_test.dart b/test/domain/usecases/cart/get_cached_cart_usecase_test.dart index 922c730..43d60f9 100644 --- a/test/domain/usecases/cart/get_cached_cart_usecase_test.dart +++ b/test/domain/usecases/cart/get_cached_cart_usecase_test.dart @@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/repositories/cart_repository.dart'; -import 'package:eshop/domain/usecases/cart/get_cached_cart_usecase.dart'; +import 'package:eshop/domain/usecases/cart/get_local_cart_items_usecase.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; @@ -11,19 +11,19 @@ import '../../../fixtures/constant_objects.dart'; class MockCartRepository extends Mock implements CartRepository {} void main() { - late GetCachedCartUseCase usecase; + late GetLocalCartItemsUseCase usecase; late MockCartRepository mockProductRepository; setUp(() { mockProductRepository = MockCartRepository(); - usecase = GetCachedCartUseCase(mockProductRepository); + usecase = GetLocalCartItemsUseCase(mockProductRepository); }); test( 'Should get cart item from the repository when Cart Repository add data successfully', () async { /// Arrange - when(() => mockProductRepository.getCachedCart()) + when(() => mockProductRepository.getLocalCartItems()) .thenAnswer((_) async => Right([tCartItemModel])); /// Act @@ -34,7 +34,7 @@ void main() { (failure) => fail('Test Fail!'), (cart) => expect(cart, [tCartItemModel]), ); - verify(() => mockProductRepository.getCachedCart()); + verify(() => mockProductRepository.getLocalCartItems()); verifyNoMoreInteractions(mockProductRepository); }, ); @@ -42,7 +42,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = NetworkFailure(); - when(() => mockProductRepository.getCachedCart()) + when(() => mockProductRepository.getLocalCartItems()) .thenAnswer((_) async => Left(failure)); /// Act @@ -50,7 +50,7 @@ void main() { /// Assert expect(result, Left(failure)); - verify(() => mockProductRepository.getCachedCart()); + verify(() => mockProductRepository.getLocalCartItems()); verifyNoMoreInteractions(mockProductRepository); }); } diff --git a/test/domain/usecases/cart/sync_cart_usecase_test.dart b/test/domain/usecases/cart/sync_cart_usecase_test.dart index 4d56b13..b323c60 100644 --- a/test/domain/usecases/cart/sync_cart_usecase_test.dart +++ b/test/domain/usecases/cart/sync_cart_usecase_test.dart @@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/repositories/cart_repository.dart'; -import 'package:eshop/domain/usecases/cart/sync_cart_usecase.dart'; +import 'package:eshop/domain/usecases/cart/get_remote_cart_items_usecase.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; @@ -11,19 +11,19 @@ import '../../../fixtures/constant_objects.dart'; class MockCartRepository extends Mock implements CartRepository {} void main() { - late SyncCartUseCase usecase; + late GetRemoteCardItemsUseCase usecase; late MockCartRepository mockProductRepository; setUp(() { mockProductRepository = MockCartRepository(); - usecase = SyncCartUseCase(mockProductRepository); + usecase = GetRemoteCardItemsUseCase(mockProductRepository); }); test( 'Should get cart item from the repository when Cart Repository add data successfully', () async { /// Arrange - when(() => mockProductRepository.syncCart()) + when(() => mockProductRepository.getRemoteCartItems()) .thenAnswer((_) async => Right([tCartItemModel])); /// Act @@ -34,7 +34,7 @@ void main() { (failure) => fail('Test Fail!'), (cart) => expect(cart, [tCartItemModel]), ); - verify(() => mockProductRepository.syncCart()); + verify(() => mockProductRepository.getRemoteCartItems()); verifyNoMoreInteractions(mockProductRepository); }, ); @@ -42,7 +42,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = NetworkFailure(); - when(() => mockProductRepository.syncCart()) + when(() => mockProductRepository.getRemoteCartItems()) .thenAnswer((_) async => Left(failure)); /// Act @@ -50,7 +50,7 @@ void main() { /// Assert expect(result, Left(failure)); - verify(() => mockProductRepository.syncCart()); + verify(() => mockProductRepository.getRemoteCartItems()); verifyNoMoreInteractions(mockProductRepository); }); } diff --git a/test/domain/usecases/category/get_cached_category_usecase_test.dart b/test/domain/usecases/category/get_cached_category_usecase_test.dart index a4ba01a..65f6830 100644 --- a/test/domain/usecases/category/get_cached_category_usecase_test.dart +++ b/test/domain/usecases/category/get_cached_category_usecase_test.dart @@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/repositories/category_repository.dart'; -import 'package:eshop/domain/usecases/category/get_cached_category_usecase.dart'; +import 'package:eshop/domain/usecases/category/get_local_category_usecase.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; @@ -11,19 +11,19 @@ import '../../../fixtures/constant_objects.dart'; class MockCartRepository extends Mock implements CategoryRepository {} void main() { - late GetCachedCategoryUseCase usecase; + late GetLocalCategoryUseCase usecase; late MockCartRepository mockProductRepository; setUp(() { mockProductRepository = MockCartRepository(); - usecase = GetCachedCategoryUseCase(mockProductRepository); + usecase = GetLocalCategoryUseCase(mockProductRepository); }); test( 'Should get category from the repository when Category Repository add data successfully', () async { /// Arrange - when(() => mockProductRepository.getCachedCategories()) + when(() => mockProductRepository.getLocalCategories()) .thenAnswer((_) async => const Right([tCategoryModel])); /// Act @@ -34,7 +34,7 @@ void main() { (failure) => fail('Test Fail!'), (cart) => expect(cart, [tCategoryModel]), ); - verify(() => mockProductRepository.getCachedCategories()); + verify(() => mockProductRepository.getLocalCategories()); verifyNoMoreInteractions(mockProductRepository); }, ); @@ -42,7 +42,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = NetworkFailure(); - when(() => mockProductRepository.getCachedCategories()) + when(() => mockProductRepository.getLocalCategories()) .thenAnswer((_) async => Left(failure)); /// Act @@ -50,7 +50,7 @@ void main() { /// Assert expect(result, Left(failure)); - verify(() => mockProductRepository.getCachedCategories()); + verify(() => mockProductRepository.getLocalCategories()); verifyNoMoreInteractions(mockProductRepository); }); } diff --git a/test/domain/usecases/delivery_info/clear_local_delivery_info_test.dart b/test/domain/usecases/delivery_info/clear_local_delivery_info_test.dart index 2bf52a5..29c13e2 100644 --- a/test/domain/usecases/delivery_info/clear_local_delivery_info_test.dart +++ b/test/domain/usecases/delivery_info/clear_local_delivery_info_test.dart @@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/repositories/delivery_info_repository.dart'; -import 'package:eshop/domain/usecases/delivery_info/clear_local_delivery_info_usecase.dart'; +import 'package:eshop/domain/usecases/delivery_info/delete_local_delivery_info_usecase.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; @@ -11,19 +11,19 @@ class MockDeliveryInfoRepository extends Mock implements DeliveryInfoRepository {} void main() { - late ClearLocalDeliveryInfoUseCase usecase; + late DeleteLocalDeliveryInfoUseCase usecase; late MockDeliveryInfoRepository mockProductRepository; setUp(() { mockProductRepository = MockDeliveryInfoRepository(); - usecase = ClearLocalDeliveryInfoUseCase(mockProductRepository); + usecase = DeleteLocalDeliveryInfoUseCase(mockProductRepository); }); test( 'Should get Right(NoParams()) when DeliveryInfo Repository clear data successfully', () async { /// Arrange - when(() => mockProductRepository.clearLocalDeliveryInfo()) + when(() => mockProductRepository.deleteLocalDeliveryInfo()) .thenAnswer((_) async => Right(NoParams())); /// Act @@ -34,7 +34,7 @@ void main() { (failure) => fail('Test Fail!'), (result) => expect(result, NoParams()), ); - verify(() => mockProductRepository.clearLocalDeliveryInfo()); + verify(() => mockProductRepository.deleteLocalDeliveryInfo()); verifyNoMoreInteractions(mockProductRepository); }, ); @@ -42,7 +42,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = CacheFailure(); - when(() => mockProductRepository.clearLocalDeliveryInfo()) + when(() => mockProductRepository.deleteLocalDeliveryInfo()) .thenAnswer((_) async => Left(failure)); /// Act @@ -50,7 +50,7 @@ void main() { /// Assert expect(result, Left(failure)); - verify(() => mockProductRepository.clearLocalDeliveryInfo()); + verify(() => mockProductRepository.deleteLocalDeliveryInfo()); verifyNoMoreInteractions(mockProductRepository); }); } diff --git a/test/domain/usecases/delivery_info/get_cached_delivery_info_usecase_test.dart b/test/domain/usecases/delivery_info/get_cached_delivery_info_usecase_test.dart index 8ab1df4..e5d1977 100644 --- a/test/domain/usecases/delivery_info/get_cached_delivery_info_usecase_test.dart +++ b/test/domain/usecases/delivery_info/get_cached_delivery_info_usecase_test.dart @@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/repositories/delivery_info_repository.dart'; -import 'package:eshop/domain/usecases/delivery_info/get_cached_delivery_info_usecase.dart'; +import 'package:eshop/domain/usecases/delivery_info/get_local_delivery_info_usecase.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; @@ -11,19 +11,19 @@ import '../../../fixtures/constant_objects.dart'; class MockDeliveryInfoRepository extends Mock implements DeliveryInfoRepository {} void main() { - late GetCachedDeliveryInfoUseCase usecase; + late GetLocalDeliveryInfoUseCase usecase; late MockDeliveryInfoRepository mockProductRepository; setUp(() { mockProductRepository = MockDeliveryInfoRepository(); - usecase = GetCachedDeliveryInfoUseCase(mockProductRepository); + usecase = GetLocalDeliveryInfoUseCase(mockProductRepository); }); test( 'Should get delivery info from the repository when DeliveryInfo Repository add data successfully', () async { /// Arrange - when(() => mockProductRepository.getCachedDeliveryInfo()) + when(() => mockProductRepository.getLocalDeliveryInfo()) .thenAnswer((_) async => const Right([tDeliveryInfoModel])); /// Act @@ -34,7 +34,7 @@ void main() { (failure) => fail('Test Fail!'), (cart) => expect(cart, [tDeliveryInfoModel]), ); - verify(() => mockProductRepository.getCachedDeliveryInfo()); + verify(() => mockProductRepository.getLocalDeliveryInfo()); verifyNoMoreInteractions(mockProductRepository); }, ); @@ -42,7 +42,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = NetworkFailure(); - when(() => mockProductRepository.getCachedDeliveryInfo()) + when(() => mockProductRepository.getLocalDeliveryInfo()) .thenAnswer((_) async => Left(failure)); /// Act @@ -50,7 +50,7 @@ void main() { /// Assert expect(result, Left(failure)); - verify(() => mockProductRepository.getCachedDeliveryInfo()); + verify(() => mockProductRepository.getLocalDeliveryInfo()); verifyNoMoreInteractions(mockProductRepository); }); } diff --git a/test/domain/usecases/order/clear_local_orders_usecase_test.dart b/test/domain/usecases/order/clear_local_orders_usecase_test.dart index f2c35cc..d9baa6e 100644 --- a/test/domain/usecases/order/clear_local_orders_usecase_test.dart +++ b/test/domain/usecases/order/clear_local_orders_usecase_test.dart @@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/repositories/order_repository.dart'; -import 'package:eshop/domain/usecases/order/clear_local_order_usecase.dart'; +import 'package:eshop/domain/usecases/order/delete_local_order_usecase.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; @@ -10,19 +10,19 @@ import 'package:mocktail/mocktail.dart'; class MockOrderRepository extends Mock implements OrderRepository {} void main() { - late ClearLocalOrdersUseCase usecase; + late DeleteLocalOrdersUseCase usecase; late MockOrderRepository mockOrderRepository; setUp(() { mockOrderRepository = MockOrderRepository(); - usecase = ClearLocalOrdersUseCase(mockOrderRepository); + usecase = DeleteLocalOrdersUseCase(mockOrderRepository); }); test( 'Should get Right(NoParams()) when DeliveryInfo Repository clear data successfully', () async { /// Arrange - when(() => mockOrderRepository.clearLocalOrders()) + when(() => mockOrderRepository.deleteLocalOrders()) .thenAnswer((_) async => Right(NoParams())); /// Act @@ -33,7 +33,7 @@ void main() { (failure) => fail('Test Fail!'), (result) => expect(result, NoParams()), ); - verify(() => mockOrderRepository.clearLocalOrders()); + verify(() => mockOrderRepository.deleteLocalOrders()); verifyNoMoreInteractions(mockOrderRepository); }, ); @@ -41,7 +41,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = CacheFailure(); - when(() => mockOrderRepository.clearLocalOrders()) + when(() => mockOrderRepository.deleteLocalOrders()) .thenAnswer((_) async => Left(failure)); /// Act @@ -49,7 +49,7 @@ void main() { /// Assert expect(result, Left(failure)); - verify(() => mockOrderRepository.clearLocalOrders()); + verify(() => mockOrderRepository.deleteLocalOrders()); verifyNoMoreInteractions(mockOrderRepository); }); } diff --git a/test/domain/usecases/order/get_cached_orders_usecase_test.dart b/test/domain/usecases/order/get_cached_orders_usecase_test.dart index d9dfaaf..51c6bb2 100644 --- a/test/domain/usecases/order/get_cached_orders_usecase_test.dart +++ b/test/domain/usecases/order/get_cached_orders_usecase_test.dart @@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/repositories/order_repository.dart'; -import 'package:eshop/domain/usecases/order/get_cached_orders_usecase.dart'; +import 'package:eshop/domain/usecases/order/get_local_orders_usecase.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; @@ -11,19 +11,19 @@ import '../../../fixtures/constant_objects.dart'; class MockOrderRepository extends Mock implements OrderRepository {} void main() { - late GetCachedOrdersUseCase usecase; + late GetLocalOrdersUseCase usecase; late MockOrderRepository mockOrderRepository; setUp(() { mockOrderRepository = MockOrderRepository(); - usecase = GetCachedOrdersUseCase(mockOrderRepository); + usecase = GetLocalOrdersUseCase(mockOrderRepository); }); test( 'Should get order from the repository when Order Repository add data successfully', () async { /// Arrange - when(() => mockOrderRepository.getCachedOrders()) + when(() => mockOrderRepository.getLocalOrders()) .thenAnswer((_) async => Right([tOrderDetailsModel])); /// Act @@ -34,7 +34,7 @@ void main() { (failure) => fail('Test Fail!'), (cart) => expect(cart, [tOrderDetailsModel]), ); - verify(() => mockOrderRepository.getCachedOrders()); + verify(() => mockOrderRepository.getLocalOrders()); verifyNoMoreInteractions(mockOrderRepository); }, ); @@ -42,7 +42,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = NetworkFailure(); - when(() => mockOrderRepository.getCachedOrders()) + when(() => mockOrderRepository.getLocalOrders()) .thenAnswer((_) async => Left(failure)); /// Act @@ -50,7 +50,7 @@ void main() { /// Assert expect(result, Left(failure)); - verify(() => mockOrderRepository.getCachedOrders()); + verify(() => mockOrderRepository.getLocalOrders()); verifyNoMoreInteractions(mockOrderRepository); }); } diff --git a/test/domain/usecases/product/get_product_usecase_test.dart b/test/domain/usecases/product/get_product_usecase_test.dart index 3492316..5ccd08e 100644 --- a/test/domain/usecases/product/get_product_usecase_test.dart +++ b/test/domain/usecases/product/get_product_usecase_test.dart @@ -23,7 +23,7 @@ void main() { () async { /// Arrange when(() => mockProductRepository - .getProducts(const FilterProductParams())) + .getRemoteProducts(const FilterProductParams())) .thenAnswer((_) async => Right(tProductResponseModel)); /// Act @@ -32,7 +32,7 @@ void main() { /// Assert expect(result, Right(tProductResponseModel)); verify(() => - mockProductRepository.getProducts(const FilterProductParams())); + mockProductRepository.getRemoteProducts(const FilterProductParams())); verifyNoMoreInteractions(mockProductRepository); }, ); @@ -40,7 +40,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = NetworkFailure(); - when(() => mockProductRepository.getProducts( + when(() => mockProductRepository.getRemoteProducts( const FilterProductParams())).thenAnswer((_) async => Left(failure)); /// Act @@ -49,7 +49,7 @@ void main() { /// Assert expect(result, Left(failure)); verify(() => - mockProductRepository.getProducts(const FilterProductParams())); + mockProductRepository.getRemoteProducts(const FilterProductParams())); verifyNoMoreInteractions(mockProductRepository); }); } diff --git a/test/domain/usecases/user/get_cached_user_usecase_test.dart b/test/domain/usecases/user/get_cached_user_usecase_test.dart index 2f2a908..72dc877 100644 --- a/test/domain/usecases/user/get_cached_user_usecase_test.dart +++ b/test/domain/usecases/user/get_cached_user_usecase_test.dart @@ -2,7 +2,7 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/repositories/user_repository.dart'; -import 'package:eshop/domain/usecases/user/get_cached_user_usecase.dart'; +import 'package:eshop/domain/usecases/user/get_local_user_usecase.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mocktail/mocktail.dart'; @@ -11,19 +11,19 @@ import '../../../fixtures/constant_objects.dart'; class MockRepository extends Mock implements UserRepository {} void main() { - late GetCachedUserUseCase usecase; + late GetLocalUserUseCase usecase; late MockRepository mockRepository; setUp(() { mockRepository = MockRepository(); - usecase = GetCachedUserUseCase(mockRepository); + usecase = GetLocalUserUseCase(mockRepository); }); test( 'Should get User from the repository when User Repository return data successfully', () async { /// Arrange - when(() => mockRepository.getCachedUser()) + when(() => mockRepository.getLocalUser()) .thenAnswer((_) async => const Right(tUserModel)); /// Act @@ -31,7 +31,7 @@ void main() { /// Assert expect(result, const Right(tUserModel)); - verify(() => mockRepository.getCachedUser()); + verify(() => mockRepository.getLocalUser()); verifyNoMoreInteractions(mockRepository); }, ); @@ -39,7 +39,7 @@ void main() { test('should return a Failure from the repository', () async { /// Arrange final failure = NetworkFailure(); - when(() => mockRepository.getCachedUser()) + when(() => mockRepository.getLocalUser()) .thenAnswer((_) async => Left(failure)); /// Act @@ -47,7 +47,7 @@ void main() { /// Assert expect(result, Left(failure)); - verify(() => mockRepository.getCachedUser()); + verify(() => mockRepository.getLocalUser()); verifyNoMoreInteractions(mockRepository); }); } diff --git a/test/fixtures/cart/cart_item.json b/test/fixtures/cart/cart_item.json index 305fc53..93a7c98 100644 --- a/test/fixtures/cart/cart_item.json +++ b/test/fixtures/cart/cart_item.json @@ -1,14 +1,37 @@ { "_id": "1", "product": { - "_id": "1", - "name": "name", - "description": "description", - "priceTags": [{"_id": "1", "name": "name", "price": 100}], - "categories": [{"_id": "1", "name": "name", "image": "image"}], - "images": ["image"], - "createdAt": "2000-01-01T00:00:00.000", - "updatedAt": "2000-01-01T00:00:00.000" + "_id": "64eb722a41cb9b05eb4420b7", + "name": "Asus Gaming Mouse", + "description": "Text description", + "priceTags": [ + { + "_id": "64eb728341cb9b05eb4420ba", + "name": "White", + "price": 50.99 + } + ], + "categories": [ + { + "_id": "64cecb613357eaec7b1ab31b", + "name": "Headphone", + "image": "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg" + } + ], + "images": [ + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vxyyemcdwcuoooyejehj.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vqiw6cswpnzhgryd3s1l.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/tkanjwktt2t0qvybk5xf.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/yjxkgevogpaim02wonks.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/m2bb9pzzobynrpyo9ike.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/xhojjofgfyfpbjwo2vox.jpg" + ], + "createdAt": "2023-08-27T15:56:26.504Z", + "updatedAt": "2023-08-27T16:19:16.683Z" }, - "priceTag": {"_id": "1", "name": "name", "price": 100} + "priceTag": { + "_id": "64eb728341cb9b05eb4420ba", + "name": "White", + "price": 50.99 + } } diff --git a/test/fixtures/cart/cart_item_list.json b/test/fixtures/cart/cart_item_list.json index b8a751e..6688e20 100644 --- a/test/fixtures/cart/cart_item_list.json +++ b/test/fixtures/cart/cart_item_list.json @@ -2,15 +2,38 @@ { "_id": "1", "product": { - "_id": "1", - "name": "name", - "description": "description", - "priceTags": [{"_id": "1", "name": "name", "price": 100}], - "categories": [{"_id": "1", "name": "name", "image": "image"}], - "images": ["image"], - "createdAt": "2000-01-01T00:00:00.000", - "updatedAt": "2000-01-01T00:00:00.000" + "_id": "64eb722a41cb9b05eb4420b7", + "name": "Asus Gaming Mouse", + "description": "Text description", + "priceTags": [ + { + "_id": "64eb728341cb9b05eb4420ba", + "name": "White", + "price": 50.99 + } + ], + "categories": [ + { + "_id": "64cecb613357eaec7b1ab31b", + "name": "Headphone", + "image": "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg" + } + ], + "images": [ + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vxyyemcdwcuoooyejehj.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vqiw6cswpnzhgryd3s1l.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/tkanjwktt2t0qvybk5xf.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/yjxkgevogpaim02wonks.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/m2bb9pzzobynrpyo9ike.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/xhojjofgfyfpbjwo2vox.jpg" + ], + "createdAt": "2023-08-27T15:56:26.504Z", + "updatedAt": "2023-08-27T16:19:16.683Z" }, - "priceTag": {"_id": "1", "name": "name", "price": 100} + "priceTag": { + "_id": "64eb728341cb9b05eb4420ba", + "name": "White", + "price": 50.99 + } } ] \ No newline at end of file diff --git a/test/fixtures/category/category.json b/test/fixtures/category/category.json index d02c8e2..2b9bca1 100644 --- a/test/fixtures/category/category.json +++ b/test/fixtures/category/category.json @@ -1,5 +1,5 @@ { - "_id":"1", - "name":"name", - "image":"image" + "_id": "64cecb613357eaec7b1ab31b", + "name": "Headphone", + "image": "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg" } \ No newline at end of file diff --git a/test/fixtures/category/category_get_response.json b/test/fixtures/category/category_get_response.json index b729144..1d3132d 100644 --- a/test/fixtures/category/category_get_response.json +++ b/test/fixtures/category/category_get_response.json @@ -1,9 +1,9 @@ { "data": [ - { - "_id":"1", - "name":"name", - "image":"image" - } + { + "_id": "64cecb613357eaec7b1ab31b", + "name": "Headphone", + "image": "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg" + } ] } \ No newline at end of file diff --git a/test/fixtures/category/category_list.json b/test/fixtures/category/category_list.json index 03af035..714fe54 100644 --- a/test/fixtures/category/category_list.json +++ b/test/fixtures/category/category_list.json @@ -1,7 +1,7 @@ [ { - "_id":"1", - "name":"name", - "image":"image" + "_id": "64cecb613357eaec7b1ab31b", + "name": "Headphone", + "image": "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg" } ] \ No newline at end of file diff --git a/test/fixtures/constant_objects.dart b/test/fixtures/constant_objects.dart index 2f46c8e..730f432 100644 --- a/test/fixtures/constant_objects.dart +++ b/test/fixtures/constant_objects.dart @@ -15,14 +15,21 @@ import 'package:eshop/domain/usecases/user/sign_up_usecase.dart'; //products final tProductModel = ProductModel( - id: "1", - name: "name", - description: "description", - priceTags: [PriceTagModel(id: "1", name: "name", price: 100)], - categories: const [CategoryModel(id: "1", name: "name", image: "image")], - images: const ["image"], - createdAt: DateTime(2000), - updatedAt: DateTime(2000), + id: "64eb722a41cb9b05eb4420b7", + name: "Asus Gaming Mouse", + description: "Text description", + priceTags: [tPriceTagModel], + categories: const [tCategoryModel], + images: const [ + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vxyyemcdwcuoooyejehj.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vqiw6cswpnzhgryd3s1l.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/tkanjwktt2t0qvybk5xf.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/yjxkgevogpaim02wonks.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/m2bb9pzzobynrpyo9ike.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/xhojjofgfyfpbjwo2vox.jpg" + ], + createdAt: DateTime.parse("2023-08-27T15:56:26.504Z"), + updatedAt: DateTime.parse("2023-08-27T16:19:16.683Z"), ); final tProductModelList = [tProductModel, tProductModel]; @@ -45,7 +52,11 @@ final tProductResponseModel = ProductResponseModel( ); //price tag -final tPriceTagModel = PriceTagModel(id: "1", name: "name", price: 100); +final tPriceTagModel = PriceTagModel( + id: "64eb728341cb9b05eb4420ba", + name: "White", + price: 50.99, +); //cart final tCartItemModel = CartItemModel( @@ -56,21 +67,21 @@ final tCartItemModel = CartItemModel( //category const tCategoryModel = CategoryModel( - id: "1", - name: "name", - image: "image", + id: "64cecb613357eaec7b1ab31b", + name: "Headphone", + image: "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg", ); // delivery info const tDeliveryInfoModel = DeliveryInfoModel( id: '1', - firstName: 'firstName', - lastName: 'lastName', - addressLineOne: 'addressLineOne', - addressLineTwo: 'addressLineTwo', - city: 'city', - zipCode: 'zipCode', - contactNumber: 'contactNumber', + firstName: 'Jon', + lastName: 'Perera', + addressLineOne: '23/1 Main Road', + addressLineTwo: 'Navinna', + city: 'Mahragama', + zipCode: '10800', + contactNumber: '0779125803', ); // order details @@ -83,10 +94,10 @@ final tOrderDetailsModel = OrderDetailsModel( // order item final tOrderItemModel = OrderItemModel( - id: '1', + id: '651301997eae44a63472d728', product: tProductModel, priceTag: tPriceTagModel, - price: 100, + price: 50.99, quantity: 1, ); @@ -103,4 +114,8 @@ const tAuthenticationResponseModel = AuthenticationResponseModel(token: 'token', user: tUserModel); //params const tSignInParams = SignInParams(username: 'username', password: 'password'); -const tSignUpParams = SignUpParams(firstName: 'firstName', lastName: 'lastName', email: 'email', password: 'password'); +const tSignUpParams = SignUpParams( + firstName: 'firstName', + lastName: 'lastName', + email: 'email', + password: 'password'); diff --git a/test/fixtures/delivery_info/delivery_info.json b/test/fixtures/delivery_info/delivery_info.json index 7cbacb9..11dd4f6 100644 --- a/test/fixtures/delivery_info/delivery_info.json +++ b/test/fixtures/delivery_info/delivery_info.json @@ -1,10 +1,10 @@ { "_id": "1", - "firstName": "firstName", - "lastName": "lastName", - "addressLineOne": "addressLineOne", - "addressLineTwo": "addressLineTwo", - "city": "city", - "zipCode": "zipCode", - "contactNumber": "contactNumber" + "firstName": "Jon", + "lastName": "Perera", + "addressLineOne": "23/1 Main Road", + "addressLineTwo": "Navinna", + "city": "Mahragama", + "zipCode": "10800", + "contactNumber": "0779125803" } \ No newline at end of file diff --git a/test/fixtures/delivery_info/delivery_info_list.json b/test/fixtures/delivery_info/delivery_info_list.json index 8807403..6ad2f40 100644 --- a/test/fixtures/delivery_info/delivery_info_list.json +++ b/test/fixtures/delivery_info/delivery_info_list.json @@ -1,12 +1,12 @@ [ { "_id": "1", - "firstName": "firstName", - "lastName": "lastName", - "addressLineOne": "addressLineOne", - "addressLineTwo": "addressLineTwo", - "city": "city", - "zipCode": "zipCode", - "contactNumber": "contactNumber" + "firstName": "Jon", + "lastName": "Perera", + "addressLineOne": "23/1 Main Road", + "addressLineTwo": "Navinna", + "city": "Mahragama", + "zipCode": "10800", + "contactNumber": "0779125803" } ] \ No newline at end of file diff --git a/test/fixtures/order/order_details.json b/test/fixtures/order/order_details.json index 8b96cbf..c27da26 100644 --- a/test/fixtures/order/order_details.json +++ b/test/fixtures/order/order_details.json @@ -5,7 +5,7 @@ "_id": "651301997eae44a63472d728", "product": { "_id": "64eb722a41cb9b05eb4420b7", - "name": "Text name", + "name": "Asus Gaming Mouse", "description": "Text description", "priceTags": [ { @@ -36,8 +36,7 @@ "priceTag": { "_id": "64eb728341cb9b05eb4420ba", "name": "White", - "price": 50.99, - "product": "64eb722a41cb9b05eb4420b7" + "price": 50.99 }, "price": 50.99, "quantity": 1 diff --git a/test/fixtures/order/order_details_body.json b/test/fixtures/order/order_details_body.json index 76434ec..6f31464 100644 --- a/test/fixtures/order/order_details_body.json +++ b/test/fixtures/order/order_details_body.json @@ -1,14 +1,14 @@ { - "_id":"1", - "orderItems":[ + "_id": "1", + "orderItems": [ { - "_id":"1", - "product":"1", - "priceTag":"1", - "price":100, - "quantity":1 + "_id": "651301997eae44a63472d728", + "product": "64eb722a41cb9b05eb4420b7", + "priceTag": "64eb728341cb9b05eb4420ba", + "price": 50.99, + "quantity": 1 } ], - "deliveryInfo":"1", - "discount":0 -} + "deliveryInfo": "1", + "discount": 0 +} \ No newline at end of file diff --git a/test/fixtures/order/order_details_list.json b/test/fixtures/order/order_details_list.json index 3c8e7eb..b197083 100644 --- a/test/fixtures/order/order_details_list.json +++ b/test/fixtures/order/order_details_list.json @@ -6,7 +6,7 @@ "_id": "651301997eae44a63472d728", "product": { "_id": "64eb722a41cb9b05eb4420b7", - "name": "Text name", + "name": "Asus Gaming Mouse", "description": "Text description", "priceTags": [ { diff --git a/test/fixtures/order/order_details_response.json b/test/fixtures/order/order_details_response.json index ab65621..b197083 100644 --- a/test/fixtures/order/order_details_response.json +++ b/test/fixtures/order/order_details_response.json @@ -1,60 +1,60 @@ [ - { - "_id": "1", - "orderItems": [ - { - "_id": "651301997eae44a63472d728", - "product": { - "_id": "64eb722a41cb9b05eb4420b7", - "name": "Text name", - "description": "Text description", - "priceTags": [ - { - "_id": "64eb728341cb9b05eb4420ba", - "name": "White", - "price": 50.99, - "product": "64eb722a41cb9b05eb4420b7" - } - ], - "categories": [ - { - "_id": "64cecb613357eaec7b1ab31b", - "name": "Headphone", - "image": "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg" - } - ], - "images": [ - "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vxyyemcdwcuoooyejehj.jpg", - "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vqiw6cswpnzhgryd3s1l.jpg", - "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/tkanjwktt2t0qvybk5xf.jpg", - "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/yjxkgevogpaim02wonks.jpg", - "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/m2bb9pzzobynrpyo9ike.jpg", - "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/xhojjofgfyfpbjwo2vox.jpg" - ], - "createdAt": "2023-08-27T15:56:26.504Z", - "updatedAt": "2023-08-27T16:19:16.683Z" - }, - "priceTag": { - "_id": "64eb728341cb9b05eb4420ba", - "name": "White", - "price": 50.99, - "product": "64eb722a41cb9b05eb4420b7" - }, + { + "_id": "1", + "orderItems": [ + { + "_id": "651301997eae44a63472d728", + "product": { + "_id": "64eb722a41cb9b05eb4420b7", + "name": "Asus Gaming Mouse", + "description": "Text description", + "priceTags": [ + { + "_id": "64eb728341cb9b05eb4420ba", + "name": "White", + "price": 50.99, + "product": "64eb722a41cb9b05eb4420b7" + } + ], + "categories": [ + { + "_id": "64cecb613357eaec7b1ab31b", + "name": "Headphone", + "image": "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg" + } + ], + "images": [ + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vxyyemcdwcuoooyejehj.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vqiw6cswpnzhgryd3s1l.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/tkanjwktt2t0qvybk5xf.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/yjxkgevogpaim02wonks.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/m2bb9pzzobynrpyo9ike.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/xhojjofgfyfpbjwo2vox.jpg" + ], + "createdAt": "2023-08-27T15:56:26.504Z", + "updatedAt": "2023-08-27T16:19:16.683Z" + }, + "priceTag": { + "_id": "64eb728341cb9b05eb4420ba", + "name": "White", "price": 50.99, - "quantity": 1 - } - ], - "deliveryInfo": { - "_id": "1", - "firstName": "Jon", - "lastName": "Perera", - "addressLineOne": "23/1 Main Road", - "addressLineTwo": "Navinna", - "city": "Mahragama", - "zipCode": "10800", - "contactNumber": "0779125803" - }, - "discount": 0, - "orderStatus": 0 - } + "product": "64eb722a41cb9b05eb4420b7" + }, + "price": 50.99, + "quantity": 1 + } + ], + "deliveryInfo": { + "_id": "1", + "firstName": "Jon", + "lastName": "Perera", + "addressLineOne": "23/1 Main Road", + "addressLineTwo": "Navinna", + "city": "Mahragama", + "zipCode": "10800", + "contactNumber": "0779125803" + }, + "discount": 0, + "orderStatus": 0 + } ] \ No newline at end of file diff --git a/test/fixtures/product/product.json b/test/fixtures/product/product.json index f5b22f2..5916181 100644 --- a/test/fixtures/product/product.json +++ b/test/fixtures/product/product.json @@ -1,10 +1,29 @@ { - "_id": "1", - "name": "name", - "description": "description", - "priceTags": [{"_id": "1", "name": "name", "price": 100}], - "categories": [{"_id": "1", "name": "name", "image": "image"}], - "images": ["image"], - "createdAt": "2000-01-01T00:00:00.000", - "updatedAt": "2000-01-01T00:00:00.000" + "_id": "64eb722a41cb9b05eb4420b7", + "name": "Asus Gaming Mouse", + "description": "Text description", + "priceTags": [ + { + "_id": "64eb728341cb9b05eb4420ba", + "name": "White", + "price": 50.99 + } + ], + "categories": [ + { + "_id": "64cecb613357eaec7b1ab31b", + "name": "Headphone", + "image": "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg" + } + ], + "images": [ + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vxyyemcdwcuoooyejehj.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vqiw6cswpnzhgryd3s1l.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/tkanjwktt2t0qvybk5xf.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/yjxkgevogpaim02wonks.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/m2bb9pzzobynrpyo9ike.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/xhojjofgfyfpbjwo2vox.jpg" + ], + "createdAt": "2023-08-27T15:56:26.504Z", + "updatedAt": "2023-08-27T16:19:16.683Z" } \ No newline at end of file diff --git a/test/fixtures/product/product_int.json b/test/fixtures/product/product_int.json index f5b22f2..5916181 100644 --- a/test/fixtures/product/product_int.json +++ b/test/fixtures/product/product_int.json @@ -1,10 +1,29 @@ { - "_id": "1", - "name": "name", - "description": "description", - "priceTags": [{"_id": "1", "name": "name", "price": 100}], - "categories": [{"_id": "1", "name": "name", "image": "image"}], - "images": ["image"], - "createdAt": "2000-01-01T00:00:00.000", - "updatedAt": "2000-01-01T00:00:00.000" + "_id": "64eb722a41cb9b05eb4420b7", + "name": "Asus Gaming Mouse", + "description": "Text description", + "priceTags": [ + { + "_id": "64eb728341cb9b05eb4420ba", + "name": "White", + "price": 50.99 + } + ], + "categories": [ + { + "_id": "64cecb613357eaec7b1ab31b", + "name": "Headphone", + "image": "https://res.cloudinary.com/dhyttttax/image/upload/v1693148015/category/headphone_pdqwo2.jpg" + } + ], + "images": [ + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vxyyemcdwcuoooyejehj.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/vqiw6cswpnzhgryd3s1l.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/tkanjwktt2t0qvybk5xf.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/yjxkgevogpaim02wonks.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/m2bb9pzzobynrpyo9ike.jpg", + "https://res.cloudinary.com/dhyttttax/image/upload/v1693151785/product/xhojjofgfyfpbjwo2vox.jpg" + ], + "createdAt": "2023-08-27T15:56:26.504Z", + "updatedAt": "2023-08-27T16:19:16.683Z" } \ No newline at end of file diff --git a/test/presentation/blocs/cart/cart_bloc_test.dart b/test/presentation/blocs/cart/cart_bloc_test.dart index 2acc02f..3b6e6a2 100644 --- a/test/presentation/blocs/cart/cart_bloc_test.dart +++ b/test/presentation/blocs/cart/cart_bloc_test.dart @@ -3,22 +3,22 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/usecases/cart/add_cart_item_usecase.dart'; -import 'package:eshop/domain/usecases/cart/clear_cart_usecase.dart'; -import 'package:eshop/domain/usecases/cart/get_cached_cart_usecase.dart'; -import 'package:eshop/domain/usecases/cart/sync_cart_usecase.dart'; +import 'package:eshop/domain/usecases/cart/delete_cart_usecase.dart'; +import 'package:eshop/domain/usecases/cart/get_local_cart_items_usecase.dart'; +import 'package:eshop/domain/usecases/cart/get_remote_cart_items_usecase.dart'; import 'package:eshop/presentation/blocs/cart/cart_bloc.dart'; import 'package:mocktail/mocktail.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../../fixtures/constant_objects.dart'; -class MockGetCachedCartUseCase extends Mock implements GetCachedCartUseCase {} +class MockGetCachedCartUseCase extends Mock implements GetLocalCartItemsUseCase {} class MockAddCartUseCase extends Mock implements AddCartUseCase {} -class MockSyncCartUseCase extends Mock implements SyncCartUseCase {} +class MockSyncCartUseCase extends Mock implements GetRemoteCardItemsUseCase {} -class MockClearCartUseCase extends Mock implements ClearCartUseCase {} +class MockClearCartUseCase extends Mock implements DeleteCartUseCase {} void main() { group('CartBloc', () { @@ -82,7 +82,7 @@ void main() { 'emits [CartLoading, CartLoaded] when ClearCart is added', build: () { when(() => mockClearCartUseCase(NoParams())) - .thenAnswer((_) async => const Right(true)); + .thenAnswer((_) async => Right(NoParams())); return cartBloc; }, act: (bloc) => bloc.add(const ClearCart()), diff --git a/test/presentation/blocs/category/category_bloc_test.dart b/test/presentation/blocs/category/category_bloc_test.dart index b057ec8..0e97320 100644 --- a/test/presentation/blocs/category/category_bloc_test.dart +++ b/test/presentation/blocs/category/category_bloc_test.dart @@ -3,7 +3,7 @@ import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; import 'package:eshop/domain/usecases/category/filter_category_usecase.dart'; -import 'package:eshop/domain/usecases/category/get_cached_category_usecase.dart'; +import 'package:eshop/domain/usecases/category/get_local_category_usecase.dart'; import 'package:eshop/domain/usecases/category/get_remote_category_usecase.dart'; import 'package:eshop/presentation/blocs/category/category_bloc.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -15,7 +15,7 @@ class MockGetRemoteCategoryUseCase extends Mock implements GetRemoteCategoryUseCase {} class MockGetCachedCategoryUseCase extends Mock - implements GetCachedCategoryUseCase {} + implements GetLocalCategoryUseCase {} class MockFilterCategoryUseCase extends Mock implements FilterCategoryUseCase {} diff --git a/test/presentation/blocs/user/user_bloc_test.dart b/test/presentation/blocs/user/user_bloc_test.dart index 8917a05..096c54f 100644 --- a/test/presentation/blocs/user/user_bloc_test.dart +++ b/test/presentation/blocs/user/user_bloc_test.dart @@ -2,7 +2,7 @@ import 'package:bloc_test/bloc_test.dart'; import 'package:dartz/dartz.dart'; import 'package:eshop/core/error/failures.dart'; import 'package:eshop/core/usecases/usecase.dart'; -import 'package:eshop/domain/usecases/user/get_cached_user_usecase.dart'; +import 'package:eshop/domain/usecases/user/get_local_user_usecase.dart'; import 'package:eshop/domain/usecases/user/sign_in_usecase.dart'; import 'package:eshop/domain/usecases/user/sign_out_usecase.dart'; import 'package:eshop/domain/usecases/user/sign_up_usecase.dart'; @@ -17,7 +17,7 @@ class MockSignUpUseCase extends Mock implements SignUpUseCase {} class MockSignOutUseCase extends Mock implements SignOutUseCase {} -class MockGetCachedUserUseCase extends Mock implements GetCachedUserUseCase {} +class MockGetCachedUserUseCase extends Mock implements GetLocalUserUseCase {} void main() { group('UserBloc', () {