Skip to content

Commit

Permalink
fixed tests
Browse files Browse the repository at this point in the history
  • Loading branch information
frankmer committed Nov 2, 2023
1 parent a329472 commit 76a9c58
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 54 deletions.
79 changes: 48 additions & 31 deletions lib/state_notifiers/token_notifier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ import '../utils/view_utils.dart';
import '../widgets/two_step_dialog.dart';

class TokenNotifier extends StateNotifier<TokenState> {
late Future<bool> isInitialized;
Future<void> isLoading = Future.value();
late Future<void> isLoading;
final TokenRepository _repo;
final QrParser _qrParser;
final RsaUtils _rsaUtils;
Expand Down Expand Up @@ -64,16 +63,19 @@ class TokenNotifier extends StateNotifier<TokenState> {
_init();
}

void _init() async {
isInitialized = Future(() async {
Future<void> _init() async {
isLoading = Future(() async {
await loadFromRepo();
return true;
return;
});
await isLoading;
}

void _saveOrReplaceTokensRepo(List<Token> tokens) async {
Future<void> _saveOrReplaceTokensRepo(List<Token> tokens) async {
await isLoading;
isLoading = Future(() async {
final failedTokens = await _repo.saveOrReplaceTokens(tokens);
Logger.warning('Saved Tokens to repo.!!');
if (failedTokens.isNotEmpty) {
Logger.warning(
'Saving tokens failed. Failed Tokens: ${failedTokens.length}',
Expand All @@ -82,16 +84,19 @@ class TokenNotifier extends StateNotifier<TokenState> {
state = state.addOrReplaceTokens(failedTokens);
}
});
await isLoading;
}

void _deleteTokensRepo(List<Token> tokens) async {
Future<void> _deleteTokensRepo(List<Token> tokens) async {
await isLoading;
isLoading = Future(() async {
final failedTokens = await _repo.deleteTokens(tokens);
state = state.addOrReplaceTokens(failedTokens);
if (state.hasPushTokens == false) {
globalRef?.read(settingsProvider.notifier).setHidePushTokens(isHidden: false);
}
});
await isLoading;
}

Future<bool> loadFromRepo() async {
Expand Down Expand Up @@ -129,68 +134,77 @@ class TokenNotifier extends StateNotifier<TokenState> {
return state.tokens.firstWhereOrNull((element) => element.id == id);
}

void incrementCounter(HOTPToken token) {
Future<void> incrementCounter(HOTPToken token) async {
await isLoading;
token = state.currentOf(token)?.copyWith(counter: token.counter + 1) ?? token.copyWith(counter: token.counter + 1);
state = state.replaceToken(token);
_saveOrReplaceTokensRepo([token]);
await _saveOrReplaceTokensRepo([token]);
}

void removeToken(Token token) {
Future<void> removeToken(Token token) async {
await isLoading;
state = state.withoutToken(token);
_deleteTokensRepo([token]);
await _deleteTokensRepo([token]);
}

void addOrReplaceToken(Token token) {
Future<void> addOrReplaceToken(Token token) async {
await isLoading;
state = state.addOrReplaceToken(token);
_saveOrReplaceTokensRepo([token]);
await _saveOrReplaceTokensRepo([token]);
}

void addOrReplaceTokens(List<Token> updatedTokens) {
Future<void> addOrReplaceTokens(List<Token> updatedTokens) async {
await isLoading;
state = state.addOrReplaceTokens(updatedTokens);
_saveOrReplaceTokensRepo(updatedTokens);
await _saveOrReplaceTokensRepo(updatedTokens);
}

void updateToken<T extends Token>(T token, T Function(T) updater) {
Future<void> updateToken<T extends Token>(T token, T Function(T) updater) async {
await isLoading;
final current = state.currentOf<T>(token);
if (current == null) {
Logger.warning('Tried to update a token that does not exist.', name: 'token_notifier.dart#updateToken');
return;
}
final updated = updater(current);
state = state.replaceToken(updated);
_saveOrReplaceTokensRepo([updated]);
await _saveOrReplaceTokensRepo([updated]);
}

void updateTokens<T extends Token>(List<T> token, T Function(T) updater) {
Future<void> updateTokens<T extends Token>(List<T> token, T Function(T) updater) async {
await isLoading;
List<T> updatedTokens = [];
for (final t in token) {
final current = state.currentOf<T>(t) ?? t;
updatedTokens.add(updater(current));
}
state = state.replaceTokens(updatedTokens);
_saveOrReplaceTokensRepo(updatedTokens);
await _saveOrReplaceTokensRepo(updatedTokens);
}

void handleLink(Uri uri) {
Future<void> handleLink(Uri uri) async {
await isLoading;
if (uri.scheme == enumAsString(UriSchemes.otpauth)) {
addTokenFromOtpAuth(otpAuth: uri.toString());
await addTokenFromOtpAuth(otpAuth: uri.toString());
return;
}
if (uri.scheme == enumAsString(UriSchemes.pia)) {
addTokenFromPia(pia: uri.toString());
await addTokenFromPia(pia: uri.toString());
return;
}
showMessage(message: 'Scheme "${uri.scheme}" is not supported', duration: const Duration(seconds: 3));
}

void addTokenFromPia({required String pia}) async {
Future<void> addTokenFromPia({required String pia}) async {
await isLoading;
// TODO: Implement pia:// scheme
showMessage(message: 'Scheme "pia" is not implemented yet', duration: const Duration(seconds: 3));
}

void addTokenFromOtpAuth({
Future<void> addTokenFromOtpAuth({
required String otpAuth,
}) async {
await isLoading;
Logger.info('Try to handle otpAuth:', name: 'token_notifier.dart#addTokenFromOtpAuth');

try {
Expand Down Expand Up @@ -219,23 +233,25 @@ class TokenNotifier extends StateNotifier<TokenState> {
} on FormatException catch (e) {
Logger.warning('Error while parsing otpAuth.', name: 'token_notifier.dart#addTokenFromOtpAuth', error: e);
showMessage(message: e.message, duration: const Duration(seconds: 3));
await isLoading;
return;
}

if (newToken is PushToken && state.tokens.contains(newToken)) {
showMessage(message: 'A token with the serial ${newToken.serial} already exists!', duration: const Duration(seconds: 2));
await isLoading;
return;
}
addOrReplaceToken(newToken);
await addOrReplaceToken(newToken);
if (newToken is PushToken) {
rolloutPushToken(newToken);
await rolloutPushToken(newToken);
}

return;
} on ArgumentError catch (e, s) {
// Error while parsing qr code.
Logger.warning('Malformed QR code:', name: 'token_notifier.dart#_handleOtpAuth', error: e, stackTrace: s);
showMessage(message: '${e.message}\n Please inform the creator of this qr code about the problem.', duration: const Duration(seconds: 8));

return;
}
}
Expand Down Expand Up @@ -282,25 +298,26 @@ class TokenNotifier extends StateNotifier<TokenState> {
return false;
}
// Save the pending request.
updateToken(token, (p0) => p0.withPushRequest(pr));
await updateToken(token, (p0) => p0.withPushRequest(pr));

// Remove the request after it expires.
int time = pr.expirationDate.difference(DateTime.now()).inMilliseconds;
Future.delayed(Duration(milliseconds: time < 1 ? 1 : time), () async => globalRef?.read(tokenProvider.notifier).removePushRequest(pr));

Logger.info('Added push request ${pr.id} to token ${token.id}', name: 'token_notifier.dart#addPushRequestToToken');

return true;
}

bool removePushRequest(PushRequest pushRequest) {
Future<bool> removePushRequest(PushRequest pushRequest) async {
await isLoading;
Logger.info('Removing push request ${pushRequest.id}');
PushToken? token = state.tokens.whereType<PushToken>().firstWhereOrNull((t) => t.serial == pushRequest.serial);

if (token == null) {
Logger.warning('The requested token with serial "${pushRequest.serial}" does not exist.', name: 'token_notifier.dart#removePushRequest');
return false;
}
updateToken<PushToken>(token, (p0) => p0.withoutPushRequest(pushRequest));
await updateToken<PushToken>(token, (p0) => p0.withoutPushRequest(pushRequest));

Logger.info('Removed push request from token ${token.id}', name: 'token_notifier.dart#removePushRequest');
return true;
Expand Down
2 changes: 1 addition & 1 deletion lib/widgets/app_wrapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class ConnectivityListener extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final connectivity = ref.watch(connectivityProvider).asData?.value;
final hasConnection = connectivity != null && connectivity != ConnectivityResult.none;
ref.read(tokenProvider.notifier).isInitialized.then(
ref.read(tokenProvider.notifier).isLoading.then(
(value) {
final hasPushTokens = ref.read(tokenProvider).hasPushTokens;
if (!hasConnection && hasPushTokens) {
Expand Down
29 changes: 7 additions & 22 deletions test/unit_test/state_notifiers/token_notifier_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,7 @@ void _testTokenNotifier() {
),
);
final notifier = container.read(testProvider.notifier);
await notifier.isLoading;
notifier.incrementCounter(before.first);
await notifier.isLoading;
await notifier.incrementCounter(before.first);
final state = container.read(testProvider);
expect(state, isNotNull);
expect(state.tokens, after);
Expand All @@ -129,9 +127,7 @@ void _testTokenNotifier() {
(ref) => TokenNotifier(repository: mockRepo),
);
final notifier = container.read(testProvider.notifier);
await notifier.isLoading;
notifier.removeToken(before.last);
await notifier.isLoading;
await notifier.removeToken(before.last);
final state = container.read(testProvider);
expect(state, isNotNull);
expect(state.tokens, after);
Expand All @@ -156,9 +152,7 @@ void _testTokenNotifier() {
),
);
final notifier = container.read(testProvider.notifier);
await notifier.isLoading;
notifier.addOrReplaceToken(after.last);
await notifier.isLoading;
await notifier.addOrReplaceToken(after.last);
final state = container.read(testProvider);
expect(state, isNotNull);
expect(state.tokens, after);
Expand All @@ -183,9 +177,7 @@ void _testTokenNotifier() {
),
);
final notifier = container.read(testProvider.notifier);
await notifier.isLoading;
notifier.addOrReplaceToken(after.last);
await notifier.isLoading;
await notifier.addOrReplaceToken(after.last);
final state = container.read(testProvider);
expect(state, isNotNull);
expect(state.tokens, after);
Expand All @@ -211,8 +203,7 @@ void _testTokenNotifier() {
),
);
final notifier = container.read(testProvider.notifier);
await notifier.isLoading;
notifier.addOrReplaceTokens([...after]);
await notifier.addOrReplaceTokens([...after]);
final state = container.read(testProvider);
expect(state, isNotNull);
expect(state.tokens, after);
Expand Down Expand Up @@ -243,9 +234,7 @@ void _testTokenNotifier() {
(ref) => TokenNotifier(repository: mockRepo, qrParser: mockQrParser),
);
final notifier = container.read(testProvider.notifier);
await notifier.isLoading;
notifier.addTokenFromOtpAuth(otpAuth: 'otpAuthString');
await notifier.isLoading;
await notifier.addTokenFromOtpAuth(otpAuth: 'otpAuthString');
final state = container.read(testProvider);
expect(state, isNotNull);
after.last = after.last.copyWith(id: state.tokens.last.id);
Expand Down Expand Up @@ -290,7 +279,6 @@ void _testTokenNotifier() {
final notifier = container.read(testProvider.notifier);
expect(await notifier.addPushRequestToToken(pr), true);
final state = container.read(testProvider);
await notifier.isLoading;
expect(state, isNotNull);
expect(state.tokens, after);
verify(mockRepo.saveOrReplaceTokens([after.first])).called(1);
Expand Down Expand Up @@ -320,9 +308,7 @@ void _testTokenNotifier() {
(ref) => TokenNotifier(repository: mockRepo),
);
final notifier = container.read(testProvider.notifier);
await notifier.isLoading;
notifier.removePushRequest(pr);
await notifier.isLoading;
await notifier.removePushRequest(pr);
final state = container.read(testProvider);
expect(state, isNotNull);
expect(state.tokens, after);
Expand Down Expand Up @@ -364,7 +350,6 @@ void _testTokenNotifier() {
);
final notifier = container.read(testProvider.notifier);
expect(await notifier.rolloutPushToken(before.first), true);
await notifier.isLoading;
final state = container.read(testProvider);
expect(state, isNotNull);
expect(state.tokens, after);
Expand Down

0 comments on commit 76a9c58

Please sign in to comment.