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