test: (WIP) add some tests
This commit is contained in:
parent
c5d42feef4
commit
96f9aad1b3
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
|
// File: secret_key_test.dart
|
||||||
// Created Date: 26/05/2022 10:52:41
|
// 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
|
// Copyright (c) 2022
|
||||||
|
|
||||||
@ -20,6 +20,32 @@ void main() {
|
|||||||
final MockNativeCryptoPlatform mock = MockNativeCryptoPlatform();
|
final MockNativeCryptoPlatform mock = MockNativeCryptoPlatform();
|
||||||
NativeCryptoPlatform.instance = mock;
|
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', () {
|
group('fromSecureRandom', () {
|
||||||
test('handles returning random bytes', () async {
|
test('handles returning random bytes', () async {
|
||||||
mock
|
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