From bc024b47fa179ec046edf901348068ea93d678f3 Mon Sep 17 00:00:00 2001 From: Mohit Maulekhi Date: Wed, 25 Dec 2024 14:45:29 +0530 Subject: [PATCH] Test updated --- .../login_view_model.dart | 2 +- .../login_view_model_test.dart | 63 +++++++++++++++ .../app_settings/app_setting_page_test.dart | 77 +++++++++++++++++++ ...ustom_alert_dialog_with_checkbox_test.dart | 35 +++++++++ .../widgets/directly_login_test.dart | 3 + 5 files changed, 179 insertions(+), 1 deletion(-) diff --git a/lib/view_model/pre_auth_view_models/login_view_model.dart b/lib/view_model/pre_auth_view_models/login_view_model.dart index 4648ac053..7bb922b0f 100644 --- a/lib/view_model/pre_auth_view_models/login_view_model.dart +++ b/lib/view_model/pre_auth_view_models/login_view_model.dart @@ -29,7 +29,7 @@ class LoginViewModel extends BaseModel { String? prevUserPassword; /// Secure local storage instance. - final secureStorage = const FlutterSecureStorage(); + FlutterSecureStorage secureStorage = const FlutterSecureStorage(); /// List of maps to store greetings.. late List> greeting; diff --git a/test/view_model_tests/pre_auth_view_models/login_view_model_test.dart b/test/view_model_tests/pre_auth_view_models/login_view_model_test.dart index 3c39e72cf..dad04ffa5 100644 --- a/test/view_model_tests/pre_auth_view_models/login_view_model_test.dart +++ b/test/view_model_tests/pre_auth_view_models/login_view_model_test.dart @@ -2,6 +2,8 @@ // ignore_for_file: talawa_good_doc_comments // import 'package:flutter/material.dart'; +import 'dart:async'; + import 'package:flutter/widgets.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -170,6 +172,48 @@ Future main() async { expect(model.validate, AutovalidateMode.disabled); verify(databaseFunctions.gqlNonAuthMutation(queries.loginUser('', ''))); }); + + test("Check if prev user is fetched correctly with success", () async { + final model = LoginViewModel(); + FlutterSecureStorage.setMockInitialValues( + {"userEmail": "test@example.com", "userPassword": "password123"}, + ); + await model.fetchPrevUser(); + + expect(model.prevUserEmail, "test@example.com"); + expect(model.prevUserPassword, "password123"); + }); + + test("Check if fetching previous user result in error", () async { + final model = LoginViewModel(); + FlutterSecureStorage.setMockInitialValues( + {"userEmail": "test@example.com", "userPassword": "password123"}, + ); + final mockSecureStorage = MockFlutterSecureStorage(); + model.secureStorage = mockSecureStorage; + + String log = ""; + + await runZonedGuarded( + () async { + await model.fetchPrevUser(); + }, + (error, stack) { + expect(error, isA()); + expect(error.toString(), contains("Unable to read")); + expect(stack, isNotNull); + }, + zoneSpecification: ZoneSpecification( + print: (self, parent, zone, line) { + log = line; + }, + ), + ); + expect( + log, + contains("Unable to read"), + ); + }); }); } @@ -191,3 +235,22 @@ class MockUserConfig extends Mock implements UserConfig { @override Future updateUser(User user) async => true; } + +/// Mock Class for Flutter Secure Storage. +class MockFlutterSecureStorage extends Mock implements FlutterSecureStorage { + @override + Future read({ + required String key, + IOSOptions? iOptions, + AndroidOptions? aOptions, + LinuxOptions? lOptions, + WebOptions? webOptions, + MacOsOptions? mOptions, + WindowsOptions? wOptions, + }) async { + if (key == "userEmail" || key == "userPassword") { + throw Exception("Unable to read"); + } + return Future.value(null); + } +} diff --git a/test/widget_tests/after_auth_screens/app_settings/app_setting_page_test.dart b/test/widget_tests/after_auth_screens/app_settings/app_setting_page_test.dart index a22ac3df0..fa48d3e5c 100644 --- a/test/widget_tests/after_auth_screens/app_settings/app_setting_page_test.dart +++ b/test/widget_tests/after_auth_screens/app_settings/app_setting_page_test.dart @@ -1,5 +1,8 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/mockito.dart'; import 'package:provider/provider.dart'; @@ -23,6 +26,25 @@ import '../../../helpers/test_locator.dart'; /// MockBuildContext class helps to mock the BuildContext class. class MockBuildContext extends Mock implements BuildContext {} +/// Mock Class for Flutter Secure Storage. +class MockFlutterSecureStorage extends Mock implements FlutterSecureStorage { + @override + Future delete({ + required String key, + IOSOptions? iOptions, + AndroidOptions? aOptions, + LinuxOptions? lOptions, + WebOptions? webOptions, + MacOsOptions? mOptions, + WindowsOptions? wOptions, + }) async { + if (key == "userEmail" || key == "userPassword") { + throw Exception("Deletion error"); + } + return Future.value(null); + } +} + /// MockCallbackFunction class helps to mock the callback function. class MockCallbackFunction extends Mock { /// call function helps to mock the call function. @@ -307,5 +329,60 @@ Future main() async { verify(model.logout()); }); + test('Should delete stored values if checkBoxVal is false', () async { + FlutterSecureStorage.setMockInitialValues( + {"userEmail": "test@example.com", "userPassword": "password123"}, + ); + const secureStorage = FlutterSecureStorage(); + const bool checkBoxVal = false; + if (checkBoxVal == false) { + try { + await secureStorage.delete(key: "userEmail"); + await secureStorage.delete(key: "userPassword"); + } catch (e) { + print("Unable to delete stored value : $e"); + } + } + final userEmail = await secureStorage.read(key: "userEmail"); + final userPassword = await secureStorage.read(key: "userPassword"); + expect(userEmail, isNull); + expect(userPassword, isNull); + }); + test('Should handle exception during deletion', () async { + FlutterSecureStorage.setMockInitialValues( + {"userEmail": "test@example.com", "userPassword": "password123"}, + ); + final mockSecureStorage = MockFlutterSecureStorage(); + const checkBoxVal = false; + + String log = ""; + + await runZonedGuarded( + () async { + if (checkBoxVal == false) { + try { + await mockSecureStorage.delete(key: "userEmail"); + await mockSecureStorage.delete(key: "userPassword"); + } catch (e) { + print("Unable to delete stored value: $e"); + } + } + }, + (error, stack) { + expect(error, isA()); + expect(error.toString(), contains("Deletion error")); + expect(stack, isNotNull); + }, + zoneSpecification: ZoneSpecification( + print: (self, parent, zone, line) { + log = line; + }, + ), + ); + expect( + log, + contains("Deletion error"), + ); + }); }); } diff --git a/test/widget_tests/widgets/custom_alert_dialog_with_checkbox_test.dart b/test/widget_tests/widgets/custom_alert_dialog_with_checkbox_test.dart index e362fc041..850d0e1ce 100644 --- a/test/widget_tests/widgets/custom_alert_dialog_with_checkbox_test.dart +++ b/test/widget_tests/widgets/custom_alert_dialog_with_checkbox_test.dart @@ -9,19 +9,54 @@ import 'package:talawa/widgets/raised_round_edge_button.dart'; import '../../helpers/test_locator.dart'; +/// success variable for checkBox. bool success = false; + +/// cancellation variabe for checkBox. bool cancelled = false; + +/// Checkbox variable. bool checkboxValue = false; +/// Function to run on pressing success. +/// +/// Running this function will idicate that success is chosed and success is working properly. +/// +/// **params**: +/// * `value`: Represents the new value of check +/// +/// **returns**: +/// None void onSuccess(bool? value) { success = true; checkboxValue = value!; } +/// Function to run on pressing cancellation. +/// +/// Running this function will idicate that cancel is chosed and cancellation is working properly. +/// +/// **params**: +/// None +/// +/// **returns**: +/// None void onCancel() { cancelled = true; } +/// Function to run on pressing cancellation. +/// +/// Running this function will idicate that cancel is chosed and cancellation is working properly. +/// +/// **params**: +/// * `reverse`: Indicates whether the order of action buttons should be reversed. +/// * `dialogTitle`: Title displayed in the dialog. +/// * `initialCheckboxValue`: Initial value for the checkbox. +/// * `passSecondaryFunc`: Indicates whether to pass secondary function. +/// +/// **returns**: +/// * `Widget`: Widget that we will be using for testing Widget createCustomAlertDialogWithCheckbox({ bool reverse = false, String? dialogTitle, diff --git a/test/widget_tests/widgets/directly_login_test.dart b/test/widget_tests/widgets/directly_login_test.dart index 37454e1db..cf3757c14 100644 --- a/test/widget_tests/widgets/directly_login_test.dart +++ b/test/widget_tests/widgets/directly_login_test.dart @@ -135,6 +135,9 @@ void main() { ); await tester.pump(); await tester.pump(const Duration(milliseconds: 500)); + + expect(mockLoginViewModel.email.text, ""); + expect(mockLoginViewModel.password.text, ""); expect(find.byType(SizedBox), findsOneWidget); }); }