Repository: PalisadoesFoundation/talawa (language: dart)

Issue:
Write tests for lib/utils/encryptor.dart
The Talawa code base needs to be 100% reliable. This means we need to have 100% unittest code coverage. No functionality must be removed to achieve this goal.

We will need unittests done for all methods, classes and functions found in this file.

Any widgets referenced in this file must also have unittests done


```
lib/utils/encryptor.dart

```

The current code coverage for this file can be found here:
-  https://app.codecov.io/gh/PalisadoesFoundation/talawa?displayType=list



Discussion hints:
@Ayush0Chaudhary  @noman2002 I would like to work on this issue.. can you please assign it to me?
Solve other issues first 
@Ayush0Chaudhary @noman2002 Can you assign this issue to me?
There is a problem lying in the `generateRSAKeyPair()` function, the parameters passed in ` final random = SecureRandom('Fortuna')
      ..seed(secureRandom as CipherParameters);` are wrong as `secureRandom` is not a Cypher Parameter. When changed to the `KeyParametres` then to start AES Enginer, a key is required and also more configurations are required which can't be done without the assistance of Maintainers. See this link for more info: [AES-CBC with Pointy Castle](https://github.com/bcgit/pc-dart/blob/master/tutorials/aes-cbc.md)
If Maintainers can allow me, I can move forward with random configurations which can be modified further, otherwise test can't be written as parameters are wrong!
@literalEval Please answer this query.
```
AsymmetricKeyPair<PublicKey, PrivateKey> generateRSAKeyPair() {
    final secureRandom = FortunaRandom();
    final random = Random.secure();
    final List<int> seeds = [];
    for (int i = 0; i < 32; i++) {
      seeds.add(random.nextInt(255));
    }
    secureRandom.seed(KeyParameter(Uint8List.fromList(seeds)));
    final rsapars = RSAKeyGeneratorParameters(BigInt.from(65537), 2048, 64);
  final params = ParametersWithRandom(rsapars, secureRandom);
  final keyGenerator = RSAKeyGenerator();
  keyGenerator.init(params);
  return keyGenerator.generateKeyPair();
  }
```
I have modified this function in this way with the help of the blog [Asymmetric Key Generation in Flutter](https://medium.com/flutter-community/asymmetric-key-generation-in-flutter-ad2b912f3309l). Kindly check if it is right as it is working fine!

Pull request: Tests for encryptor.dart written
<!--
This section can be deleted after reading.

We employ the following branching strategy to simplify the development process and to ensure that only stable code is pushed to the `master` branch:

- `develop`: For unstable code: New features and bug fixes.
- `master`: Where the stable production ready code lies. Only security related bugs.

NOTE!!!

ONLY SUBMIT PRS AGAINST OUR `DEVELOP` BRANCH. THE DEFAULT IS `MAIN`, SO YOU WILL HAVE TO MODIFY THIS BEFORE SUBMITTING YOUR PR FOR REVIEW. PRS MADE AGAINST `MAIN` WILL BE CLOSED.
-->

<!--
Thanks for submitting a pull request! Please provide enough information so that others can review your pull request.
-->

**What kind of change does this PR introduce?** 
This change is about:
1) Making the coverage of `lib/utils/encryptor.dart` from 2.94% to 100%
2) Covering all the test cases related to this file
3) Correcting the `generateRSAKeyPair()` function which previously was not generating keys but currently is!
4) Created AsymetricKeys Model to save Key Pairs in Hive which previously was not created, registered the respective Adapters in the `main.dart` file.  
5) Created a Mock/Testing environment for Hive Data Base, so that Future Developers are able to write tests including Hive easily.   

<!-- E.g. a bugfix, feature, refactoring, etc… -->

**Issue Number:** 2149

Fixes #<!--Add related issue number here.-->2149

**Did you add tests for your changes?** Yes

<!--Yes or No. Note: Add unit tests or automation tests for your code.-->

**Snapshots/Videos:**

<!--Add snapshots or videos wherever possible.-->

**If relevant, did you update the documentation?**

<!--Add link to Talawa-Docs.-->

**Summary**

<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
<!-- Try to link to an open issue for more information. -->

**Does this PR introduce a breaking change?** Yes, the Testing Environment for Hive is going to make life of Talawa Developers easy! 

<!-- If this PR introduces a breaking change, please describe the impact and a migration path for existing applications. -->

**Other information**

<!--Add extra information about this PR here-->

**Have you read the [contributing guide](https://github.com/PalisadoesFoundation/talawa/blob/master/CONTRIBUTING.md)?** Yes

<!--Yes or No-->


Test command: nan

Fix patch:
diff --git a/lib/main.dart b/lib/main.dart
index 19350a4cc3..7ec3b18905 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -15,6 +15,7 @@ import 'package:talawa/constants/custom_theme.dart';
 import 'package:talawa/constants/quick_actions.dart';
 import 'package:talawa/firebase_options.dart';
 import 'package:talawa/locator.dart';
+import 'package:talawa/models/asymetric_keys/asymetric_keys.dart';
 import 'package:talawa/models/organization/org_info.dart';
 import 'package:talawa/models/user/user_info.dart';
 import 'package:talawa/plugins/fetch_plugin_list.dart';
@@ -105,11 +106,12 @@ Future<void> main() async {
   Hive
     ..init(dir.path)
     ..registerAdapter(UserAdapter())
-    ..registerAdapter(OrgInfoAdapter());
+    ..registerAdapter(OrgInfoAdapter())
+    ..registerAdapter(AsymetricKeysAdapter());
 
   await Hive.openBox<User>('currentUser');
   await Hive.openBox<OrgInfo>('currentOrg');
-
+  await Hive.openBox<AsymetricKeys>('user_keys');
   await Hive.openBox('pluginBox');
   await Hive.openBox('url');
 
diff --git a/lib/models/asymetric_keys/asymetric_keys.dart b/lib/models/asymetric_keys/asymetric_keys.dart
new file mode 100644
index 0000000000..5791136a4c
--- /dev/null
+++ b/lib/models/asymetric_keys/asymetric_keys.dart
@@ -0,0 +1,11 @@
+import 'package:hive/hive.dart';
+import 'package:pointycastle/api.dart';
+part 'asymetric_keys.g.dart';
+
+// This model is created to save Asymmetric Keys to the Hive as Hive doesn't allow to store objects other than Arrays, List, int, Strings etc.
+@HiveType(typeId: 7)
+class AsymetricKeys extends HiveObject {
+  AsymetricKeys({required this.keyPair});
+  @HiveField(0)
+  final AsymmetricKeyPair<PublicKey, PrivateKey> keyPair;
+}
diff --git a/lib/models/asymetric_keys/asymetric_keys.g.dart b/lib/models/asymetric_keys/asymetric_keys.g.dart
new file mode 100644
index 0000000000..5661ba4f03
--- /dev/null
+++ b/lib/models/asymetric_keys/asymetric_keys.g.dart
@@ -0,0 +1,41 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'asymetric_keys.dart';
+
+// **************************************************************************
+// TypeAdapterGenerator
+// **************************************************************************
+
+class AsymetricKeysAdapter extends TypeAdapter<AsymetricKeys> {
+  @override
+  final int typeId = 7;
+
+  @override
+  AsymetricKeys read(BinaryReader reader) {
+    final numOfFields = reader.readByte();
+    final fields = <int, dynamic>{
+      for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
+    };
+    return AsymetricKeys(
+      keyPair: fields[0] as AsymmetricKeyPair<PublicKey, PrivateKey>,
+    );
+  }
+
+  @override
+  void write(BinaryWriter writer, AsymetricKeys obj) {
+    writer
+      ..writeByte(1)
+      ..writeByte(0)
+      ..write(obj.keyPair);
+  }
+
+  @override
+  int get hashCode => typeId.hashCode;
+
+  @override
+  bool operator ==(Object other) =>
+      identical(this, other) ||
+      other is AsymetricKeysAdapter &&
+          runtimeType == other.runtimeType &&
+          typeId == other.typeId;
+}
diff --git a/lib/utils/encryptor.dart b/lib/utils/encryptor.dart
index 6435a25275..8bdef772d8 100644
--- a/lib/utils/encryptor.dart
+++ b/lib/utils/encryptor.dart
@@ -1,12 +1,15 @@
 import 'dart:convert';
+import 'dart:math';
 import 'dart:typed_data';
 
 import 'package:crypto/crypto.dart';
 import 'package:hive/hive.dart';
 import 'package:pointycastle/asymmetric/oaep.dart';
 import 'package:pointycastle/asymmetric/rsa.dart';
+import 'package:pointycastle/key_generators/rsa_key_generator.dart';
 import 'package:pointycastle/pointycastle.dart';
 import 'package:pointycastle/random/fortuna_random.dart';
+import 'package:talawa/models/asymetric_keys/asymetric_keys.dart';
 
 /// Handles all of the encryption tasks in the codebase.
 class Encryptor {
@@ -43,15 +46,17 @@ class Encryptor {
   /// * `AsymmetricKeyPair<PublicKey, PrivateKey>`: The generated
   /// public and private keys.
   AsymmetricKeyPair<PublicKey, PrivateKey> generateRSAKeyPair() {
-    final keyGen = RSAKeyGeneratorParameters(BigInt.parse('65537'), 2048, 64);
     final secureRandom = FortunaRandom();
-    final random = SecureRandom('Fortuna')
-      ..seed(secureRandom as CipherParameters);
-    final keyGenParams = ParametersWithRandom(keyGen, random);
-
-    final keyGenerator = KeyGenerator('RSA');
-    keyGenerator.init(keyGenParams);
-
+    final random = Random.secure();
+    final List<int> seeds = [];
+    for (int i = 0; i < 32; i++) {
+      seeds.add(random.nextInt(255));
+    }
+    secureRandom.seed(KeyParameter(Uint8List.fromList(seeds)));
+    final rsapars = RSAKeyGeneratorParameters(BigInt.from(65537), 2048, 64);
+    final params = ParametersWithRandom(rsapars, secureRandom);
+    final keyGenerator = RSAKeyGenerator();
+    keyGenerator.init(params);
     return keyGenerator.generateKeyPair();
   }
 
@@ -66,13 +71,12 @@ class Encryptor {
   /// * `Future<void>`: None
   Future<void> saveKeyPair(
     AsymmetricKeyPair<PublicKey, PrivateKey> keyPair,
+    HiveInterface hiveInterface,
   ) async {
     // TODO: Implement secure storage here
-
-    await Hive.openBox<AsymmetricKeyPair<PublicKey, PrivateKey>>('user_keys');
-    final keysBox = await Hive.openBox('user_keys');
-
-    keysBox.put('key_pair', keyPair);
+    final Box<AsymetricKeys> keysBox =
+        await hiveInterface.openBox<AsymetricKeys>('user_keys');
+    keysBox.put('key_pair', AsymetricKeys(keyPair: keyPair));
   }
 
   /// Loads secret keys from the Hive db.
@@ -83,12 +87,11 @@ class Encryptor {
   /// **returns**:
   /// * `Future<AsymmetricKeyPair<PublicKey, PrivateKey>>`: The public and
   /// private key pair
-  Future<AsymmetricKeyPair<PublicKey, PrivateKey>> loadKeyPair() async {
-    await Hive.openBox<AsymmetricKeyPair<PublicKey, PrivateKey>>('user_keys');
-    final keysBox = await Hive.openBox('user_keys');
-
-    return (await keysBox.get('key_pair'))
-        as AsymmetricKeyPair<PublicKey, PrivateKey>;
+  Future<AsymmetricKeyPair<PublicKey, PrivateKey>> loadKeyPair(
+    HiveInterface hive,
+  ) async {
+    final keysBox = await hive.openBox<AsymetricKeys>('user_keys');
+    return keysBox.get('key_pair')!.keyPair;
   }
 
   /// Encrypts the given string data with Recipient's Public Key.
@@ -136,15 +139,21 @@ class Encryptor {
   /// **returns**:
   /// * `Future<void>`: None
   /// TODO: Use this somewhere
-  Future<void> receiveMessage(Map<String, dynamic> message) async {
-    final privateKey = (await loadKeyPair()).privateKey;
-
-    final encryptedMessage = message['encryptedMessage'] as String;
-    final decryptedMessage = assymetricDecryptString(
-      encryptedMessage,
-      privateKey as RSAPrivateKey,
-    );
-
-    print('Decrypted Message: $decryptedMessage');
+  Future<void> receiveMessage(
+    Map<String, dynamic> message,
+    HiveInterface hive,
+  ) async {
+    try {
+      final encryptedMessage = message['encryptedMessage'] as String;
+      final privateKey = (await loadKeyPair(hive)).privateKey;
+      final decryptedMessage = assymetricDecryptString(
+        encryptedMessage,
+        privateKey as RSAPrivateKey,
+      );
+
+      print('Decrypted Message: $decryptedMessage');
+    } catch (e) {
+      throw Exception('Error');
+    }
   }
 }


Test patch:
diff --git a/test/helpers/setup_hive.dart b/test/helpers/setup_hive.dart
index cb9b87fbc5..55cc63be57 100644
--- a/test/helpers/setup_hive.dart
+++ b/test/helpers/setup_hive.dart
@@ -2,9 +2,22 @@
 // ignore_for_file: talawa_good_doc_comments
 
 import 'package:hive/hive.dart';
+import 'package:mockito/annotations.dart';
 import 'package:talawa/models/organization/org_info.dart';
 import 'package:talawa/models/user/user_info.dart';
 
+@GenerateMocks(
+  [
+    HiveInterface,
+    Box,
+  ],
+  customMocks: [
+    MockSpec<Box>(
+      as: Symbol('MockHiveBox'),
+      onMissingStub: OnMissingStub.returnDefault,
+    ),
+  ],
+)
 Future<Box> setUpUserInfoHive() async {
   Hive
     ..init("./temporaryPath")
diff --git a/test/helpers/setup_hive.mocks.dart b/test/helpers/setup_hive.mocks.dart
new file mode 100644
index 0000000000..dc67dfd0a5
--- /dev/null
+++ b/test/helpers/setup_hive.mocks.dart
@@ -0,0 +1,837 @@
+// Mocks generated by Mockito 5.4.3 from annotations
+// in talawa/test/utils/encryptor_test.dart.
+// Do not manually edit this file.
+
+// ignore_for_file: no_leading_underscores_for_library_prefixes
+import 'dart:async' as _i3;
+import 'dart:typed_data' as _i6;
+
+import 'package:hive/hive.dart' as _i2;
+import 'package:hive/src/box/default_compaction_strategy.dart' as _i5;
+import 'package:hive/src/box/default_key_comparator.dart' as _i4;
+import 'package:mockito/mockito.dart' as _i1;
+import 'package:mockito/src/dummies.dart' as _i7;
+
+// ignore_for_file: type=lint
+// ignore_for_file: avoid_redundant_argument_values
+// ignore_for_file: avoid_setters_without_getters
+// ignore_for_file: comment_references
+// ignore_for_file: deprecated_member_use
+// ignore_for_file: deprecated_member_use_from_same_package
+// ignore_for_file: implementation_imports
+// ignore_for_file: invalid_use_of_visible_for_testing_member
+// ignore_for_file: prefer_const_constructors
+// ignore_for_file: unnecessary_parenthesis
+// ignore_for_file: camel_case_types
+// ignore_for_file: subtype_of_sealed_class
+
+class _FakeBox_0<E1> extends _i1.SmartFake implements _i2.Box<E1> {
+  _FakeBox_0(
+    Object parent,
+    Invocation parentInvocation,
+  ) : super(
+          parent,
+          parentInvocation,
+        );
+}
+
+class _FakeLazyBox_1<E1> extends _i1.SmartFake implements _i2.LazyBox<E1> {
+  _FakeLazyBox_1(
+    Object parent,
+    Invocation parentInvocation,
+  ) : super(
+          parent,
+          parentInvocation,
+        );
+}
+
+/// A class which mocks [HiveInterface].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockHiveInterface extends _i1.Mock implements _i2.HiveInterface {
+  MockHiveInterface() {
+    _i1.throwOnMissingStub(this);
+  }
+
+  @override
+  void init(
+    String? path, {
+    _i2.HiveStorageBackendPreference? backendPreference =
+        _i2.HiveStorageBackendPreference.native,
+  }) =>
+      super.noSuchMethod(
+        Invocation.method(
+          #init,
+          [path],
+          {#backendPreference: backendPreference},
+        ),
+        returnValueForMissingStub: null,
+      );
+
+  @override
+  _i3.Future<_i2.Box<E>> openBox<E>(
+    String? name, {
+    _i2.HiveCipher? encryptionCipher,
+    _i2.KeyComparator? keyComparator = _i4.defaultKeyComparator,
+    _i2.CompactionStrategy? compactionStrategy = _i5.defaultCompactionStrategy,
+    bool? crashRecovery = true,
+    String? path,
+    _i6.Uint8List? bytes,
+    String? collection,
+    List<int>? encryptionKey,
+  }) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #openBox,
+          [name],
+          {
+            #encryptionCipher: encryptionCipher,
+            #keyComparator: keyComparator,
+            #compactionStrategy: compactionStrategy,
+            #crashRecovery: crashRecovery,
+            #path: path,
+            #bytes: bytes,
+            #collection: collection,
+            #encryptionKey: encryptionKey,
+          },
+        ),
+        returnValue: _i3.Future<_i2.Box<E>>.value(_FakeBox_0<E>(
+          this,
+          Invocation.method(
+            #openBox,
+            [name],
+            {
+              #encryptionCipher: encryptionCipher,
+              #keyComparator: keyComparator,
+              #compactionStrategy: compactionStrategy,
+              #crashRecovery: crashRecovery,
+              #path: path,
+              #bytes: bytes,
+              #collection: collection,
+              #encryptionKey: encryptionKey,
+            },
+          ),
+        )),
+      ) as _i3.Future<_i2.Box<E>>);
+
+  @override
+  _i3.Future<_i2.LazyBox<E>> openLazyBox<E>(
+    String? name, {
+    _i2.HiveCipher? encryptionCipher,
+    _i2.KeyComparator? keyComparator = _i4.defaultKeyComparator,
+    _i2.CompactionStrategy? compactionStrategy = _i5.defaultCompactionStrategy,
+    bool? crashRecovery = true,
+    String? path,
+    String? collection,
+    List<int>? encryptionKey,
+  }) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #openLazyBox,
+          [name],
+          {
+            #encryptionCipher: encryptionCipher,
+            #keyComparator: keyComparator,
+            #compactionStrategy: compactionStrategy,
+            #crashRecovery: crashRecovery,
+            #path: path,
+            #collection: collection,
+            #encryptionKey: encryptionKey,
+          },
+        ),
+        returnValue: _i3.Future<_i2.LazyBox<E>>.value(_FakeLazyBox_1<E>(
+          this,
+          Invocation.method(
+            #openLazyBox,
+            [name],
+            {
+              #encryptionCipher: encryptionCipher,
+              #keyComparator: keyComparator,
+              #compactionStrategy: compactionStrategy,
+              #crashRecovery: crashRecovery,
+              #path: path,
+              #collection: collection,
+              #encryptionKey: encryptionKey,
+            },
+          ),
+        )),
+      ) as _i3.Future<_i2.LazyBox<E>>);
+
+  @override
+  _i2.Box<E> box<E>(String? name) => (super.noSuchMethod(
+        Invocation.method(
+          #box,
+          [name],
+        ),
+        returnValue: _FakeBox_0<E>(
+          this,
+          Invocation.method(
+            #box,
+            [name],
+          ),
+        ),
+      ) as _i2.Box<E>);
+
+  @override
+  _i2.LazyBox<E> lazyBox<E>(String? name) => (super.noSuchMethod(
+        Invocation.method(
+          #lazyBox,
+          [name],
+        ),
+        returnValue: _FakeLazyBox_1<E>(
+          this,
+          Invocation.method(
+            #lazyBox,
+            [name],
+          ),
+        ),
+      ) as _i2.LazyBox<E>);
+
+  @override
+  bool isBoxOpen(String? name) => (super.noSuchMethod(
+        Invocation.method(
+          #isBoxOpen,
+          [name],
+        ),
+        returnValue: false,
+      ) as bool);
+
+  @override
+  _i3.Future<void> close() => (super.noSuchMethod(
+        Invocation.method(
+          #close,
+          [],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> deleteBoxFromDisk(
+    String? name, {
+    String? path,
+  }) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #deleteBoxFromDisk,
+          [name],
+          {#path: path},
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> deleteFromDisk() => (super.noSuchMethod(
+        Invocation.method(
+          #deleteFromDisk,
+          [],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  List<int> generateSecureKey() => (super.noSuchMethod(
+        Invocation.method(
+          #generateSecureKey,
+          [],
+        ),
+        returnValue: <int>[],
+      ) as List<int>);
+
+  @override
+  _i3.Future<bool> boxExists(
+    String? name, {
+    String? path,
+  }) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #boxExists,
+          [name],
+          {#path: path},
+        ),
+        returnValue: _i3.Future<bool>.value(false),
+      ) as _i3.Future<bool>);
+
+  @override
+  void resetAdapters() => super.noSuchMethod(
+        Invocation.method(
+          #resetAdapters,
+          [],
+        ),
+        returnValueForMissingStub: null,
+      );
+
+  @override
+  void registerAdapter<T>(
+    _i2.TypeAdapter<T>? adapter, {
+    bool? internal = false,
+    bool? override = false,
+  }) =>
+      super.noSuchMethod(
+        Invocation.method(
+          #registerAdapter,
+          [adapter],
+          {
+            #internal: internal,
+            #override: override,
+          },
+        ),
+        returnValueForMissingStub: null,
+      );
+
+  @override
+  bool isAdapterRegistered(int? typeId) => (super.noSuchMethod(
+        Invocation.method(
+          #isAdapterRegistered,
+          [typeId],
+        ),
+        returnValue: false,
+      ) as bool);
+
+  @override
+  void ignoreTypeId<T>(int? typeId) => super.noSuchMethod(
+        Invocation.method(
+          #ignoreTypeId,
+          [typeId],
+        ),
+        returnValueForMissingStub: null,
+      );
+}
+
+/// A class which mocks [Box].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockBox<E> extends _i1.Mock implements _i2.Box<E> {
+  MockBox() {
+    _i1.throwOnMissingStub(this);
+  }
+
+  @override
+  Iterable<E> get values => (super.noSuchMethod(
+        Invocation.getter(#values),
+        returnValue: <E>[],
+      ) as Iterable<E>);
+
+  @override
+  String get name => (super.noSuchMethod(
+        Invocation.getter(#name),
+        returnValue: _i7.dummyValue<String>(
+          this,
+          Invocation.getter(#name),
+        ),
+      ) as String);
+
+  @override
+  bool get isOpen => (super.noSuchMethod(
+        Invocation.getter(#isOpen),
+        returnValue: false,
+      ) as bool);
+
+  @override
+  bool get lazy => (super.noSuchMethod(
+        Invocation.getter(#lazy),
+        returnValue: false,
+      ) as bool);
+
+  @override
+  Iterable<dynamic> get keys => (super.noSuchMethod(
+        Invocation.getter(#keys),
+        returnValue: <dynamic>[],
+      ) as Iterable<dynamic>);
+
+  @override
+  int get length => (super.noSuchMethod(
+        Invocation.getter(#length),
+        returnValue: 0,
+      ) as int);
+
+  @override
+  bool get isEmpty => (super.noSuchMethod(
+        Invocation.getter(#isEmpty),
+        returnValue: false,
+      ) as bool);
+
+  @override
+  bool get isNotEmpty => (super.noSuchMethod(
+        Invocation.getter(#isNotEmpty),
+        returnValue: false,
+      ) as bool);
+
+  @override
+  Iterable<E> valuesBetween({
+    dynamic startKey,
+    dynamic endKey,
+  }) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #valuesBetween,
+          [],
+          {
+            #startKey: startKey,
+            #endKey: endKey,
+          },
+        ),
+        returnValue: <E>[],
+      ) as Iterable<E>);
+
+  @override
+  E? getAt(int? index) => (super.noSuchMethod(Invocation.method(
+        #getAt,
+        [index],
+      )) as E?);
+
+  @override
+  Map<dynamic, E> toMap() => (super.noSuchMethod(
+        Invocation.method(
+          #toMap,
+          [],
+        ),
+        returnValue: <dynamic, E>{},
+      ) as Map<dynamic, E>);
+
+  @override
+  dynamic keyAt(int? index) => super.noSuchMethod(Invocation.method(
+        #keyAt,
+        [index],
+      ));
+
+  @override
+  _i3.Stream<_i2.BoxEvent> watch({dynamic key}) => (super.noSuchMethod(
+        Invocation.method(
+          #watch,
+          [],
+          {#key: key},
+        ),
+        returnValue: _i3.Stream<_i2.BoxEvent>.empty(),
+      ) as _i3.Stream<_i2.BoxEvent>);
+
+  @override
+  bool containsKey(dynamic key) => (super.noSuchMethod(
+        Invocation.method(
+          #containsKey,
+          [key],
+        ),
+        returnValue: false,
+      ) as bool);
+
+  @override
+  _i3.Future<void> put(
+    dynamic key,
+    E? value,
+  ) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #put,
+          [
+            key,
+            value,
+          ],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> putAt(
+    int? index,
+    E? value,
+  ) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #putAt,
+          [
+            index,
+            value,
+          ],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> putAll(Map<dynamic, E>? entries) => (super.noSuchMethod(
+        Invocation.method(
+          #putAll,
+          [entries],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<int> add(E? value) => (super.noSuchMethod(
+        Invocation.method(
+          #add,
+          [value],
+        ),
+        returnValue: _i3.Future<int>.value(0),
+      ) as _i3.Future<int>);
+
+  @override
+  _i3.Future<Iterable<int>> addAll(Iterable<E>? values) => (super.noSuchMethod(
+        Invocation.method(
+          #addAll,
+          [values],
+        ),
+        returnValue: _i3.Future<Iterable<int>>.value(<int>[]),
+      ) as _i3.Future<Iterable<int>>);
+
+  @override
+  _i3.Future<void> delete(dynamic key) => (super.noSuchMethod(
+        Invocation.method(
+          #delete,
+          [key],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> deleteAt(int? index) => (super.noSuchMethod(
+        Invocation.method(
+          #deleteAt,
+          [index],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> deleteAll(Iterable<dynamic>? keys) => (super.noSuchMethod(
+        Invocation.method(
+          #deleteAll,
+          [keys],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> compact() => (super.noSuchMethod(
+        Invocation.method(
+          #compact,
+          [],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<int> clear() => (super.noSuchMethod(
+        Invocation.method(
+          #clear,
+          [],
+        ),
+        returnValue: _i3.Future<int>.value(0),
+      ) as _i3.Future<int>);
+
+  @override
+  _i3.Future<void> close() => (super.noSuchMethod(
+        Invocation.method(
+          #close,
+          [],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> deleteFromDisk() => (super.noSuchMethod(
+        Invocation.method(
+          #deleteFromDisk,
+          [],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> flush() => (super.noSuchMethod(
+        Invocation.method(
+          #flush,
+          [],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+}
+
+/// A class which mocks [Box].
+///
+/// See the documentation for Mockito's code generation for more information.
+class MockHiveBox<E> extends _i1.Mock implements _i2.Box<E> {
+  @override
+  Iterable<E> get values => (super.noSuchMethod(
+        Invocation.getter(#values),
+        returnValue: <E>[],
+        returnValueForMissingStub: <E>[],
+      ) as Iterable<E>);
+
+  @override
+  String get name => (super.noSuchMethod(
+        Invocation.getter(#name),
+        returnValue: _i7.dummyValue<String>(
+          this,
+          Invocation.getter(#name),
+        ),
+        returnValueForMissingStub: _i7.dummyValue<String>(
+          this,
+          Invocation.getter(#name),
+        ),
+      ) as String);
+
+  @override
+  bool get isOpen => (super.noSuchMethod(
+        Invocation.getter(#isOpen),
+        returnValue: false,
+        returnValueForMissingStub: false,
+      ) as bool);
+
+  @override
+  bool get lazy => (super.noSuchMethod(
+        Invocation.getter(#lazy),
+        returnValue: false,
+        returnValueForMissingStub: false,
+      ) as bool);
+
+  @override
+  Iterable<dynamic> get keys => (super.noSuchMethod(
+        Invocation.getter(#keys),
+        returnValue: <dynamic>[],
+        returnValueForMissingStub: <dynamic>[],
+      ) as Iterable<dynamic>);
+
+  @override
+  int get length => (super.noSuchMethod(
+        Invocation.getter(#length),
+        returnValue: 0,
+        returnValueForMissingStub: 0,
+      ) as int);
+
+  @override
+  bool get isEmpty => (super.noSuchMethod(
+        Invocation.getter(#isEmpty),
+        returnValue: false,
+        returnValueForMissingStub: false,
+      ) as bool);
+
+  @override
+  bool get isNotEmpty => (super.noSuchMethod(
+        Invocation.getter(#isNotEmpty),
+        returnValue: false,
+        returnValueForMissingStub: false,
+      ) as bool);
+
+  @override
+  Iterable<E> valuesBetween({
+    dynamic startKey,
+    dynamic endKey,
+  }) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #valuesBetween,
+          [],
+          {
+            #startKey: startKey,
+            #endKey: endKey,
+          },
+        ),
+        returnValue: <E>[],
+        returnValueForMissingStub: <E>[],
+      ) as Iterable<E>);
+
+  @override
+  E? getAt(int? index) => (super.noSuchMethod(
+        Invocation.method(
+          #getAt,
+          [index],
+        ),
+        returnValueForMissingStub: null,
+      ) as E?);
+
+  @override
+  Map<dynamic, E> toMap() => (super.noSuchMethod(
+        Invocation.method(
+          #toMap,
+          [],
+        ),
+        returnValue: <dynamic, E>{},
+        returnValueForMissingStub: <dynamic, E>{},
+      ) as Map<dynamic, E>);
+
+  @override
+  dynamic keyAt(int? index) => super.noSuchMethod(
+        Invocation.method(
+          #keyAt,
+          [index],
+        ),
+        returnValueForMissingStub: null,
+      );
+
+  @override
+  _i3.Stream<_i2.BoxEvent> watch({dynamic key}) => (super.noSuchMethod(
+        Invocation.method(
+          #watch,
+          [],
+          {#key: key},
+        ),
+        returnValue: _i3.Stream<_i2.BoxEvent>.empty(),
+        returnValueForMissingStub: _i3.Stream<_i2.BoxEvent>.empty(),
+      ) as _i3.Stream<_i2.BoxEvent>);
+
+  @override
+  bool containsKey(dynamic key) => (super.noSuchMethod(
+        Invocation.method(
+          #containsKey,
+          [key],
+        ),
+        returnValue: false,
+        returnValueForMissingStub: false,
+      ) as bool);
+
+  @override
+  _i3.Future<void> put(
+    dynamic key,
+    E? value,
+  ) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #put,
+          [
+            key,
+            value,
+          ],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> putAt(
+    int? index,
+    E? value,
+  ) =>
+      (super.noSuchMethod(
+        Invocation.method(
+          #putAt,
+          [
+            index,
+            value,
+          ],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> putAll(Map<dynamic, E>? entries) => (super.noSuchMethod(
+        Invocation.method(
+          #putAll,
+          [entries],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<int> add(E? value) => (super.noSuchMethod(
+        Invocation.method(
+          #add,
+          [value],
+        ),
+        returnValue: _i3.Future<int>.value(0),
+        returnValueForMissingStub: _i3.Future<int>.value(0),
+      ) as _i3.Future<int>);
+
+  @override
+  _i3.Future<Iterable<int>> addAll(Iterable<E>? values) => (super.noSuchMethod(
+        Invocation.method(
+          #addAll,
+          [values],
+        ),
+        returnValue: _i3.Future<Iterable<int>>.value(<int>[]),
+        returnValueForMissingStub: _i3.Future<Iterable<int>>.value(<int>[]),
+      ) as _i3.Future<Iterable<int>>);
+
+  @override
+  _i3.Future<void> delete(dynamic key) => (super.noSuchMethod(
+        Invocation.method(
+          #delete,
+          [key],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> deleteAt(int? index) => (super.noSuchMethod(
+        Invocation.method(
+          #deleteAt,
+          [index],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> deleteAll(Iterable<dynamic>? keys) => (super.noSuchMethod(
+        Invocation.method(
+          #deleteAll,
+          [keys],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> compact() => (super.noSuchMethod(
+        Invocation.method(
+          #compact,
+          [],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<int> clear() => (super.noSuchMethod(
+        Invocation.method(
+          #clear,
+          [],
+        ),
+        returnValue: _i3.Future<int>.value(0),
+        returnValueForMissingStub: _i3.Future<int>.value(0),
+      ) as _i3.Future<int>);
+
+  @override
+  _i3.Future<void> close() => (super.noSuchMethod(
+        Invocation.method(
+          #close,
+          [],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> deleteFromDisk() => (super.noSuchMethod(
+        Invocation.method(
+          #deleteFromDisk,
+          [],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+
+  @override
+  _i3.Future<void> flush() => (super.noSuchMethod(
+        Invocation.method(
+          #flush,
+          [],
+        ),
+        returnValue: _i3.Future<void>.value(),
+        returnValueForMissingStub: _i3.Future<void>.value(),
+      ) as _i3.Future<void>);
+}
diff --git a/test/utils/encryptor_test.dart b/test/utils/encryptor_test.dart
new file mode 100644
index 0000000000..4c311a665c
--- /dev/null
+++ b/test/utils/encryptor_test.dart
@@ -0,0 +1,139 @@
+import 'dart:convert';
+import 'dart:typed_data';
+
+import 'package:crypto/crypto.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:mockito/mockito.dart';
+import 'package:pointycastle/api.dart' as pointy;
+import 'package:pointycastle/asymmetric/oaep.dart';
+import 'package:pointycastle/asymmetric/rsa.dart';
+import 'package:pointycastle/pointycastle.dart';
+import 'package:talawa/models/asymetric_keys/asymetric_keys.dart';
+import 'package:talawa/utils/encryptor.dart';
+import '../helpers/setup_hive.mocks.dart';
+
+// This test is being written believing that in future when Encryptor class will get rid of shouldEncrypt variable then all the tests using that variable can be removed
+void main() {
+  group('When shouldEncrypt is true', () {
+    test('encryptString method should return the encrypted string', () {
+      Encryptor.shouldEncrypt = true;
+      const String inputString = 'password123';
+      final String outputString =
+          sha256.convert(utf8.encode(inputString)).toString();
+      expect(Encryptor.encryptString(inputString), outputString);
+    });
+  });
+// As the bool variable is not used anywhere except in this method so moving ahead with making this variable as false
+// On getting rid of this variable the above test can be removed
+  group('When shouldEncrypt is false', () {
+    late Encryptor encryptor;
+    late AsymmetricKeyPair<PublicKey, PrivateKey> keyPair;
+    late pointy.PublicKey publicKey;
+    late MockHiveInterface mockHiveInterface;
+    late MockBox<AsymetricKeys> mockHiveBox;
+    setUpAll(() {
+      encryptor = Encryptor();
+      Encryptor.shouldEncrypt = false;
+      keyPair = encryptor.generateRSAKeyPair();
+      publicKey = keyPair.publicKey;
+      mockHiveInterface = MockHiveInterface();
+      mockHiveBox = MockBox();
+    });
+    test('encryptString method should return the same string', () {
+      const String inputString = 'password123';
+      expect(Encryptor.encryptString(inputString), inputString);
+    });
+    test(
+        'Correct security options are added while generating keys from generateRSAKeyPair method',
+        () {
+      expect(publicKey, isA<RSAPublicKey>());
+      final RSAPublicKey key = publicKey as RSAPublicKey;
+      expect(key.publicExponent, BigInt.parse('65537'));
+      expect(key.modulus!.bitLength, 2048);
+    });
+    test(
+        'Checking whether Box Names and Key Names are appropriate for Hive or not',
+        () async {
+      when(mockHiveInterface.openBox<AsymetricKeys>('user_keys'))
+          .thenAnswer((realInvocation) async {
+        return mockHiveBox;
+      });
+      await encryptor.saveKeyPair(keyPair, mockHiveInterface);
+      verify(mockHiveInterface.openBox('user_keys'));
+      verify(mockHiveBox.put('key_pair', any));
+    });
+    test('For loadPairKey()', () async {
+      when(mockHiveInterface.openBox<AsymetricKeys>('user_keys'))
+          .thenAnswer((realInvocation) async {
+        return mockHiveBox;
+      });
+      when(mockHiveBox.get('key_pair'))
+          .thenAnswer((realInvocation) => AsymetricKeys(keyPair: keyPair));
+      await encryptor.loadKeyPair(mockHiveInterface);
+      verify(mockHiveBox.get('key_pair'));
+    });
+    test(
+        'For checking whether the data is properly encrypted through RSA by assymetricEncryptString()',
+        () {
+      const String data = 'Hello Talawa';
+      final output = encryptor.assymetricEncryptString(
+        data,
+        keyPair.publicKey as RSAPublicKey,
+      );
+      final cipher = OAEPEncoding(RSAEngine())
+        ..init(false, PrivateKeyParameter<RSAPrivateKey>(keyPair.privateKey));
+      final decryptedBytes = cipher.process(base64Decode(output));
+      expect(String.fromCharCodes(decryptedBytes), data);
+    });
+    test(
+        'For checking whether the data is getting decrypted properly through assymetricDecryptString()',
+        () {
+      const String data = 'Hello Talawa';
+      final cipher = OAEPEncoding(RSAEngine())
+        ..init(true, PublicKeyParameter<RSAPublicKey>(keyPair.publicKey));
+      final encryptedBytes = cipher.process(Uint8List.fromList(data.codeUnits));
+      final output = encryptor.assymetricDecryptString(
+        base64Encode(encryptedBytes),
+        keyPair.privateKey as RSAPrivateKey,
+      );
+      expect(output, data);
+    });
+    test('Test for wrong message sent to receiveMessage()', () {
+      const Map<String, dynamic> message = {"message": "Hello Talawa"};
+      expect(
+        encryptor.receiveMessage(message, mockHiveInterface),
+        throwsException,
+      );
+    });
+    test('Unencrypted message sent to receiveMessage()', () {
+      const Map<String, dynamic> message = {"encryptedMessage": "Hello Talawa"};
+      when(mockHiveInterface.openBox<AsymetricKeys>('user_keys'))
+          .thenAnswer((realInvocation) async {
+        return mockHiveBox;
+      });
+      when(mockHiveBox.get('key_pair'))
+          .thenAnswer((realInvocation) => AsymetricKeys(keyPair: keyPair));
+      expect(
+        encryptor.receiveMessage(message, mockHiveInterface),
+        throwsException,
+      );
+    });
+    test('Encrypted Message sent to receiveMessage()', () {
+      const String data = 'Hello Talawa';
+      final cipher = OAEPEncoding(RSAEngine())
+        ..init(true, PublicKeyParameter<RSAPublicKey>(keyPair.publicKey));
+      final encryptedBytes = cipher.process(Uint8List.fromList(data.codeUnits));
+      final String encryptedMessge = base64Encode(encryptedBytes);
+      final Map<String, dynamic> message = {
+        "encryptedMessage": encryptedMessge,
+      };
+      when(mockHiveInterface.openBox<AsymetricKeys>('user_keys'))
+          .thenAnswer((realInvocation) async {
+        return mockHiveBox;
+      });
+      when(mockHiveBox.get('key_pair'))
+          .thenAnswer((realInvocation) => AsymetricKeys(keyPair: keyPair));
+      expect(encryptor.receiveMessage(message, mockHiveInterface), completes);
+    });
+  });
+}