From bf622640ca60a2cb6f25c3748e92cd7eb88a03ac Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Thu, 20 Oct 2022 18:41:28 +0200 Subject: [PATCH 1/2] Improve robustness of API key tests --- test/test.dart | 32 ++++++++++++-------- test/user_test.dart | 73 +++++++++++++++++++++++++++++---------------- 2 files changed, 68 insertions(+), 37 deletions(-) diff --git a/test/test.dart b/test/test.dart index 1961eb272..77a6c5717 100644 --- a/test/test.dart +++ b/test/test.dart @@ -551,21 +551,29 @@ Future loginWithRetry(App app, Credentials credentials, {int retryCount = } Future waitForCondition( - bool Function() condition, { + FutureOr Function() condition, { Duration timeout = const Duration(seconds: 1), Duration retryDelay = const Duration(milliseconds: 100), String? message, -}) async { - await Future.any([ - Future.delayed(timeout, () => throw TimeoutException('Condition not met within $timeout. Message: ${message != null ? ': $message' : ''}')), - Future.doWhile(() async { - if (condition()) { - return false; - } - await Future.delayed(retryDelay); - return true; - }) - ]); +}) { + return waitForConditionWithResult(() => condition(), (value) => value == true); +} + +Future waitForConditionWithResult(FutureOr Function() getter, FutureOr Function(T value) condition, + {Duration timeout = const Duration(seconds: 1), Duration retryDelay = const Duration(milliseconds: 100), String? message}) async { + final start = DateTime.now(); + while (true) { + final value = await getter(); + if (await condition(value)) { + return value; + } + + if (DateTime.now().difference(start) > timeout) { + throw TimeoutException('Condition not met within $timeout. Message: ${message != null ? ': $message' : ''}'); + } + + await Future.delayed(retryDelay); + } } extension RealmObjectTest on RealmObject { diff --git a/test/user_test.dart b/test/user_test.dart index aec15c39b..c8dca8108 100644 --- a/test/user_test.dart +++ b/test/user_test.dart @@ -117,10 +117,31 @@ Future main([List? args]) async { expect(user.profile.email, testUsername); }); + Future createAndVerifyApiKey(User user, String name) async { + final result = await user.apiKeys.create(name); + await waitForConditionWithResult(() => user.apiKeys.fetch(result.id), (fetched) => fetched != null, timeout: Duration(seconds: 15)); + return result; + } + + Future enableAndVerifyApiKey(User user, ObjectId keyId) async { + await user.apiKeys.enable(keyId); + await waitForConditionWithResult(() => user.apiKeys.fetch(keyId), (fetched) => fetched!.isEnabled, timeout: Duration(seconds: 15)); + } + + Future disableAndVerifyApiKey(User user, ObjectId keyId) async { + await user.apiKeys.disable(keyId); + await waitForConditionWithResult(() => user.apiKeys.fetch(keyId), (fetched) => !fetched!.isEnabled, timeout: Duration(seconds: 15)); + } + + Future deleteAndVerifyApiKey(User user, ObjectId keyId) async { + await user.apiKeys.delete(keyId); + await waitForConditionWithResult(() => user.apiKeys.fetch(keyId), (fetched) => fetched == null, timeout: Duration(seconds: 15)); + } + baasTest('User.apiKeys.create creates and reveals value', (configuration) async { final app = App(configuration); final user = await getIntegrationUser(app); - final apiKey = await user.apiKeys.create('my-api-key'); + final apiKey = await createAndVerifyApiKey(user, 'my-api-key'); expect(apiKey.isEnabled, true); expect(apiKey.name, 'my-api-key'); @@ -170,7 +191,7 @@ Future main([List? args]) async { baasTest('User.apiKeys.fetch with existent returns result', (configuration) async { final app = App(configuration); final user = await getIntegrationUser(app); - final apiKey = await user.apiKeys.create('my-api-key'); + final apiKey = await createAndVerifyApiKey(user, 'my-api-key'); final refetched = await user.apiKeys.fetch(apiKey.id); @@ -189,7 +210,7 @@ Future main([List? args]) async { final app = App(configuration); final user = await getIntegrationUser(app); - final original = await user.apiKeys.create('my-api-key'); + final original = await createAndVerifyApiKey(user, 'my-api-key'); final apiKeys = await user.apiKeys.fetchAll(); @@ -203,7 +224,7 @@ Future main([List? args]) async { final original = []; for (var i = 0; i < 5; i++) { - original.add(await user.apiKeys.create('my-api-key-$i')); + original.add(await createAndVerifyApiKey(user, 'my-api-key-$i')); } final fetched = await user.apiKeys.fetchAll(); @@ -217,7 +238,7 @@ Future main([List? args]) async { final app = App(configuration); final user = await getIntegrationUser(app); - final key = await user.apiKeys.create('key'); + final key = await createAndVerifyApiKey(user, 'key'); await user.apiKeys.delete(ObjectId()); @@ -230,10 +251,10 @@ Future main([List? args]) async { final app = App(configuration); final user = await getIntegrationUser(app); - final toDelete = await user.apiKeys.create('to-delete'); - final toRemain = await user.apiKeys.create('to-remain'); + final toDelete = await createAndVerifyApiKey(user, 'to-delete'); + final toRemain = await createAndVerifyApiKey(user, 'to-remain'); - await user.apiKeys.delete(toDelete.id); + await deleteAndVerifyApiKey(user, toDelete.id); final fetched = await user.apiKeys.fetch(toDelete.id); expect(fetched, isNull); @@ -271,7 +292,7 @@ Future main([List? args]) async { final app = App(configuration); final user = await getIntegrationUser(app); - final key = await user.apiKeys.create('my-key'); + final key = await createAndVerifyApiKey(user, 'my-key'); expect(key.isEnabled, true); @@ -286,11 +307,11 @@ Future main([List? args]) async { final app = App(configuration); final user = await getIntegrationUser(app); - final key = await user.apiKeys.create('my-key'); + final key = await createAndVerifyApiKey(user, 'my-key'); expect(key.isEnabled, true); - await user.apiKeys.disable(key.id); + await disableAndVerifyApiKey(user, key.id); final fetched = await user.apiKeys.fetch(key.id); expect(fetched!.isEnabled, false); @@ -305,15 +326,16 @@ Future main([List? args]) async { final app = App(configuration); final user = await getIntegrationUser(app); - final first = await user.apiKeys.create('first'); - final second = await user.apiKeys.create('second'); + final first = await createAndVerifyApiKey(user, 'first'); + final second = await createAndVerifyApiKey(user, 'second'); expect(first.isEnabled, true); expect(second.isEnabled, true); - await user.apiKeys.disable(first.id); + await disableAndVerifyApiKey(user, first.id); final fetched = await user.apiKeys.fetchAll(); + expect(fetched[0].id, first.id); expect(fetched[0].isEnabled, false); @@ -325,13 +347,13 @@ Future main([List? args]) async { final app = App(configuration); final user = await getIntegrationUser(app); - final first = await user.apiKeys.create('first'); - final second = await user.apiKeys.create('second'); + final first = await createAndVerifyApiKey(user, 'first'); + final second = await createAndVerifyApiKey(user, 'second'); expect(first.isEnabled, true); expect(second.isEnabled, true); - await user.apiKeys.disable(first.id); + await disableAndVerifyApiKey(user, first.id); final fetched = await user.apiKeys.fetchAll(); expect(fetched[0].id, first.id); @@ -340,7 +362,7 @@ Future main([List? args]) async { expect(fetched[1].id, second.id); expect(fetched[1].isEnabled, true); - await user.apiKeys.enable(first.id); + await enableAndVerifyApiKey(user, first.id); final refetched = await user.apiKeys.fetchAll(); expect(refetched[0].id, first.id); @@ -354,7 +376,8 @@ Future main([List? args]) async { final app = App(configuration); final user = await getIntegrationUser(app); - final key = await user.apiKeys.create('my-key'); + final key = await createAndVerifyApiKey(user, 'my-key'); + final credentials = Credentials.apiKey(key.value!); final apiKeyUser = await app.logIn(credentials); @@ -367,9 +390,9 @@ Future main([List? args]) async { final app = App(configuration); final user = await getIntegrationUser(app); - final key = await user.apiKeys.create('my-key'); + final key = await createAndVerifyApiKey(user, 'my-key'); - await user.apiKeys.disable(key.id); + await disableAndVerifyApiKey(user, key.id); final credentials = Credentials.apiKey(key.value!); @@ -380,7 +403,7 @@ Future main([List? args]) async { .having((e) => e.statusCode, 'statusCode', 401) .having((e) => e.linkToServerLogs, 'linkToServerLogs', contains('logs?co_id=')))); - await user.apiKeys.enable(key.id); + await enableAndVerifyApiKey(user, key.id); final apiKeyUser = await app.logIn(credentials); expect(apiKeyUser.provider, AuthProviderType.apiKey); @@ -392,9 +415,9 @@ Future main([List? args]) async { final app = App(configuration); final user = await getIntegrationUser(app); - final key = await user.apiKeys.create('my-key'); + final key = await createAndVerifyApiKey(user, 'my-key'); - await user.apiKeys.delete(key.id); + await deleteAndVerifyApiKey(user, key.id); final credentials = Credentials.apiKey(key.value!); @@ -433,7 +456,7 @@ Future main([List? args]) async { baasTest("Credentials.apiKey user cannot access API keys", (configuration) async { final app = App(configuration); final user = await getIntegrationUser(app); - final apiKey = await user.apiKeys.create('my-key'); + final apiKey = await createAndVerifyApiKey(user, 'my-key'); final apiKeyUser = await app.logIn(Credentials.apiKey(apiKey.value!)); From cd8bf52e62ce5c9682397f396532034f13010357 Mon Sep 17 00:00:00 2001 From: Nikola Irinchev Date: Thu, 20 Oct 2022 21:17:53 +0200 Subject: [PATCH 2/2] Update metrics.g.dart --- lib/src/cli/metrics/metrics.g.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/cli/metrics/metrics.g.dart b/lib/src/cli/metrics/metrics.g.dart index f8352e52b..d92e95bbc 100644 --- a/lib/src/cli/metrics/metrics.g.dart +++ b/lib/src/cli/metrics/metrics.g.dart @@ -61,7 +61,7 @@ Map _$PropertiesToJson(Properties instance) { val['Realm Version'] = instance.realmVersion; val['Host OS Type'] = instance.hostOsType; val['Host OS Version'] = instance.hostOsVersion; - val['Target OS Type'] = _$TargetOsTypeEnumMap[instance.targetOsType]; + writeNotNull('Target OS Type', _$TargetOsTypeEnumMap[instance.targetOsType]); writeNotNull('Target OS Version', instance.targetOsVersion); return val; }