Fix/Update #1
							
								
								
									
										192
									
								
								packages/native_crypto/test/src/cipher_text_test.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								packages/native_crypto/test/src/cipher_text_test.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,192 @@ | ||||
| // Author: Hugo Pointcheval | ||||
| // Email: git@pcl.ovh | ||||
| // ----- | ||||
| // File: cipher_text_test.dart | ||||
| // Created Date: 26/05/2022 20:45:38 | ||||
| // Last Modified: 26/05/2022 21:29:51 | ||||
| // ----- | ||||
| // Copyright (c) 2022 | ||||
| 
 | ||||
| import 'dart:typed_data'; | ||||
| 
 | ||||
| import 'package:flutter_test/flutter_test.dart'; | ||||
| import 'package:native_crypto/native_crypto.dart'; | ||||
| 
 | ||||
| void main() { | ||||
|   setUp(() { | ||||
|     Cipher.bytesCountPerChunk = Cipher.defaultBytesCountPerChunk; | ||||
|   }); | ||||
| 
 | ||||
|   group('fromBytes', () { | ||||
|     test('throws if length is not the one expected', () { | ||||
|       final Uint8List bytes = Uint8List.fromList([1, 2, 3, 4, 5]); | ||||
|       expect( | ||||
|         () => CipherText.fromBytes( | ||||
|           bytes, | ||||
|           ivLength: 1, | ||||
|           messageLength: 1, | ||||
|           tagLength: 1, | ||||
|         ), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_argument', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('Invalid cipher text length'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('throws if length is bigger than expected', () { | ||||
|       final Uint8List bytes = Uint8List.fromList([1, 3, 3, 3, 1]); | ||||
|       Cipher.bytesCountPerChunk = 2; | ||||
|       expect( | ||||
|         () => CipherText.fromBytes( | ||||
|           bytes, | ||||
|           ivLength: 1, | ||||
|           messageLength: 3, | ||||
|           tagLength: 1, | ||||
|         ), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_argument', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('Cipher text is too big'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('throws if data is empty', () { | ||||
|       final Uint8List bytes = Uint8List(0); | ||||
|       expect( | ||||
|         () => CipherText.fromBytes( | ||||
|           bytes, | ||||
|           ivLength: 1, | ||||
|           messageLength: 3, | ||||
|           tagLength: 1, | ||||
|         ), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_argument', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('Passed data is empty'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('throws if one of the length is negative', () { | ||||
|       final Uint8List bytes = Uint8List(0); | ||||
|       expect( | ||||
|         () => CipherText.fromBytes( | ||||
|           bytes, | ||||
|           ivLength: -1, | ||||
|           messageLength: 1, | ||||
|           tagLength: 1, | ||||
|         ), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_argument', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('Invalid length'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   group('get.cipherAlgorithm', () { | ||||
|     test('throws if not set', () { | ||||
|       final CipherText cipherText = CipherText.fromBytes( | ||||
|         Uint8List.fromList([1, 2, 3]), | ||||
|         ivLength: 1, | ||||
|         messageLength: 1, | ||||
|         tagLength: 1, | ||||
|       ); | ||||
|       expect( | ||||
|         () => cipherText.cipherAlgorithm, | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_cipher', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('Cipher algorithm is not specified'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('returns the expected value', () { | ||||
|       final CipherText cipherText = CipherText.fromBytes( | ||||
|         Uint8List.fromList([1, 2, 3]), | ||||
|         ivLength: 1, | ||||
|         messageLength: 1, | ||||
|         tagLength: 1, | ||||
|         cipherAlgorithm: CipherAlgorithm.aes, | ||||
|       ); | ||||
|       expect(cipherText.cipherAlgorithm, CipherAlgorithm.aes); | ||||
|     }); | ||||
|   }); | ||||
|    | ||||
|   group('Lengths', () { | ||||
|     test('get.ivLength returns the expected value', () { | ||||
|       final CipherText cipherText = CipherText.fromBytes( | ||||
|         Uint8List.fromList([1, 2, 3]), | ||||
|         ivLength: 1, | ||||
|         messageLength: 1, | ||||
|         tagLength: 1, | ||||
|       ); | ||||
|       expect(cipherText.ivLength, 1); | ||||
|     }); | ||||
| 
 | ||||
|     test('get.messageLength returns the expected value', () { | ||||
|       final CipherText cipherText = CipherText.fromBytes( | ||||
|         Uint8List.fromList([1, 2, 3]), | ||||
|         ivLength: 1, | ||||
|         messageLength: 1, | ||||
|         tagLength: 1, | ||||
|       ); | ||||
|       expect(cipherText.messageLength, 1); | ||||
|     }); | ||||
| 
 | ||||
|     test('get.tagLength returns the expected value', () { | ||||
|       final CipherText cipherText = CipherText.fromBytes( | ||||
|         Uint8List.fromList([1, 2, 3]), | ||||
|         ivLength: 1, | ||||
|         messageLength: 1, | ||||
|         tagLength: 1, | ||||
|       ); | ||||
|       expect(cipherText.tagLength, 1); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
							
								
								
									
										327
									
								
								packages/native_crypto/test/src/cipher_text_wrapper_test.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								packages/native_crypto/test/src/cipher_text_wrapper_test.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,327 @@ | ||||
| // Author: Hugo Pointcheval | ||||
| // Email: git@pcl.ovh | ||||
| // ----- | ||||
| // File: cipher_text_wrapper_test.dart | ||||
| // Created Date: 26/05/2022 21:35:41 | ||||
| // Last Modified: 26/05/2022 22:27:31 | ||||
| // ----- | ||||
| // Copyright (c) 2022 | ||||
| 
 | ||||
| import 'dart:typed_data'; | ||||
| 
 | ||||
| import 'package:flutter_test/flutter_test.dart'; | ||||
| import 'package:native_crypto/native_crypto.dart'; | ||||
| 
 | ||||
| void main() { | ||||
|   late CipherText single; | ||||
|   late List<CipherText> list; | ||||
| 
 | ||||
|   setUp(() { | ||||
|     Cipher.bytesCountPerChunk = Cipher.defaultBytesCountPerChunk; | ||||
|     single = CipherText.fromBytes( | ||||
|       Uint8List.fromList([1, 2, 3]), | ||||
|       ivLength: 1, | ||||
|       messageLength: 1, | ||||
|       tagLength: 1, | ||||
|     ); | ||||
|     list = [ | ||||
|       CipherText.fromBytes( | ||||
|         Uint8List.fromList([1, 2, 3]), | ||||
|         ivLength: 1, | ||||
|         messageLength: 1, | ||||
|         tagLength: 1, | ||||
|       ), | ||||
|       CipherText.fromBytes( | ||||
|         Uint8List.fromList([4, 5, 6]), | ||||
|         ivLength: 1, | ||||
|         messageLength: 1, | ||||
|         tagLength: 1, | ||||
|       ), | ||||
|     ]; | ||||
|   }); | ||||
| 
 | ||||
|   group('single', () { | ||||
|     test('makes isSingle true', () { | ||||
|       final wrapper = CipherTextWrapper.single(single); | ||||
|       expect(wrapper.isSingle, isTrue); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes isList false', () { | ||||
|       final wrapper = CipherTextWrapper.single(single); | ||||
|       expect(wrapper.isList, isFalse); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes CipherText the single value', () { | ||||
|       final wrapper = CipherTextWrapper.single(single); | ||||
|       expect(wrapper.single, single); | ||||
|     }); | ||||
| 
 | ||||
|     test('throws when trying to get list', () { | ||||
|       final wrapper = CipherTextWrapper.single(single); | ||||
|       expect( | ||||
|         () => wrapper.list, | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_data', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('is not list'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes wrapper returns bytes of CipherText', () { | ||||
|       final wrapper = CipherTextWrapper.single(single); | ||||
|       expect(wrapper.bytes, single.bytes); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes chunkCount = 1', () { | ||||
|       final wrapper = CipherTextWrapper.single(single); | ||||
|       expect(wrapper.chunkCount, 1); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes unwrap() returns only CipherText', () { | ||||
|       final wrapper = CipherTextWrapper.single(single); | ||||
|       expect(wrapper.unwrap<CipherText>(), single); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes unwrap() throws when trying to unwrap List', () { | ||||
|       final wrapper = CipherTextWrapper.single(single); | ||||
|       expect( | ||||
|         () => wrapper.unwrap<List<CipherText>>(), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_data', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('you should use unwrap'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes adding is not supported', () { | ||||
|       final wrapper = CipherTextWrapper.single(single); | ||||
|       expect( | ||||
|         () => wrapper.add(single), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_data', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('is already single'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   group('list', () { | ||||
|     test('makes isList true', () { | ||||
|       final wrapper = CipherTextWrapper.list(list); | ||||
|       expect(wrapper.isList, isTrue); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes isSingle false', () { | ||||
|       final wrapper = CipherTextWrapper.list(list); | ||||
|       expect(wrapper.isSingle, isFalse); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes List<CipherText> the list value', () { | ||||
|       final wrapper = CipherTextWrapper.list(list); | ||||
|       expect(wrapper.list, list); | ||||
|     }); | ||||
| 
 | ||||
|     test('throws when trying to get single', () { | ||||
|       final wrapper = CipherTextWrapper.list(list); | ||||
|       expect( | ||||
|         () => wrapper.single, | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_data', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('is not single'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes wrapper returns bytes of all CipherText joined', () { | ||||
|       final wrapper = CipherTextWrapper.list(list); | ||||
|       expect(wrapper.bytes, Uint8List.fromList([1, 2, 3, 4, 5, 6])); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes chunkCount = 2', () { | ||||
|       final wrapper = CipherTextWrapper.list(list); | ||||
|       expect(wrapper.chunkCount, 2); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes unwrap() returns List<CipherText>', () { | ||||
|       final wrapper = CipherTextWrapper.list(list); | ||||
|       expect(wrapper.unwrap<List<CipherText>>(), list); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes unwrap() throws when trying to unwrap single', () { | ||||
|       final wrapper = CipherTextWrapper.list(list); | ||||
|       expect( | ||||
|         () => wrapper.unwrap<CipherText>(), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_data', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('you should use unwrap'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes adding is supported', () { | ||||
|       final originalList = List<CipherText>.from(list); | ||||
|       final wrapper = CipherTextWrapper.list(list)..add(single); | ||||
|       printOnFailure(list.length.toString()); | ||||
|       expect(wrapper.list, [...originalList, single]); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   group('empty', () { | ||||
|     test('makes isList true', () { | ||||
|       final wrapper = CipherTextWrapper.empty(); | ||||
|       expect(wrapper.isList, isTrue); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes isSingle false', () { | ||||
|       final wrapper = CipherTextWrapper.empty(); | ||||
|       expect(wrapper.isSingle, isFalse); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes List<CipherText> the list value', () { | ||||
|       final wrapper = CipherTextWrapper.empty(); | ||||
|       expect(wrapper.list, <CipherText>[]); | ||||
|     }); | ||||
| 
 | ||||
|     test('throws when trying to get single', () { | ||||
|       final wrapper = CipherTextWrapper.empty(); | ||||
|       expect( | ||||
|         () => wrapper.single, | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_data', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('is not single'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes wrapper returns empty bytes', () { | ||||
|       final wrapper = CipherTextWrapper.empty(); | ||||
|       expect(wrapper.bytes, Uint8List.fromList([])); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes chunkCount = 0', () { | ||||
|       final wrapper = CipherTextWrapper.empty(); | ||||
|       expect(wrapper.chunkCount, 0); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes unwrap() returns empty List<CipherText>', () { | ||||
|       final wrapper = CipherTextWrapper.empty(); | ||||
|       expect(wrapper.unwrap<List<CipherText>>(), <CipherText>[]); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes unwrap() throws when trying to unwrap single', () { | ||||
|       final wrapper = CipherTextWrapper.empty(); | ||||
|       expect( | ||||
|         () => wrapper.unwrap<CipherText>(), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_data', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('you should use unwrap'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('makes adding is supported', () { | ||||
|       final wrapper = CipherTextWrapper.empty()..add(single); | ||||
|       expect(wrapper.list, [single]); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   group('fromBytes', () { | ||||
|     test('creates single from bytes when no too big', () { | ||||
|       final wrapper = CipherTextWrapper.fromBytes( | ||||
|         Uint8List.fromList([1, 2, 3]), | ||||
|         ivLength: 1, | ||||
|         messageLength: 1, | ||||
|         tagLength: 1, | ||||
|       ); | ||||
|       expect(wrapper.isSingle, isTrue); | ||||
|       expect(wrapper.single, single); | ||||
|     }); | ||||
| 
 | ||||
|     test('creates list from bytes when too big', () { | ||||
|       Cipher.bytesCountPerChunk = 3; | ||||
|       final wrapper = CipherTextWrapper.fromBytes( | ||||
|         Uint8List.fromList([1, 2, 3, 4, 5, 6]), | ||||
|         ivLength: 1, | ||||
|         messageLength: 1, | ||||
|         tagLength: 1, | ||||
|       ); | ||||
|       expect(wrapper.isList, isTrue); | ||||
|       expect(wrapper.list, list); | ||||
|     }); | ||||
| 
 | ||||
|     test('modifies Cipher.bytesCountPerChunk', () { | ||||
|       expect(Cipher.bytesCountPerChunk, Cipher.defaultBytesCountPerChunk); | ||||
|       CipherTextWrapper.fromBytes( | ||||
|         Uint8List.fromList([1, 2, 3]), | ||||
|         ivLength: 1, | ||||
|         messageLength: 1, | ||||
|         tagLength: 1, | ||||
|         chunkSize: 3, | ||||
|       ); | ||||
|       expect(Cipher.bytesCountPerChunk, 3); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
							
								
								
									
										128
									
								
								packages/native_crypto/test/src/hash_algorithm_test.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								packages/native_crypto/test/src/hash_algorithm_test.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | ||||
| // Author: Hugo Pointcheval | ||||
| // Email: git@pcl.ovh | ||||
| // ----- | ||||
| // File: hash_algorithm_test.dart | ||||
| // Created Date: 26/05/2022 22:28:53 | ||||
| // Last Modified: 26/05/2022 23:03:03 | ||||
| // ----- | ||||
| // Copyright (c) 2022 | ||||
| 
 | ||||
| import 'dart:typed_data'; | ||||
| 
 | ||||
| import 'package:flutter/services.dart'; | ||||
| import 'package:flutter_test/flutter_test.dart'; | ||||
| import 'package:native_crypto/src/utils/hash_algorithm.dart'; | ||||
| import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart'; | ||||
| 
 | ||||
| import '../mocks/mock_native_crypto_platform.dart'; | ||||
| 
 | ||||
| void main() { | ||||
|   final MockNativeCryptoPlatform mock = MockNativeCryptoPlatform(); | ||||
|   NativeCryptoPlatform.instance = mock; | ||||
| 
 | ||||
|   group('name', () { | ||||
|     test('is sha256 for HashAlgorithm.sha256', () { | ||||
|       expect(HashAlgorithm.sha256.name, 'sha256'); | ||||
|     }); | ||||
|     test('is sha384 for HashAlgorithm.sha384', () { | ||||
|       expect(HashAlgorithm.sha384.name, 'sha384'); | ||||
|     }); | ||||
|     test('is sha512 for HashAlgorithm.sha512', () { | ||||
|       expect(HashAlgorithm.sha512.name, 'sha512'); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   group('digest', () { | ||||
|     test('handles returning empty list', () async { | ||||
|       mock | ||||
|         ..setDigestExpectations( | ||||
|           data: Uint8List.fromList([1, 2, 3]), | ||||
|           algorithm: 'sha256', | ||||
|         ) | ||||
|         ..setResponse(() => Uint8List(0)); | ||||
| 
 | ||||
|       await expectLater( | ||||
|         () => HashAlgorithm.sha256.digest(Uint8List.fromList([1, 2, 3])), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>().having( | ||||
|             (e) => e.code, | ||||
|             'code', | ||||
|             'platform_returned_empty_data', | ||||
|           ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles returning null', () async { | ||||
|       mock | ||||
|         ..setDigestExpectations( | ||||
|           data: Uint8List.fromList([1, 2, 3]), | ||||
|           algorithm: 'sha256', | ||||
|         ) | ||||
|         ..setResponse(() => null); | ||||
| 
 | ||||
|       await expectLater( | ||||
|         () => HashAlgorithm.sha256.digest(Uint8List.fromList([1, 2, 3])), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>().having( | ||||
|             (e) => e.code, | ||||
|             'code', | ||||
|             'platform_returned_null', | ||||
|           ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles throwing PlatformException', () async { | ||||
|       mock | ||||
|         ..setDigestExpectations( | ||||
|           data: Uint8List.fromList([1, 2, 3]), | ||||
|           algorithm: 'sha256', | ||||
|         ) | ||||
|         ..setResponse( | ||||
|           () => throw PlatformException( | ||||
|             code: 'native_crypto', | ||||
|             message: 'dummy error', | ||||
|           ), | ||||
|         ); | ||||
| 
 | ||||
|       await expectLater( | ||||
|         () => HashAlgorithm.sha256.digest(Uint8List.fromList([1, 2, 3])), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 'PlatformException(native_crypto, dummy error, null, null)', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'platform_throws', | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('returns data on success', () async { | ||||
|       final hash = Uint8List.fromList([4, 5, 6]); | ||||
|       mock | ||||
|         ..setDigestExpectations( | ||||
|           data: Uint8List.fromList([1, 2, 3]), | ||||
|           algorithm: 'sha256', | ||||
|         ) | ||||
|         ..setResponse(() => hash); | ||||
| 
 | ||||
|       final result = await HashAlgorithm.sha256.digest( | ||||
|         Uint8List.fromList( | ||||
|           [1, 2, 3], | ||||
|         ), | ||||
|       ); | ||||
| 
 | ||||
|       expect( | ||||
|         result, | ||||
|         hash, | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
							
								
								
									
										280
									
								
								packages/native_crypto/test/src/pbkdf2_test.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								packages/native_crypto/test/src/pbkdf2_test.dart
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,280 @@ | ||||
| // Author: Hugo Pointcheval | ||||
| // Email: git@pcl.ovh | ||||
| // ----- | ||||
| // File: pbkdf2_test.dart | ||||
| // Created Date: 26/05/2022 22:37:27 | ||||
| // Last Modified: 26/05/2022 23:20:11 | ||||
| // ----- | ||||
| // Copyright (c) 2022 | ||||
| 
 | ||||
| import 'dart:typed_data'; | ||||
| 
 | ||||
| import 'package:flutter/services.dart'; | ||||
| import 'package:flutter_test/flutter_test.dart'; | ||||
| import 'package:native_crypto/native_crypto.dart'; | ||||
| import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart'; | ||||
| 
 | ||||
| import '../mocks/mock_native_crypto_platform.dart'; | ||||
| 
 | ||||
| void main() { | ||||
|   final MockNativeCryptoPlatform mock = MockNativeCryptoPlatform(); | ||||
|   NativeCryptoPlatform.instance = mock; | ||||
| 
 | ||||
|   group('Constructor', () { | ||||
|     test('throws if keyBytesCount is negative', () { | ||||
|       expect( | ||||
|         () => Pbkdf2(keyBytesCount: -1, iterations: 10000), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_argument', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('must be positive'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('throws if iterations is negative or 0', () { | ||||
|       expect( | ||||
|         () => Pbkdf2(keyBytesCount: 32, iterations: -1), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_argument', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('must be strictly positive'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   group('derive', () { | ||||
|     test('throws if password is null', () async { | ||||
|       final pbkdf2 = Pbkdf2(keyBytesCount: 32, iterations: 10000); | ||||
|       await expectLater( | ||||
|         () => pbkdf2.derive( | ||||
|           salt: 'salt', | ||||
|         ), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_argument', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('cannot be null'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('throws if salt is null', () async { | ||||
|       final pbkdf2 = Pbkdf2(keyBytesCount: 32, iterations: 10000); | ||||
|       await expectLater( | ||||
|         () => pbkdf2.derive( | ||||
|           password: 'password', | ||||
|         ), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'invalid_argument', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 contains('cannot be null'), | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles returning empty list', () async { | ||||
|       mock | ||||
|         ..setPbkdf2Expectations( | ||||
|           password: 'password', | ||||
|           salt: 'salt', | ||||
|           keyBytesCount: 32, | ||||
|           iterations: 10000, | ||||
|           algorithm: 'sha256', | ||||
|         ) | ||||
|         ..setResponse(() => Uint8List(0)); | ||||
| 
 | ||||
|       final pbkdf2 = Pbkdf2(keyBytesCount: 32, iterations: 10000); | ||||
| 
 | ||||
|       await expectLater( | ||||
|         () => pbkdf2.derive( | ||||
|           password: 'password', | ||||
|           salt: 'salt', | ||||
|         ), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>().having( | ||||
|             (e) => e.code, | ||||
|             'code', | ||||
|             'platform_returned_empty_data', | ||||
|           ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles returning null', () async { | ||||
|       mock | ||||
|         ..setPbkdf2Expectations( | ||||
|           password: 'password', | ||||
|           salt: 'salt', | ||||
|           keyBytesCount: 32, | ||||
|           iterations: 10000, | ||||
|           algorithm: 'sha256', | ||||
|         ) | ||||
|         ..setResponse(() => null); | ||||
| 
 | ||||
|       final pbkdf2 = Pbkdf2(keyBytesCount: 32, iterations: 10000); | ||||
| 
 | ||||
|       await expectLater( | ||||
|         () => pbkdf2.derive( | ||||
|           password: 'password', | ||||
|           salt: 'salt', | ||||
|         ), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>().having( | ||||
|             (e) => e.code, | ||||
|             'code', | ||||
|             'platform_returned_null', | ||||
|           ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles returning data with wrong length', () async { | ||||
|       mock | ||||
|         ..setPbkdf2Expectations( | ||||
|           password: 'password', | ||||
|           salt: 'salt', | ||||
|           keyBytesCount: 32, | ||||
|           iterations: 10000, | ||||
|           algorithm: 'sha256', | ||||
|         ) | ||||
|         ..setResponse(() => Uint8List(33)); | ||||
| 
 | ||||
|       final pbkdf2 = Pbkdf2(keyBytesCount: 32, iterations: 10000); | ||||
| 
 | ||||
|       await expectLater( | ||||
|         () => pbkdf2.derive( | ||||
|           password: 'password', | ||||
|           salt: 'salt', | ||||
|         ), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>().having( | ||||
|             (e) => e.code, | ||||
|             'code', | ||||
|             'platform_returned_invalid_data', | ||||
|           ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles throwing PlatformException', () async { | ||||
|       mock | ||||
|         ..setPbkdf2Expectations( | ||||
|           password: 'password', | ||||
|           salt: 'salt', | ||||
|           keyBytesCount: 32, | ||||
|           iterations: 10000, | ||||
|           algorithm: 'sha256', | ||||
|         ) | ||||
|         ..setResponse( | ||||
|           () => throw PlatformException( | ||||
|             code: 'native_crypto', | ||||
|             message: 'dummy error', | ||||
|           ), | ||||
|         ); | ||||
| 
 | ||||
|       final pbkdf2 = Pbkdf2(keyBytesCount: 32, iterations: 10000); | ||||
| 
 | ||||
|       await expectLater( | ||||
|         () => pbkdf2.derive( | ||||
|           password: 'password', | ||||
|           salt: 'salt', | ||||
|         ), | ||||
|         throwsA( | ||||
|           isA<NativeCryptoException>() | ||||
|               .having( | ||||
|                 (e) => e.message, | ||||
|                 'message', | ||||
|                 'PlatformException(native_crypto, dummy error, null, null)', | ||||
|               ) | ||||
|               .having( | ||||
|                 (e) => e.code, | ||||
|                 'code', | ||||
|                 'platform_throws', | ||||
|               ), | ||||
|         ), | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('returns SecretKey on success', () async { | ||||
|       final data = Uint8List.fromList([1, 2, 3, 4, 5, 6]); | ||||
|       final sk = SecretKey(data); | ||||
|       mock | ||||
|         ..setPbkdf2Expectations( | ||||
|           password: 'password', | ||||
|           salt: 'salt', | ||||
|           keyBytesCount: 6, | ||||
|           iterations: 10000, | ||||
|           algorithm: 'sha256', | ||||
|         ) | ||||
|         ..setResponse(() => data); | ||||
| 
 | ||||
|       final pbkdf = Pbkdf2(keyBytesCount: 6, iterations: 10000); | ||||
|       final result = await pbkdf.derive( | ||||
|         password: 'password', | ||||
|         salt: 'salt', | ||||
|       ); | ||||
| 
 | ||||
|       expect( | ||||
|         result, | ||||
|         sk, | ||||
|       ); | ||||
|     }); | ||||
| 
 | ||||
|     test('return empty SecretKey when keyBytesCount is set to 0', () async { | ||||
|       final sk = SecretKey(Uint8List(0)); | ||||
|       mock | ||||
|         ..setPbkdf2Expectations( | ||||
|           password: 'password', | ||||
|           salt: 'salt', | ||||
|           keyBytesCount: 0, | ||||
|           iterations: 10000, | ||||
|           algorithm: 'sha256', | ||||
|         ) | ||||
|         ..setResponse(() => Uint8List(0)); | ||||
| 
 | ||||
|       final pbkdf = Pbkdf2(keyBytesCount: 0, iterations: 10000); | ||||
|       final result = await pbkdf.derive( | ||||
|         password: 'password', | ||||
|         salt: 'salt', | ||||
|       ); | ||||
| 
 | ||||
|       expect( | ||||
|         result, | ||||
|         sk, | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| @ -3,7 +3,7 @@ | ||||
| // ----- | ||||
| // File: secret_key_test.dart | ||||
| // Created Date: 26/05/2022 10:52:41 | ||||
| // Last Modified: 26/05/2022 19:24:44 | ||||
| // Last Modified: 26/05/2022 22:38:07 | ||||
| // ----- | ||||
| // Copyright (c) 2022 | ||||
| 
 | ||||
| @ -20,6 +20,32 @@ void main() { | ||||
|   final MockNativeCryptoPlatform mock = MockNativeCryptoPlatform(); | ||||
|   NativeCryptoPlatform.instance = mock; | ||||
| 
 | ||||
|   group('Constructors', () { | ||||
|     test('handles Uint8List', () { | ||||
|       final SecretKey key = SecretKey(Uint8List.fromList([1, 2, 3, 4, 5])); | ||||
| 
 | ||||
|       expect(key.bytes, Uint8List.fromList([1, 2, 3, 4, 5])); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles base16', () { | ||||
|       final SecretKey key = SecretKey.fromBase16('0102030405'); | ||||
| 
 | ||||
|       expect(key.bytes, Uint8List.fromList([1, 2, 3, 4, 5])); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles base64', () { | ||||
|       final SecretKey key = SecretKey.fromBase64('AQIDBAU='); | ||||
| 
 | ||||
|       expect(key.bytes, Uint8List.fromList([1, 2, 3, 4, 5])); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles utf8', () { | ||||
|       final SecretKey key = SecretKey.fromUtf8('ABCDE'); | ||||
| 
 | ||||
|       expect(key.bytes, Uint8List.fromList([65, 66, 67, 68, 69])); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   group('fromSecureRandom', () { | ||||
|     test('handles returning random bytes', () async { | ||||
|       mock | ||||
| @ -96,30 +122,4 @@ void main() { | ||||
|       ); | ||||
|     }); | ||||
|   }); | ||||
|    | ||||
|   group('Constructors', () { | ||||
|     test('handles Uint8List', () { | ||||
|       final SecretKey key = SecretKey(Uint8List.fromList([1, 2, 3, 4, 5])); | ||||
| 
 | ||||
|       expect(key.bytes, Uint8List.fromList([1, 2, 3, 4, 5])); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles base16', () { | ||||
|       final SecretKey key = SecretKey.fromBase16('0102030405'); | ||||
| 
 | ||||
|       expect(key.bytes, Uint8List.fromList([1, 2, 3, 4, 5])); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles base64', () { | ||||
|       final SecretKey key = SecretKey.fromBase64('AQIDBAU='); | ||||
| 
 | ||||
|       expect(key.bytes, Uint8List.fromList([1, 2, 3, 4, 5])); | ||||
|     }); | ||||
| 
 | ||||
|     test('handles utf8', () { | ||||
|       final SecretKey key = SecretKey.fromUtf8('ABCDE'); | ||||
| 
 | ||||
|       expect(key.bytes, Uint8List.fromList([65, 66, 67, 68, 69])); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user