test: (WIP) add mocks and tests for secret key
This commit is contained in:
		
							parent
							
								
									81335dc350
								
							
						
					
					
						commit
						9bfe969c7d
					
				@ -2,7 +2,7 @@ name: native_crypto
 | 
				
			|||||||
description: Fast and secure cryptography for Flutter.
 | 
					description: Fast and secure cryptography for Flutter.
 | 
				
			||||||
version: 0.1.1
 | 
					version: 0.1.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# publish_to: 'none'
 | 
					publish_to: 'none'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
environment:
 | 
					environment:
 | 
				
			||||||
  sdk: ">=2.17.0 <3.0.0"
 | 
					  sdk: ">=2.17.0 <3.0.0"
 | 
				
			||||||
@ -34,6 +34,9 @@ dev_dependencies:
 | 
				
			|||||||
  flutter_test:
 | 
					  flutter_test:
 | 
				
			||||||
    sdk: flutter
 | 
					    sdk: flutter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  mockito: ^5.2.0
 | 
				
			||||||
 | 
					  plugin_platform_interface: ^2.1.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  wyatt_analysis:
 | 
					  wyatt_analysis:
 | 
				
			||||||
    git:
 | 
					    git:
 | 
				
			||||||
      url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
 | 
					      url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,192 @@
 | 
				
			|||||||
 | 
					// Author: Hugo Pointcheval
 | 
				
			||||||
 | 
					// Email: git@pcl.ovh
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					// File: mock_native_crypto_platform.dart
 | 
				
			||||||
 | 
					// Created Date: 25/05/2022 23:34:34
 | 
				
			||||||
 | 
					// Last Modified: 26/05/2022 11:40:24
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					// Copyright (c) 2022
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'dart:typed_data';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'package:flutter_test/flutter_test.dart';
 | 
				
			||||||
 | 
					import 'package:native_crypto_platform_interface/native_crypto_platform_interface.dart';
 | 
				
			||||||
 | 
					import 'package:plugin_platform_interface/plugin_platform_interface.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MockNativeCryptoPlatform extends Fake
 | 
				
			||||||
 | 
					    with MockPlatformInterfaceMixin
 | 
				
			||||||
 | 
					    implements NativeCryptoPlatform {
 | 
				
			||||||
 | 
					  Uint8List? data;
 | 
				
			||||||
 | 
					  List<Uint8List>? dataAsList;
 | 
				
			||||||
 | 
					  Uint8List? key;
 | 
				
			||||||
 | 
					  String? algorithm;
 | 
				
			||||||
 | 
					  int? bitsCount;
 | 
				
			||||||
 | 
					  String? password;
 | 
				
			||||||
 | 
					  String? salt;
 | 
				
			||||||
 | 
					  int? keyBytesCount;
 | 
				
			||||||
 | 
					  int? iterations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Uint8List? Function()? response;
 | 
				
			||||||
 | 
					  List<Uint8List>? Function()? responseAsList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // ignore: use_setters_to_change_properties
 | 
				
			||||||
 | 
					  void setResponse(Uint8List? Function()? response) {
 | 
				
			||||||
 | 
					    this.response = response;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // ignore: use_setters_to_change_properties
 | 
				
			||||||
 | 
					  void setResponseAsList(List<Uint8List>? Function()? responseAsList) {
 | 
				
			||||||
 | 
					    this.responseAsList = responseAsList;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setDecryptExpectations({
 | 
				
			||||||
 | 
					    required Uint8List data,
 | 
				
			||||||
 | 
					    required Uint8List key,
 | 
				
			||||||
 | 
					    required String algorithm,
 | 
				
			||||||
 | 
					  }) {
 | 
				
			||||||
 | 
					    this.data = data;
 | 
				
			||||||
 | 
					    this.key = key;
 | 
				
			||||||
 | 
					    this.algorithm = algorithm;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<Uint8List?> decrypt(
 | 
				
			||||||
 | 
					    Uint8List data,
 | 
				
			||||||
 | 
					    Uint8List key,
 | 
				
			||||||
 | 
					    String algorithm,
 | 
				
			||||||
 | 
					  ) async {
 | 
				
			||||||
 | 
					    expect(data, this.data);
 | 
				
			||||||
 | 
					    expect(key, this.key);
 | 
				
			||||||
 | 
					    expect(algorithm, this.algorithm);
 | 
				
			||||||
 | 
					    return response?.call();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setDecryptAsListExpectations({
 | 
				
			||||||
 | 
					    required List<Uint8List> data,
 | 
				
			||||||
 | 
					    required Uint8List key,
 | 
				
			||||||
 | 
					    required String algorithm,
 | 
				
			||||||
 | 
					  }) {
 | 
				
			||||||
 | 
					    dataAsList = data;
 | 
				
			||||||
 | 
					    this.key = key;
 | 
				
			||||||
 | 
					    this.algorithm = algorithm;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<Uint8List?> decryptAsList(
 | 
				
			||||||
 | 
					    List<Uint8List> data,
 | 
				
			||||||
 | 
					    Uint8List key,
 | 
				
			||||||
 | 
					    String algorithm,
 | 
				
			||||||
 | 
					  ) async {
 | 
				
			||||||
 | 
					    expect(data, dataAsList);
 | 
				
			||||||
 | 
					    expect(key, this.key);
 | 
				
			||||||
 | 
					    expect(algorithm, this.algorithm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return response?.call();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setDigestExpectations({
 | 
				
			||||||
 | 
					    required Uint8List data,
 | 
				
			||||||
 | 
					    required String algorithm,
 | 
				
			||||||
 | 
					  }) {
 | 
				
			||||||
 | 
					    this.data = data;
 | 
				
			||||||
 | 
					    this.algorithm = algorithm;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<Uint8List?> digest(Uint8List data, String algorithm) async {
 | 
				
			||||||
 | 
					    expect(data, this.data);
 | 
				
			||||||
 | 
					    expect(algorithm, this.algorithm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return response?.call();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setEncryptExpectations({
 | 
				
			||||||
 | 
					    required Uint8List data,
 | 
				
			||||||
 | 
					    required Uint8List key,
 | 
				
			||||||
 | 
					    required String algorithm,
 | 
				
			||||||
 | 
					  }) {
 | 
				
			||||||
 | 
					    this.data = data;
 | 
				
			||||||
 | 
					    this.key = key;
 | 
				
			||||||
 | 
					    this.algorithm = algorithm;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<Uint8List?> encrypt(
 | 
				
			||||||
 | 
					    Uint8List data,
 | 
				
			||||||
 | 
					    Uint8List key,
 | 
				
			||||||
 | 
					    String algorithm,
 | 
				
			||||||
 | 
					  ) async {
 | 
				
			||||||
 | 
					    expect(data, this.data);
 | 
				
			||||||
 | 
					    expect(key, this.key);
 | 
				
			||||||
 | 
					    expect(algorithm, this.algorithm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return response?.call();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setEncryptAsListExpectations({
 | 
				
			||||||
 | 
					    required Uint8List data,
 | 
				
			||||||
 | 
					    required Uint8List key,
 | 
				
			||||||
 | 
					    required String algorithm,
 | 
				
			||||||
 | 
					  }) =>
 | 
				
			||||||
 | 
					      setEncryptExpectations(
 | 
				
			||||||
 | 
					        data: data,
 | 
				
			||||||
 | 
					        key: key,
 | 
				
			||||||
 | 
					        algorithm: algorithm,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<List<Uint8List>?> encryptAsList(
 | 
				
			||||||
 | 
					    Uint8List data,
 | 
				
			||||||
 | 
					    Uint8List key,
 | 
				
			||||||
 | 
					    String algorithm,
 | 
				
			||||||
 | 
					  ) async {
 | 
				
			||||||
 | 
					    expect(data, this.data);
 | 
				
			||||||
 | 
					    expect(key, this.key);
 | 
				
			||||||
 | 
					    expect(algorithm, this.algorithm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return responseAsList?.call();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // ignore: use_setters_to_change_properties
 | 
				
			||||||
 | 
					  void setGenerateKeyExpectations({required int bitsCount}) {
 | 
				
			||||||
 | 
					    this.bitsCount = bitsCount;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<Uint8List?> generateSecretKey(int bitsCount) async {
 | 
				
			||||||
 | 
					    expect(bitsCount, this.bitsCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return response?.call();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void setPbkdf2Expectations({
 | 
				
			||||||
 | 
					    required String password,
 | 
				
			||||||
 | 
					    required String salt,
 | 
				
			||||||
 | 
					    required int keyBytesCount,
 | 
				
			||||||
 | 
					    required int iterations,
 | 
				
			||||||
 | 
					    required String algorithm,
 | 
				
			||||||
 | 
					  }) {
 | 
				
			||||||
 | 
					    this.password = password;
 | 
				
			||||||
 | 
					    this.salt = salt;
 | 
				
			||||||
 | 
					    this.iterations = iterations;
 | 
				
			||||||
 | 
					    this.keyBytesCount = keyBytesCount;
 | 
				
			||||||
 | 
					    this.algorithm = algorithm;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<Uint8List?> pbkdf2(
 | 
				
			||||||
 | 
					    String password,
 | 
				
			||||||
 | 
					    String salt,
 | 
				
			||||||
 | 
					    int keyBytesCount,
 | 
				
			||||||
 | 
					    int iterations,
 | 
				
			||||||
 | 
					    String algorithm,
 | 
				
			||||||
 | 
					  ) async {
 | 
				
			||||||
 | 
					    expect(password, this.password);
 | 
				
			||||||
 | 
					    expect(salt, this.salt);
 | 
				
			||||||
 | 
					    expect(keyBytesCount, this.keyBytesCount);
 | 
				
			||||||
 | 
					    expect(iterations, this.iterations);
 | 
				
			||||||
 | 
					    expect(algorithm, this.algorithm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return response?.call();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										125
									
								
								packages/native_crypto/test/src/secret_key_test.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								packages/native_crypto/test/src/secret_key_test.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,125 @@
 | 
				
			|||||||
 | 
					// Author: Hugo Pointcheval
 | 
				
			||||||
 | 
					// Email: git@pcl.ovh
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					// File: secret_key_test.dart
 | 
				
			||||||
 | 
					// Created Date: 26/05/2022 10:52:41
 | 
				
			||||||
 | 
					// Last Modified: 26/05/2022 12:07:33
 | 
				
			||||||
 | 
					// -----
 | 
				
			||||||
 | 
					// Copyright (c) 2022
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'dart:typed_data';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'package:flutter/services.dart';
 | 
				
			||||||
 | 
					import 'package:flutter_test/flutter_test.dart';
 | 
				
			||||||
 | 
					import 'package:native_crypto/src/keys/secret_key.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('fromSecureRandom', () {
 | 
				
			||||||
 | 
					    test('handles returning random bytes', () async {
 | 
				
			||||||
 | 
					      mock
 | 
				
			||||||
 | 
					        ..setGenerateKeyExpectations(bitsCount: 5)
 | 
				
			||||||
 | 
					        ..setResponse(() => Uint8List.fromList([1, 2, 3, 4, 5]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      final SecretKey secretKey = await SecretKey.fromSecureRandom(5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(
 | 
				
			||||||
 | 
					        secretKey.bytes,
 | 
				
			||||||
 | 
					        Uint8List.fromList([1, 2, 3, 4, 5]),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('handles returning empty list', () async {
 | 
				
			||||||
 | 
					      mock
 | 
				
			||||||
 | 
					        ..setGenerateKeyExpectations(bitsCount: 5)
 | 
				
			||||||
 | 
					        ..setResponse(() => Uint8List(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await expectLater(
 | 
				
			||||||
 | 
					        () => SecretKey.fromSecureRandom(5),
 | 
				
			||||||
 | 
					        throwsA(
 | 
				
			||||||
 | 
					          isA<KeyException>().having(
 | 
				
			||||||
 | 
					            (e) => e.code,
 | 
				
			||||||
 | 
					            'code',
 | 
				
			||||||
 | 
					            'platform_returned_null',
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('handles returning null', () async {
 | 
				
			||||||
 | 
					      mock
 | 
				
			||||||
 | 
					        ..setGenerateKeyExpectations(bitsCount: 5)
 | 
				
			||||||
 | 
					        ..setResponse(() => null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await expectLater(
 | 
				
			||||||
 | 
					        () => SecretKey.fromSecureRandom(5),
 | 
				
			||||||
 | 
					        throwsA(
 | 
				
			||||||
 | 
					          isA<KeyException>().having(
 | 
				
			||||||
 | 
					            (e) => e.code,
 | 
				
			||||||
 | 
					            'code',
 | 
				
			||||||
 | 
					            'platform_returned_null',
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test('handles throwing PlatformException', () async {
 | 
				
			||||||
 | 
					      mock
 | 
				
			||||||
 | 
					        ..setGenerateKeyExpectations(bitsCount: 5)
 | 
				
			||||||
 | 
					        ..setResponse(
 | 
				
			||||||
 | 
					          () => throw PlatformException(
 | 
				
			||||||
 | 
					            code: 'native_crypto',
 | 
				
			||||||
 | 
					            message: 'dummy error',
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await expectLater(
 | 
				
			||||||
 | 
					        () => SecretKey.fromSecureRandom(5),
 | 
				
			||||||
 | 
					        throwsA(
 | 
				
			||||||
 | 
					          isA<KeyException>()
 | 
				
			||||||
 | 
					              .having(
 | 
				
			||||||
 | 
					                (e) => e.message,
 | 
				
			||||||
 | 
					                'message',
 | 
				
			||||||
 | 
					                'PlatformException(native_crypto, dummy error, null, null)',
 | 
				
			||||||
 | 
					              )
 | 
				
			||||||
 | 
					              .having(
 | 
				
			||||||
 | 
					                (e) => e.code,
 | 
				
			||||||
 | 
					                'code',
 | 
				
			||||||
 | 
					                'failed_to_generate_secret_key',
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  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