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
|
||||
// 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