diff --git a/CHANGELOG.md b/CHANGELOG.md index f247af67..6362da7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 28.1.0 + +* Added: `createQuery` on `databases`, `documentsDB` and `tablesDB` to send list queries in the request body +* Added: `account.listMemberships` +* Added: `bundleId` and `environment` on `account.createPushTarget` and `account.updatePushTarget` for APNs routing +* Fixed: OAuth2 sign-in on Windows and Linux returns through a loopback callback and creates the session; a denied sign-in throws its error instead of opening the `failure` URL +* Fixed: saving the OAuth2 session waits for client initialisation already in progress + ## 28.0.0 * Breaking: requests send `X-Appwrite-Response-Format: 2.5.0`; responses follow the 2.5 shapes diff --git a/README.md b/README.md index 99066c04..0cca741c 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Or add it to your app's `pubspec.yaml` file and run `flutter pub get`: ```yaml dependencies: - appwrite: ^28.0.0 + appwrite: ^28.1.0 ``` ### Android requirements diff --git a/android/build.gradle b/android/build.gradle index 2be87ea4..5d77d97e 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,7 +1,7 @@ // The native half of Push on Android: background delivery that survives the process being // killed, a reboot and an app update, shared with the Appwrite Android SDK. group = "io.appwrite.flutter" -version = "28.0.0" +version = "28.1.0" buildscript { ext.kotlin_version = "2.1.0" diff --git a/docs/examples/account/create-push-target.md b/docs/examples/account/create-push-target.md index 250cd4db..a8368084 100644 --- a/docs/examples/account/create-push-target.md +++ b/docs/examples/account/create-push-target.md @@ -12,5 +12,7 @@ models.Target result = await account.createPushTarget( targetId: '', identifier: '', providerId: '', // optional + bundleId: '', // optional + environment: 'sandbox', // optional ); ``` diff --git a/docs/examples/account/list-memberships.md b/docs/examples/account/list-memberships.md new file mode 100644 index 00000000..92a436f8 --- /dev/null +++ b/docs/examples/account/list-memberships.md @@ -0,0 +1,15 @@ +```dart +import 'package:appwrite/appwrite.dart'; +import 'package:appwrite/models.dart' as models; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +Account account = Account(client); + +models.MembershipList result = await account.listMemberships( + queries: [], // optional + total: false, // optional +); +``` diff --git a/docs/examples/account/update-push-target.md b/docs/examples/account/update-push-target.md index 49429983..d7466119 100644 --- a/docs/examples/account/update-push-target.md +++ b/docs/examples/account/update-push-target.md @@ -11,5 +11,7 @@ Account account = Account(client); models.Target result = await account.updatePushTarget( targetId: '', identifier: '', + bundleId: '', // optional + environment: 'sandbox', // optional ); ``` diff --git a/docs/examples/analytics/create-event.md b/docs/examples/analytics/create-event.md index d88e257b..af3b50f5 100644 --- a/docs/examples/analytics/create-event.md +++ b/docs/examples/analytics/create-event.md @@ -7,7 +7,7 @@ Client client = Client() Analytics analytics = Analytics(client); -models. result = await analytics.createEvent( +await analytics.createEvent( propertyId: '', name: '', url: 'https://example.com', diff --git a/docs/examples/avatars/update-photo.md b/docs/examples/avatars/update-photo.md index e667a94a..f980ade9 100644 --- a/docs/examples/avatars/update-photo.md +++ b/docs/examples/avatars/update-photo.md @@ -1,5 +1,4 @@ ```dart -import 'dart:io'; import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; diff --git a/docs/examples/databases/create-document.md b/docs/examples/databases/create-document.md index ade4f576..fe143b0e 100644 --- a/docs/examples/databases/create-document.md +++ b/docs/examples/databases/create-document.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/databases/create-query.md b/docs/examples/databases/create-query.md new file mode 100644 index 00000000..4411715c --- /dev/null +++ b/docs/examples/databases/create-query.md @@ -0,0 +1,19 @@ +```dart +import 'package:appwrite/appwrite.dart'; +import 'package:appwrite/models.dart' as models; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +Databases databases = Databases(client); + +models.DocumentList result = await databases.createQuery( + databaseId: '', + collectionId: '', + queries: [], // optional + transactionId: '', // optional + total: false, // optional + ttl: 0, // optional +); +``` diff --git a/docs/examples/databases/update-document.md b/docs/examples/databases/update-document.md index cf6d599c..e62a15e7 100644 --- a/docs/examples/databases/update-document.md +++ b/docs/examples/databases/update-document.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/databases/upsert-document.md b/docs/examples/databases/upsert-document.md index 1cd30f25..fe658e8f 100644 --- a/docs/examples/databases/upsert-document.md +++ b/docs/examples/databases/upsert-document.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/documentsdb/create-document.md b/docs/examples/documentsdb/create-document.md index 5ed989ad..9bbe1838 100644 --- a/docs/examples/documentsdb/create-document.md +++ b/docs/examples/documentsdb/create-document.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/documentsdb/create-query.md b/docs/examples/documentsdb/create-query.md new file mode 100644 index 00000000..ef70c189 --- /dev/null +++ b/docs/examples/documentsdb/create-query.md @@ -0,0 +1,19 @@ +```dart +import 'package:appwrite/appwrite.dart'; +import 'package:appwrite/models.dart' as models; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +DocumentsDB documentsDB = DocumentsDB(client); + +models.DocumentList result = await documentsDB.createQuery( + databaseId: '', + collectionId: '', + queries: [], // optional + transactionId: '', // optional + total: false, // optional + ttl: 0, // optional +); +``` diff --git a/docs/examples/documentsdb/update-document.md b/docs/examples/documentsdb/update-document.md index ec752959..3b85281e 100644 --- a/docs/examples/documentsdb/update-document.md +++ b/docs/examples/documentsdb/update-document.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/documentsdb/upsert-document.md b/docs/examples/documentsdb/upsert-document.md index 61baa69d..fed1ac5a 100644 --- a/docs/examples/documentsdb/upsert-document.md +++ b/docs/examples/documentsdb/upsert-document.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/graphql/mutation.md b/docs/examples/graphql/mutation.md index e9632b86..e84cad35 100644 --- a/docs/examples/graphql/mutation.md +++ b/docs/examples/graphql/mutation.md @@ -1,6 +1,5 @@ ```dart import 'package:appwrite/appwrite.dart'; -import 'package:appwrite/models.dart' as models; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint @@ -8,7 +7,7 @@ Client client = Client() Graphql graphql = Graphql(client); -models.Any result = await graphql.mutation( +dynamic result = await graphql.mutation( query: { "query": "mutation { accountUpdateName(name: \"Walter\") { name } }" }, diff --git a/docs/examples/graphql/query.md b/docs/examples/graphql/query.md index de938d4a..10a16be0 100644 --- a/docs/examples/graphql/query.md +++ b/docs/examples/graphql/query.md @@ -1,6 +1,5 @@ ```dart import 'package:appwrite/appwrite.dart'; -import 'package:appwrite/models.dart' as models; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint @@ -8,7 +7,7 @@ Client client = Client() Graphql graphql = Graphql(client); -models.Any result = await graphql.query( +dynamic result = await graphql.query( query: { "query": "query { localeGet { ip } }" }, diff --git a/docs/examples/oauth2/logout-post.md b/docs/examples/oauth2/logout-post.md index 3d163784..dc077108 100644 --- a/docs/examples/oauth2/logout-post.md +++ b/docs/examples/oauth2/logout-post.md @@ -7,7 +7,7 @@ Client client = Client() Oauth2 oauth2 = Oauth2(client); -models. result = await oauth2.logoutPost( +await oauth2.logoutPost( idTokenHint: '', // optional logoutHint: '', // optional clientId: '', // optional diff --git a/docs/examples/oauth2/logout.md b/docs/examples/oauth2/logout.md index 3892325e..640642d6 100644 --- a/docs/examples/oauth2/logout.md +++ b/docs/examples/oauth2/logout.md @@ -7,7 +7,7 @@ Client client = Client() Oauth2 oauth2 = Oauth2(client); -models. result = await oauth2.logout( +await oauth2.logout( idTokenHint: '', // optional logoutHint: '', // optional clientId: '', // optional diff --git a/docs/examples/oauth2/revoke.md b/docs/examples/oauth2/revoke.md index 777340f7..a34d5421 100644 --- a/docs/examples/oauth2/revoke.md +++ b/docs/examples/oauth2/revoke.md @@ -7,7 +7,7 @@ Client client = Client() Oauth2 oauth2 = Oauth2(client); -models. result = await oauth2.revoke( +await oauth2.revoke( token: '', tokenTypeHint: 'access_token', // optional clientId: '', // optional diff --git a/docs/examples/presences/update.md b/docs/examples/presences/update.md index ed52a7b0..0fabdf5a 100644 --- a/docs/examples/presences/update.md +++ b/docs/examples/presences/update.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/presences/upsert.md b/docs/examples/presences/upsert.md index 1620ff55..0d17fb12 100644 --- a/docs/examples/presences/upsert.md +++ b/docs/examples/presences/upsert.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/storage/create-file.md b/docs/examples/storage/create-file.md index f7267340..fa7bc9c7 100644 --- a/docs/examples/storage/create-file.md +++ b/docs/examples/storage/create-file.md @@ -1,9 +1,6 @@ ```dart -import 'dart:io'; import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/storage/update-file.md b/docs/examples/storage/update-file.md index fe33f0bf..6ddd4920 100644 --- a/docs/examples/storage/update-file.md +++ b/docs/examples/storage/update-file.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/tablesdb/create-query.md b/docs/examples/tablesdb/create-query.md new file mode 100644 index 00000000..1878b678 --- /dev/null +++ b/docs/examples/tablesdb/create-query.md @@ -0,0 +1,19 @@ +```dart +import 'package:appwrite/appwrite.dart'; +import 'package:appwrite/models.dart' as models; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +TablesDB tablesDB = TablesDB(client); + +models.RowList result = await tablesDB.createQuery( + databaseId: '', + tableId: '', + queries: [], // optional + transactionId: '', // optional + total: false, // optional + ttl: 0, // optional +); +``` diff --git a/docs/examples/tablesdb/create-row.md b/docs/examples/tablesdb/create-row.md index e3b639c7..ff1969bb 100644 --- a/docs/examples/tablesdb/create-row.md +++ b/docs/examples/tablesdb/create-row.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/tablesdb/update-row.md b/docs/examples/tablesdb/update-row.md index 1d42d637..9440e37c 100644 --- a/docs/examples/tablesdb/update-row.md +++ b/docs/examples/tablesdb/update-row.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/tablesdb/upsert-row.md b/docs/examples/tablesdb/upsert-row.md index a9df95fb..e590764a 100644 --- a/docs/examples/tablesdb/upsert-row.md +++ b/docs/examples/tablesdb/upsert-row.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/vectorsdb/create-document.md b/docs/examples/vectorsdb/create-document.md index ecc02176..4a4ce765 100644 --- a/docs/examples/vectorsdb/create-document.md +++ b/docs/examples/vectorsdb/create-document.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/vectorsdb/update-document.md b/docs/examples/vectorsdb/update-document.md index 0457e855..27e37e8d 100644 --- a/docs/examples/vectorsdb/update-document.md +++ b/docs/examples/vectorsdb/update-document.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/docs/examples/vectorsdb/upsert-document.md b/docs/examples/vectorsdb/upsert-document.md index de7503fb..e5c7c189 100644 --- a/docs/examples/vectorsdb/upsert-document.md +++ b/docs/examples/vectorsdb/upsert-document.md @@ -1,8 +1,6 @@ ```dart import 'package:appwrite/appwrite.dart'; import 'package:appwrite/models.dart' as models; -import 'package:appwrite/permission.dart'; -import 'package:appwrite/role.dart'; Client client = Client() .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint diff --git a/lib/query.dart b/lib/query.dart index 33541de0..38e158c0 100644 --- a/lib/query.dart +++ b/lib/query.dart @@ -353,7 +353,7 @@ class Query { static String max(String attribute, [String alias = '']) => Query._('max', attribute, alias.isNotEmpty ? alias : null).toString(); - /// Standard deviation of [attribute], optionally aliased. + /// Population standard deviation of [attribute] (the same as stddevPop), optionally aliased. static String stddev(String attribute, [String alias = '']) => Query._('stddev', attribute, alias.isNotEmpty ? alias : null).toString(); @@ -367,7 +367,7 @@ class Query { Query._('stddevSamp', attribute, alias.isNotEmpty ? alias : null) .toString(); - /// Variance of [attribute], optionally aliased. + /// Population variance of [attribute] (the same as varPop), optionally aliased. static String variance(String attribute, [String alias = '']) => Query._('variance', attribute, alias.isNotEmpty ? alias : null) .toString(); @@ -410,7 +410,7 @@ class Query { static String on(String left, String right, [String operator = '=']) => Query._('on', null, [left, operator, right]).toString(); - /// Inner join. [table] is the joined collection/table ID. + /// Inner join. [table] is the joined collection/table ID; without an alias the server names the join after it, if the ID is a valid alias, and otherwise rejects the query. static String join( String table, Object leftOrAliasOrOn, [ @@ -420,7 +420,7 @@ class Query { ]) => Query._createJoin('join', table, leftOrAliasOrOn, rightOrOn, operator, alias); - /// Left join. [table] is the joined collection/table ID. + /// Left join. [table] is the joined collection/table ID; without an alias the server names the join after it, if the ID is a valid alias, and otherwise rejects the query. static String leftJoin( String table, Object leftOrAliasOrOn, [ @@ -430,7 +430,7 @@ class Query { ]) => Query._createJoin('leftJoin', table, leftOrAliasOrOn, rightOrOn, operator, alias); - /// Right join. [table] is the joined collection/table ID. + /// Right join. [table] is the joined collection/table ID; without an alias the server names the join after it, if the ID is a valid alias, and otherwise rejects the query. static String rightJoin( String table, Object leftOrAliasOrOn, [ @@ -440,7 +440,7 @@ class Query { ]) => Query._createJoin('rightJoin', table, leftOrAliasOrOn, rightOrOn, operator, alias); - /// Full outer join. [table] is the joined collection/table ID. + /// Full outer join. [table] is the joined collection/table ID; without an alias the server names the join after it, if the ID is a valid alias, and otherwise rejects the query. static String fullOuterJoin( String table, Object leftOrAliasOrOn, [ @@ -450,7 +450,7 @@ class Query { ]) => Query._createJoin('fullOuterJoin', table, leftOrAliasOrOn, rightOrOn, operator, alias); - /// Cross join. [table] is the joined collection/table ID. + /// Cross join. [table] is the joined collection/table ID; without an alias the server names the join after it, if the ID is a valid alias, and otherwise rejects the query. static String crossJoin(String table, [String alias = '']) => Query._('crossJoin', table, alias.isNotEmpty ? alias : null).toString(); diff --git a/lib/services/account.dart b/lib/services/account.dart index d805b833..3e6de0d8 100644 --- a/lib/services/account.dart +++ b/lib/services/account.dart @@ -415,6 +415,33 @@ class Account extends Service { return models.Jwt.fromMap(res.data); } + /// Get the team memberships of the currently logged in user. + Future listMemberships({ + List? queries, + bool? total, + }) async { + final String apiPath = '/account/memberships'; + + final Map apiParams = { + if (queries != null) 'queries': queries, + if (total != null) 'total': total, + }; + + final Map apiHeaders = { + 'X-Appwrite-Project': client.config['project'] ?? '', + 'accept': 'application/json', + }; + + final res = await client.call( + HttpMethod.get, + path: apiPath, + params: apiParams, + headers: apiHeaders, + ); + + return models.MembershipList.fromMap(res.data); + } + /// Enable or disable MFA on an account. Future updateMFA({ required bool mfa, @@ -1348,6 +1375,14 @@ class Account extends Service { /// Attack](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.md) /// the only valid redirect URLs are the ones from domains you have set when /// adding your platforms in the console interface. + /// + /// The new password must satisfy the project's enabled password policies, + /// including custom deny lists. Dictionary entries match the entire password + /// case-sensitively; personal-data terms match substrings case-insensitively. + /// Personal-data validation runs after token verification against the + /// recovered user's ID, name, email, and phone, closing the previous recovery + /// gap for profile-based checks. A rejected password leaves the existing + /// credentials unchanged and the recovery token usable. Future updateRecovery({ required String userId, required String secret, @@ -1423,6 +1458,14 @@ class Account extends Service { /// Pass the **userId** of the user along with the **secret** code from the /// email and the new **password** to set. If confirmed, this route will return /// a 200 status code, the code is consumed and the user's password is updated. + /// + /// The new password must satisfy the project's enabled password policies, + /// including custom deny lists. Dictionary entries match the entire password + /// case-sensitively; personal-data terms match substrings case-insensitively. + /// Personal-data validation runs after token verification against the + /// recovered user's ID, name, email, and phone, closing the previous recovery + /// gap for profile-based checks. A rejected password leaves the existing + /// credentials unchanged and the recovery token usable. Future updateRecoveryOTP({ required String userId, required String secret, @@ -1946,6 +1989,8 @@ class Account extends Service { required String targetId, required String identifier, String? providerId, + String? bundleId, + String? environment, }) async { final String apiPath = '/account/targets/push'; @@ -1953,6 +1998,8 @@ class Account extends Service { 'targetId': targetId, 'identifier': identifier, if (providerId != null) 'providerId': providerId, + if (bundleId != null) 'bundleId': bundleId, + if (environment != null) 'environment': environment, }; final Map apiHeaders = { @@ -1979,6 +2026,8 @@ class Account extends Service { Future updatePushTarget({ required String targetId, required String identifier, + String? bundleId, + String? environment, }) async { if (targetId.isEmpty) { throw AppwriteException( @@ -1993,6 +2042,8 @@ class Account extends Service { final Map apiParams = { 'identifier': identifier, + if (bundleId != null) 'bundleId': bundleId, + if (environment != null) 'environment': environment, }; final Map apiHeaders = { diff --git a/lib/services/databases.dart b/lib/services/databases.dart index 96fed789..11959bf9 100644 --- a/lib/services/databases.dart +++ b/lib/services/databases.dart @@ -219,6 +219,15 @@ class Databases extends Service { /// Get a list of all the user's documents in a given collection. You can use /// the query params to filter your results. + /// + /// Documents returned by aggregate, groupBy or distinct queries hold only the + /// attributes they select, group or aggregate, typed as a document types them, + /// with a joined attribute named by its join alias (`alias.attribute`). The + /// response omits their `$id`, `$sequence`, `$createdAt`, `$updatedAt`, + /// `$permissions`, `$databaseId` and `$collectionId` unless they select or + /// group it, and those of a right or full join document that no document of + /// this collection matched. SDK document models fill omitted system attributes + /// with empty values. @Deprecated( 'This API has been deprecated since 1.8.0. Please use `TablesDB.listRows` instead.', ) @@ -336,6 +345,67 @@ class Databases extends Service { return models.Document.fromMap(res.data); } + /// Get a list of all the user's documents in a given collection using a POST + /// request. This behaves identically to the list documents endpoint but + /// accepts the queries in the request body, allowing much larger `queries` + /// arrays than can fit in a URL query string. + @Deprecated( + 'This API has been deprecated since 1.8.0. Please use `TablesDB.createQuery` instead.', + ) + Future createQuery({ + required String databaseId, + required String collectionId, + List? queries, + String? transactionId, + bool? total, + int? ttl, + }) async { + if (databaseId.isEmpty) { + throw AppwriteException( + 'Missing required parameter: "databaseId"', + ); + } + + if (collectionId.isEmpty) { + throw AppwriteException( + 'Missing required parameter: "collectionId"', + ); + } + + final String apiPath = + '/databases/{databaseId}/collections/{collectionId}/documents/query' + .replaceAll( + '{databaseId}', + databaseId, + ) + .replaceAll( + '{collectionId}', + collectionId, + ); + + final Map apiParams = { + if (queries != null) 'queries': queries, + if (transactionId != null) 'transactionId': transactionId, + if (total != null) 'total': total, + if (ttl != null) 'ttl': ttl, + }; + + final Map apiHeaders = { + 'X-Appwrite-Project': client.config['project'] ?? '', + 'content-type': 'application/json', + 'accept': 'application/json', + }; + + final res = await client.call( + HttpMethod.post, + path: apiPath, + params: apiParams, + headers: apiHeaders, + ); + + return models.DocumentList.fromMap(res.data); + } + /// Get a document by its unique ID. This endpoint response returns a JSON /// object with the document data. @Deprecated( diff --git a/lib/services/documents_db.dart b/lib/services/documents_db.dart index 1d04aa9c..93ef8712 100644 --- a/lib/services/documents_db.dart +++ b/lib/services/documents_db.dart @@ -367,6 +367,64 @@ class DocumentsDB extends Service { return models.DocumentList.fromMap(res.data); } + /// Get a list of all the user's documents in a given collection using a POST + /// request. This behaves identically to the list documents endpoint but + /// accepts the queries in the request body, allowing much larger `queries` + /// arrays than can fit in a URL query string. + Future createQuery({ + required String databaseId, + required String collectionId, + List? queries, + String? transactionId, + bool? total, + int? ttl, + }) async { + if (databaseId.isEmpty) { + throw AppwriteException( + 'Missing required parameter: "databaseId"', + ); + } + + if (collectionId.isEmpty) { + throw AppwriteException( + 'Missing required parameter: "collectionId"', + ); + } + + final String apiPath = + '/documentsdb/{databaseId}/collections/{collectionId}/documents/query' + .replaceAll( + '{databaseId}', + databaseId, + ) + .replaceAll( + '{collectionId}', + collectionId, + ); + + final Map apiParams = { + if (queries != null) 'queries': queries, + if (transactionId != null) 'transactionId': transactionId, + if (total != null) 'total': total, + if (ttl != null) 'ttl': ttl, + }; + + final Map apiHeaders = { + 'X-Appwrite-Project': client.config['project'] ?? '', + 'content-type': 'application/json', + 'accept': 'application/json', + }; + + final res = await client.call( + HttpMethod.post, + path: apiPath, + params: apiParams, + headers: apiHeaders, + ); + + return models.DocumentList.fromMap(res.data); + } + /// Get a document by its unique ID. This endpoint response returns a JSON /// object with the document data. Future getDocument({ diff --git a/lib/services/tables_db.dart b/lib/services/tables_db.dart index e7a5d4a3..3ad93e30 100644 --- a/lib/services/tables_db.dart +++ b/lib/services/tables_db.dart @@ -201,6 +201,14 @@ class TablesDB extends Service { /// Get a list of all the user's rows in a given table. You can use the query /// params to filter your results. + /// + /// Rows returned by aggregate, groupBy or distinct queries hold only the + /// columns they select, group or aggregate, typed as a row types them, with a + /// joined column named by its join alias (`alias.column`). The response omits + /// their `$id`, `$sequence`, `$createdAt`, `$updatedAt`, `$permissions`, + /// `$databaseId` and `$tableId` unless they select or group it, and those of a + /// right or full join row that no row of this table matched. SDK row models + /// fill omitted system columns with empty values. Future listRows({ required String databaseId, required String tableId, @@ -310,6 +318,63 @@ class TablesDB extends Service { return models.Row.fromMap(res.data); } + /// Get a list of all the user's rows in a given table using a POST request. + /// This behaves identically to the list rows endpoint but accepts the queries + /// in the request body, allowing much larger `queries` arrays than can fit in + /// a URL query string. + Future createQuery({ + required String databaseId, + required String tableId, + List? queries, + String? transactionId, + bool? total, + int? ttl, + }) async { + if (databaseId.isEmpty) { + throw AppwriteException( + 'Missing required parameter: "databaseId"', + ); + } + + if (tableId.isEmpty) { + throw AppwriteException( + 'Missing required parameter: "tableId"', + ); + } + + final String apiPath = '/tablesdb/{databaseId}/tables/{tableId}/rows/query' + .replaceAll( + '{databaseId}', + databaseId, + ) + .replaceAll( + '{tableId}', + tableId, + ); + + final Map apiParams = { + if (queries != null) 'queries': queries, + if (transactionId != null) 'transactionId': transactionId, + if (total != null) 'total': total, + if (ttl != null) 'ttl': ttl, + }; + + final Map apiHeaders = { + 'X-Appwrite-Project': client.config['project'] ?? '', + 'content-type': 'application/json', + 'accept': 'application/json', + }; + + final res = await client.call( + HttpMethod.post, + path: apiPath, + params: apiParams, + headers: apiHeaders, + ); + + return models.RowList.fromMap(res.data); + } + /// Get a row by its unique ID. This endpoint response returns a JSON object /// with the row data. Future getRow({ diff --git a/lib/src/client_browser.dart b/lib/src/client_browser.dart index 7488458c..ab689f04 100644 --- a/lib/src/client_browser.dart +++ b/lib/src/client_browser.dart @@ -40,7 +40,7 @@ class ClientBrowser extends ClientBase with ClientMixin { 'x-sdk-name': 'Flutter', 'x-sdk-platform': 'client', 'x-sdk-language': 'flutter', - 'x-sdk-version': '28.0.0', + 'x-sdk-version': '28.1.0', 'X-Appwrite-Response-Format': '2.5.0', }; diff --git a/lib/src/client_io.dart b/lib/src/client_io.dart index af5ed1f3..5d91c62c 100644 --- a/lib/src/client_io.dart +++ b/lib/src/client_io.dart @@ -59,7 +59,7 @@ class ClientIO extends ClientBase with ClientMixin { 'x-sdk-name': 'Flutter', 'x-sdk-platform': 'client', 'x-sdk-language': 'flutter', - 'x-sdk-version': '28.0.0', + 'x-sdk-version': '28.1.0', 'X-Appwrite-Response-Format': '2.5.0', }; @@ -261,6 +261,15 @@ class ClientIO extends ClientBase with ClientMixin { _initProgress = false; } + Future _ready() async { + while (!_initialized && _initProgress) { + await Future.delayed(Duration(milliseconds: 10)); + } + if (!_initialized) { + await init(); + } + } + Future _interceptRequest(http.BaseRequest request) async { final body = (request is http.Request) ? request.body : ''; for (final i in _interceptors) { @@ -499,59 +508,116 @@ class ClientIO extends ClientBase with ClientMixin { return finalResponse ?? lastResponse; } - bool get _customSchemeAllowed => Platform.isWindows || Platform.isLinux; + bool get _loopbackCallback => + defaultTargetPlatform == TargetPlatform.windows || + defaultTargetPlatform == TargetPlatform.linux; @override - Future webAuth(Uri url, {String? callbackUrlScheme}) { - return FlutterWebAuth2.authenticate( - url: url.toString(), - callbackUrlScheme: callbackUrlScheme != null && _customSchemeAllowed - ? callbackUrlScheme - : "appwrite-callback-${config['project']!}", - options: const FlutterWebAuth2Options( - useWebview: false, + Future webAuth(Uri url, {String? callbackUrlScheme}) async { + if (!_loopbackCallback) { + return _saveSession( + await _authenticate( + url, + "appwrite-callback-${config['project']!}", + ), + ); + } + + final callback = callbackUrlScheme ?? await _loopbackUrl(); + final exchange = url.path.contains(_sessionOAuth2Path); + final result = await _authenticate( + url.replace( + path: exchange + ? url.path.replaceFirst(_sessionOAuth2Path, _tokenOAuth2Path) + : url.path, + queryParameters: { + ...url.queryParametersAll, + 'success': [callback], + 'failure': [callback], + }, ), - ).then((value) async { - Uri url = Uri.parse(value); - final key = url.queryParameters['key']; - final secret = url.queryParameters['secret']; - if (key == null || secret == null) { - final error = url.queryParameters['error']; - if (error != null && error.isNotEmpty) { - try { - final parsed = jsonDecode(error); - if (parsed is Map) { - final codeValue = parsed['code']; - final int? code = codeValue is int - ? codeValue - : int.tryParse('${codeValue ?? ''}'); - throw AppwriteException( - parsed['message']?.toString() ?? error, - code, - parsed['type']?.toString(), - error, - ); - } - } on AppwriteException { - rethrow; - } catch (_) { - // Fall through to a plain-string error when JSON is malformed. - } - throw AppwriteException(error); + callback, + ); + if (!exchange) { + return _saveSession(result); + } + + final userId = result.queryParameters['userId']; + final secret = result.queryParameters['secret']; + if (userId == null || secret == null) { + _throwCallbackError(result); + } + await call( + HttpMethod.post, + path: _tokenSessionPath, + params: {'userId': userId, 'secret': secret}, + ); + } + + static const String _sessionOAuth2Path = '/account/sessions/oauth2/'; + static const String _tokenOAuth2Path = '/account/tokens/oauth2/'; + static const String _tokenSessionPath = '/account/sessions/token'; + + Future _loopbackUrl() async { + final socket = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0); + final port = socket.port; + await socket.close(); + return 'http://localhost:$port/'; + } + + Future _authenticate(Uri url, String callbackUrlScheme) async { + return Uri.parse( + await FlutterWebAuth2.authenticate( + url: url.toString(), + callbackUrlScheme: callbackUrlScheme, + options: const FlutterWebAuth2Options(useWebview: false), + ), + ); + } + + Future _saveSession(Uri url) async { + final key = url.queryParameters['key']; + final secret = url.queryParameters['secret']; + if (key == null || secret == null) { + _throwCallbackError(url); + } + Cookie cookie = Cookie(key, secret); + cookie.domain = Uri.parse(_endPoint).host; + cookie.httpOnly = true; + cookie.path = '/'; + List cookies = [cookie]; + await _ready(); + await _cookieJar.saveFromResponse(Uri.parse(_endPoint), cookies); + } + + Never _throwCallbackError(Uri url) { + final error = url.queryParameters['error']; + if (error != null && error.isNotEmpty) { + try { + final parsed = jsonDecode(error); + if (parsed is Map) { + final codeValue = parsed['code']; + final int? code = codeValue is int + ? codeValue + : int.tryParse('${codeValue ?? ''}'); + throw AppwriteException( + parsed['message']?.toString() ?? error, + code, + parsed['type']?.toString(), + error, + ); } - throw AppwriteException( - "Invalid OAuth2 Response. Key and Secret not available.", - 500, - ); + } on AppwriteException { + rethrow; + } catch (_) { + // Fall through to a plain-string error when JSON is malformed. } - Cookie cookie = Cookie(key, secret); - cookie.domain = Uri.parse(_endPoint).host; - cookie.httpOnly = true; - cookie.path = '/'; - List cookies = [cookie]; - await init(); - _cookieJar.saveFromResponse(Uri.parse(_endPoint), cookies); - }); + throw AppwriteException(error); + } + throw AppwriteException( + "Invalid OAuth2 Response. Key and Secret not available.", + 500, + ); } @override @@ -562,12 +628,7 @@ class ClientIO extends ClientBase with ClientMixin { Map params = const {}, ResponseType? responseType, }) async { - while (!_initialized && _initProgress) { - await Future.delayed(Duration(milliseconds: 10)); - } - if (!_initialized) { - await init(); - } + await _ready(); late http.Response res; http.BaseRequest request = prepareRequest( diff --git a/pubspec.yaml b/pubspec.yaml index 08a46375..2147f32e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: appwrite -version: 28.0.0 +version: 28.1.0 description: Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API homepage: https://appwrite.io repository: https://github.com/appwrite/sdk-for-flutter diff --git a/test/query_test.dart b/test/query_test.dart index fad7f352..6ab76a8c 100644 --- a/test/query_test.dart +++ b/test/query_test.dart @@ -511,6 +511,23 @@ void main() { expect(query['values'], ['ord']); }); + test('returns nested join without alias, leaving the alias to the server', + () { + final query = + jsonDecode(Query.join('orders', [Query.on('\$id', 'customerId')])); + expect(query['method'], 'join'); + expect(query['attribute'], 'orders'); + expect(query['values'].length, 1); + expect(query['values'][0]['method'], 'on'); + }); + + test('returns crossJoin without alias, leaving the alias to the server', () { + final query = jsonDecode(Query.crossJoin('orders')); + expect(query['method'], 'crossJoin'); + expect(query['attribute'], 'orders'); + expect(query['values'] ?? [], isEmpty); + }); + test('returns vectorDot', () { final query = jsonDecode(Query.vectorDot('embedding', [0.1, 0.2])); expect(query['method'], 'vectorDot'); diff --git a/test/services/account_test.dart b/test/services/account_test.dart index a904822d..3a712b73 100644 --- a/test/services/account_test.dart +++ b/test/services/account_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -88,10 +94,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.get(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -116,7 +138,13 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.create( @@ -124,6 +152,16 @@ void main() { email: "email@example.com", password: "password", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "email", "password"])); expect(response, isA()); }); @@ -134,10 +172,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.listConsents(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/consents", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -157,12 +211,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.getConsent( consentId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/consents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -170,12 +240,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.deleteConsent( consentId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/account/consents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method listConsentTokens()', () async { @@ -185,12 +271,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.listConsentTokens( consentId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/consents//tokens", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -211,13 +313,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.getConsentToken( consentId: "", tokenId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/consents//tokens/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -225,13 +343,29 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.deleteConsentToken( consentId: "", tokenId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/account/consents//tokens/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method updateEmail()', () async { @@ -255,13 +389,29 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateEmail( email: "email@example.com", password: "password", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/email", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["email", "password"])); expect(response, isA()); }); @@ -272,10 +422,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.listIdentities(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/identities", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -283,12 +449,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.deleteIdentity( identityId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/account/identities/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method createJWT()', () async { @@ -298,13 +480,59 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createJWT(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/jwts", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); + test('test method listMemberships()', () async { + final Map data = { + 'total': 5, + 'memberships': [], + }; + + when( + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).thenAnswer((_) async => Response(data: data)); + + final response = await account.listMemberships(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/memberships", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); + expect(response, isA()); + }); + test('test method updateMFA()', () async { final Map data = { '\$id': "5e5ea5c16897e", @@ -326,12 +554,28 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateMFA( mfa: true, ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/mfa", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["mfa"])); expect(response, isA()); }); @@ -343,12 +587,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createMfaAuthenticator( type: enums.AuthenticatorType.totp, ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/mfa/authenticators/totp", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -360,12 +620,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createMFAAuthenticator( type: enums.AuthenticatorType.totp, ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/mfa/authenticators/totp", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -390,13 +666,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateMfaAuthenticator( type: enums.AuthenticatorType.totp, otp: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/mfa/authenticators/totp", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["otp"])); expect(response, isA()); }); @@ -421,13 +713,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateMFAAuthenticator( type: enums.AuthenticatorType.totp, otp: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/mfa/authenticators/totp", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["otp"])); expect(response, isA()); }); @@ -435,24 +743,56 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.deleteMfaAuthenticator( type: enums.AuthenticatorType.totp, ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/account/mfa/authenticators/totp", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method deleteMFAAuthenticator()', () async { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.deleteMFAAuthenticator( type: enums.AuthenticatorType.totp, ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/account/mfa/authenticators/totp", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method createMfaChallenge()', () async { @@ -464,12 +804,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createMfaChallenge( factor: enums.AuthenticationFactor.email, ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/mfa/challenges", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["factor"])); expect(response, isA()); }); @@ -482,12 +838,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createMFAChallenge( factor: enums.AuthenticationFactor.email, ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/mfa/challenges", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["factor"])); expect(response, isA()); }); @@ -525,13 +897,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateMfaChallenge( challengeId: "", otp: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/mfa/challenges", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["challengeId", "otp"])); expect(response, isA()); }); @@ -569,13 +957,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateMFAChallenge( challengeId: "", otp: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/mfa/challenges", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["challengeId", "otp"])); expect(response, isA()); }); @@ -589,10 +993,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.listMfaFactors(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/mfa/factors", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -606,10 +1026,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.listMFAFactors(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/mfa/factors", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -619,10 +1055,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.getMfaRecoveryCodes(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/mfa/recovery-codes", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -632,10 +1084,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.getMFARecoveryCodes(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/mfa/recovery-codes", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -645,10 +1113,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createMfaRecoveryCodes(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/mfa/recovery-codes", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -658,10 +1142,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createMFARecoveryCodes(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/mfa/recovery-codes", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -671,10 +1171,26 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateMfaRecoveryCodes(); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/mfa/recovery-codes", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -684,10 +1200,26 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateMFARecoveryCodes(); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/mfa/recovery-codes", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -712,12 +1244,28 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateName( name: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/name", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["name"])); expect(response, isA()); }); @@ -728,10 +1276,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.listPasskeys(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/passkeys", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -745,10 +1309,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createPasskey(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/passkeys", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -762,12 +1342,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.getPasskey( passkeyId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/passkeys/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -781,13 +1377,29 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updatePasskey( passkeyId: "", name: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/passkeys/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["name"])); expect(response, isA()); }); @@ -795,12 +1407,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.deletePasskey( passkeyId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/account/passkeys/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method updatePasskeyVerification()', () async { @@ -813,13 +1441,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updatePasskeyVerification( passkeyId: "", credential: {}, ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/passkeys//verification", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["credential"])); expect(response, isA()); }); @@ -844,12 +1488,28 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updatePassword( password: "password", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/password", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["password"])); expect(response, isA()); }); @@ -874,13 +1534,29 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updatePhone( phone: "+12065550100", password: "password", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/phone", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["phone", "password"])); expect(response, isA()); }); @@ -888,10 +1564,26 @@ void main() { final Map data = {}; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.getPrefs(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/prefs", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -916,12 +1608,28 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updatePrefs( prefs: {}, ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/prefs", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["prefs"])); expect(response, isA()); }); @@ -936,13 +1644,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createRecovery( email: "email@example.com", url: "https://example.com", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/recovery", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["email", "url"])); expect(response, isA()); }); @@ -957,7 +1681,13 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateRecovery( @@ -965,6 +1695,16 @@ void main() { secret: "", password: "password", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/recovery", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "secret", "password"])); expect(response, isA()); }); @@ -979,12 +1719,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createRecoveryOTP( email: "email@example.com", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/recovery/otp", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["email"])); expect(response, isA()); }); @@ -999,7 +1755,13 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateRecoveryOTP( @@ -1007,6 +1769,16 @@ void main() { secret: "", password: "password", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/recovery/otp", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "secret", "password"])); expect(response, isA()); }); @@ -1017,10 +1789,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.listSessions(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/sessions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -1028,10 +1816,26 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.deleteSessions(); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/account/sessions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method createAnonymousSession()', () async { @@ -1068,10 +1872,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createAnonymousSession(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/sessions/anonymous", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -1109,13 +1929,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createEmailPasswordSession( email: "email@example.com", password: "password", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/sessions/email", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["email", "password"])); expect(response, isA()); }); @@ -1153,13 +1989,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createIdTokenSession( provider: enums.IdTokenProvider.apple, idToken: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/sessions/id-token", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["provider", "idToken"])); expect(response, isA()); }); @@ -1197,13 +2049,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateMagicURLSession( userId: "", secret: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/sessions/magic-url", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "secret"])); expect(response, isA()); }); @@ -1215,6 +2083,8 @@ void main() { final response = await account.createOAuth2Session( provider: enums.OAuthProvider.amazon, ); + final Uri url = verify(client.webAuth(captureAny)).captured.single; + expect(Uri.decodeFull(url.path), "/v1/account/sessions/oauth2/amazon"); expect(response, equals('done')); }); @@ -1252,13 +2122,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updatePhoneSession( userId: "", secret: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/sessions/phone", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "secret"])); expect(response, isA()); }); @@ -1296,13 +2182,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createSession( userId: "", secret: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/sessions/token", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "secret"])); expect(response, isA()); }); @@ -1340,12 +2242,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.getSession( sessionId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/account/sessions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -1383,12 +2301,28 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateSession( sessionId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/sessions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -1396,12 +2330,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.deleteSession( sessionId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/account/sessions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method updateStatus()', () async { @@ -1425,10 +2375,26 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateStatus(); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/account/status", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -1445,13 +2411,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createPushTarget( targetId: "", identifier: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/targets/push", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["targetId", "identifier"])); expect(response, isA()); }); @@ -1468,13 +2450,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updatePushTarget( targetId: "", identifier: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/targets//push", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["identifier"])); expect(response, isA()); }); @@ -1482,12 +2480,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.deletePushTarget( targetId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/account/targets//push", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method createEmailToken()', () async { @@ -1501,13 +2515,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createEmailToken( userId: "", email: "email@example.com", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/tokens/email", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "email"])); expect(response, isA()); }); @@ -1522,13 +2552,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createMagicURLToken( userId: "", email: "email@example.com", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/tokens/magic-url", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "email"])); expect(response, isA()); }); @@ -1540,6 +2586,8 @@ void main() { final response = await account.createOAuth2Token( provider: enums.OAuthProvider.amazon, ); + final Uri url = verify(client.webAuth(captureAny)).captured.single; + expect(Uri.decodeFull(url.path), "/v1/account/tokens/oauth2/amazon"); expect(response, equals('done')); }); @@ -1553,10 +2601,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createPasskeyToken(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/tokens/passkey", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -1571,13 +2635,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updatePasskeyToken( challengeId: "", credential: {}, ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/tokens/passkey", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["challengeId", "credential"])); expect(response, isA()); }); @@ -1592,13 +2672,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createPhoneToken( userId: "", phone: "+12065550100", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/tokens/phone", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "phone"])); expect(response, isA()); }); @@ -1613,12 +2709,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createEmailVerification( url: "https://example.com", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/verifications/email", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["url"])); expect(response, isA()); }); @@ -1633,12 +2745,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createVerification( url: "https://example.com", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/verifications/email", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["url"])); expect(response, isA()); }); @@ -1653,13 +2781,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateEmailVerification( userId: "", secret: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/verifications/email", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "secret"])); expect(response, isA()); }); @@ -1674,13 +2818,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateVerification( userId: "", secret: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/verifications/email", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "secret"])); expect(response, isA()); }); @@ -1695,10 +2855,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createEmailVerificationOTP(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/verifications/email/otp", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -1713,13 +2889,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updateEmailVerificationOTP( userId: "", secret: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/verifications/email/otp", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "secret"])); expect(response, isA()); }); @@ -1734,10 +2926,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.createPhoneVerification(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/account/verifications/phone", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -1752,13 +2960,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await account.updatePhoneVerification( userId: "", secret: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/account/verifications/phone", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "secret"])); expect(response, isA()); }); }); diff --git a/test/services/analytics_test.dart b/test/services/analytics_test.dart index d94506aa..559e6e1b 100644 --- a/test/services/analytics_test.dart +++ b/test/services/analytics_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -71,7 +77,13 @@ void main() { final data = ''; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await analytics.createEvent( @@ -79,6 +91,16 @@ void main() { name: "", url: "https://example.com", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/analytics/properties//events", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["name", "url"])); }); }); } diff --git a/test/services/apps_test.dart b/test/services/apps_test.dart index a60f0d67..f5d6e730 100644 --- a/test/services/apps_test.dart +++ b/test/services/apps_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -74,10 +80,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.list(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/apps", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -112,7 +134,13 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.create( @@ -120,6 +148,16 @@ void main() { name: "", redirectUris: [], ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/apps", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["appId", "name", "redirectUris"])); expect(response, isA()); }); @@ -130,10 +168,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.listInstallationScopes(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/apps/scopes/installations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -144,10 +198,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.listOAuth2Scopes(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/apps/scopes/oauth2", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -182,12 +252,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.get( appId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/apps/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -222,13 +308,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.update( appId: "", name: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/apps/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["name"])); expect(response, isA()); }); @@ -236,12 +338,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.delete( appId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/apps/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method listInstallations()', () async { @@ -251,12 +369,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.listInstallations( appId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/apps//installations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -274,13 +408,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.getInstallation( appId: "", installationId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/apps//installations/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -288,13 +438,29 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.deleteInstallation( appId: "", installationId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/apps//installations/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method createInstallationToken()', () async { @@ -307,13 +473,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.createInstallationToken( appId: "", installationId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/apps//installations//tokens", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -324,12 +506,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.listKeys( appId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/apps//keys", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -347,12 +545,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.createKey( appId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/apps//keys", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -370,13 +584,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.getKey( appId: "", keyId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/apps//keys/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -384,13 +614,29 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.deleteKey( appId: "", keyId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/apps//keys/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method listSecrets()', () async { @@ -400,12 +646,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.listSecrets( appId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/apps//secrets", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -423,12 +685,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.createSecret( appId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/apps//secrets", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -445,13 +723,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.getSecret( appId: "", secretId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/apps//secrets/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -459,13 +753,29 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.deleteSecret( appId: "", secretId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/apps//secrets/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method updateTeam()', () async { @@ -499,13 +809,29 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.updateTeam( appId: "", teamId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/apps//team", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["teamId"])); expect(response, isA()); }); @@ -513,12 +839,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await apps.deleteTokens( appId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/apps//tokens", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); }); } diff --git a/test/services/avatars_test.dart b/test/services/avatars_test.dart index 18c4d03d..16f91365 100644 --- a/test/services/avatars_test.dart +++ b/test/services/avatars_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -71,12 +77,28 @@ void main() { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.getBrowser( code: enums.Browser.avantBrowser, ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/avatars/browsers/aa", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -84,12 +106,28 @@ void main() { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.getCreditCard( code: enums.CreditCard.americanExpress, ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/avatars/credit-cards/amex", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -97,12 +135,28 @@ void main() { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.getFavicon( url: "https://example.com", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/avatars/favicon", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["url"])); expect(response, isA()); }); @@ -110,12 +164,28 @@ void main() { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.getFlag( code: enums.Flag.afghanistan, ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/avatars/flags/af", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -123,12 +193,28 @@ void main() { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.getImage( url: "https://example.com", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/avatars/image", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["url"])); expect(response, isA()); }); @@ -136,10 +222,26 @@ void main() { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.getInitials(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/avatars/initials", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -147,10 +249,26 @@ void main() { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.getPhoto(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/avatars/photo", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -176,17 +294,29 @@ void main() { when( client.chunkedUpload( - path: argThat(isNotNull), - params: argThat(isNotNull), - paramName: argThat(isNotNull), - idParamName: argThat(isNotNull), - headers: argThat(isNotNull), + path: anyNamed('path'), + params: anyNamed('params'), + paramName: anyNamed('paramName'), + idParamName: anyNamed('idParamName'), + headers: anyNamed('headers'), + method: anyNamed('method'), ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.updatePhoto( file: InputFile.fromPath(path: './image.png'), ); + final Map params = verify( + client.chunkedUpload( + path: "/avatars/photo", + params: captureAnyNamed('params'), + paramName: anyNamed('paramName'), + idParamName: anyNamed('idParamName'), + headers: anyNamed('headers'), + method: HttpMethod.put, + ), + ).captured.single; + expect(params.keys, unorderedEquals(["file"])); expect(response, isA()); }); @@ -194,22 +324,54 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.deletePhoto(); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/avatars/photo", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method getQR()', () async { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.getQR( text: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/avatars/qr", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["text"])); expect(response, isA()); }); @@ -217,12 +379,28 @@ void main() { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await avatars.getScreenshot( url: "https://example.com", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/avatars/screenshots", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["url"])); expect(response, isA()); }); }); diff --git a/test/services/databases_test.dart b/test/services/databases_test.dart index eb03954a..f341f304 100644 --- a/test/services/databases_test.dart +++ b/test/services/databases_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -74,10 +80,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.listTransactions(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/databases/transactions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -92,10 +114,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.createTransaction(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/databases/transactions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -110,12 +148,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.getTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/databases/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -130,12 +184,28 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.updateTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/databases/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -143,12 +213,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.deleteTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/databases/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method createOperations()', () async { @@ -162,12 +248,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.createOperations( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/databases/transactions//operations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -178,13 +280,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.listDocuments( databaseId: "", collectionId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/databases//collections//documents", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -200,7 +318,13 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.createDocument( @@ -209,9 +333,52 @@ void main() { documentId: "", data: {}, ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/databases//collections//documents", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["documentId", "data"])); expect(response, isA()); }); + test('test method createQuery()', () async { + final Map data = { + 'total': 5, + 'documents': [], + }; + + when( + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).thenAnswer((_) async => Response(data: data)); + + final response = await databases.createQuery( + databaseId: "", + collectionId: "", + ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/databases//collections//documents/query", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); + expect(response, isA()); + }); + test('test method getDocument()', () async { final Map data = { '\$id': "5e5ea5c16897e", @@ -224,7 +391,13 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.getDocument( @@ -232,6 +405,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/databases//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -247,7 +430,13 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.upsertDocument( @@ -255,6 +444,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/databases//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -270,7 +469,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.updateDocument( @@ -278,6 +483,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/databases//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -285,7 +500,13 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.deleteDocument( @@ -293,6 +514,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/databases//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method decrementDocumentAttribute()', () async { @@ -307,7 +538,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.decrementDocumentAttribute( @@ -316,6 +553,16 @@ void main() { documentId: "", attribute: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/databases//collections//documents///decrement", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -331,7 +578,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await databases.incrementDocumentAttribute( @@ -340,6 +593,16 @@ void main() { documentId: "", attribute: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/databases//collections//documents///increment", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); }); diff --git a/test/services/documents_db_test.dart b/test/services/documents_db_test.dart index 4312cced..e6cd7d0b 100644 --- a/test/services/documents_db_test.dart +++ b/test/services/documents_db_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -74,10 +80,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.listTransactions(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/documentsdb/transactions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -92,10 +114,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.createTransaction(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/documentsdb/transactions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -110,12 +148,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.getTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/documentsdb/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -130,12 +184,28 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.updateTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/documentsdb/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -143,12 +213,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.deleteTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/documentsdb/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method createOperations()', () async { @@ -162,12 +248,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.createOperations( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/documentsdb/transactions//operations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -178,13 +280,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.listDocuments( databaseId: "", collectionId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/documentsdb//collections//documents", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -200,7 +318,13 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.createDocument( @@ -209,6 +333,16 @@ void main() { documentId: "", data: {}, ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/documentsdb//collections//documents", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["documentId", "data"])); expect(response, isA()); }); @@ -219,7 +353,13 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.createDocuments( @@ -227,6 +367,49 @@ void main() { collectionId: "", documents: [], ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/documentsdb//collections//documents", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["documents"])); + expect(response, isA()); + }); + + test('test method createQuery()', () async { + final Map data = { + 'total': 5, + 'documents': [], + }; + + when( + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).thenAnswer((_) async => Response(data: data)); + + final response = await documentsDB.createQuery( + databaseId: "", + collectionId: "", + ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/documentsdb//collections//documents/query", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -242,7 +425,13 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.getDocument( @@ -250,6 +439,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/documentsdb//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -265,7 +464,13 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.upsertDocument( @@ -273,6 +478,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/documentsdb//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -288,7 +503,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.updateDocument( @@ -296,6 +517,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/documentsdb//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -303,7 +534,13 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.deleteDocument( @@ -311,6 +548,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/documentsdb//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method decrementDocumentAttribute()', () async { @@ -325,7 +572,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.decrementDocumentAttribute( @@ -334,6 +587,16 @@ void main() { documentId: "", attribute: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/documentsdb//collections//documents///decrement", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -349,7 +612,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await documentsDB.incrementDocumentAttribute( @@ -358,6 +627,16 @@ void main() { documentId: "", attribute: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/documentsdb//collections//documents///increment", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); }); diff --git a/test/services/functions_test.dart b/test/services/functions_test.dart index 93a7bc81..05edea49 100644 --- a/test/services/functions_test.dart +++ b/test/services/functions_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -74,12 +80,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await functions.listExecutions( functionId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/functions//executions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -106,12 +128,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await functions.createExecution( functionId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/functions//executions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -138,13 +176,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await functions.getExecution( functionId: "", executionId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/functions//executions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); }); diff --git a/test/services/graphql_test.dart b/test/services/graphql_test.dart index 3333a66e..0afd4fa7 100644 --- a/test/services/graphql_test.dart +++ b/test/services/graphql_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -71,24 +77,56 @@ void main() { final data = ''; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await graphql.query( query: {}, ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/graphql", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["query"])); }); test('test method mutation()', () async { final data = ''; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await graphql.mutation( query: {}, ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/graphql/mutation", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["query"])); }); }); } diff --git a/test/services/locale_test.dart b/test/services/locale_test.dart index 77ee7ddd..b58bdcb3 100644 --- a/test/services/locale_test.dart +++ b/test/services/locale_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -79,10 +85,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await locale.get(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/locale", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -93,10 +115,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await locale.listCodes(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/locale/codes", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -107,10 +145,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await locale.listContinents(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/locale/continents", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -121,10 +175,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await locale.listCountries(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/locale/countries", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -135,10 +205,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await locale.listCountriesEU(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/locale/countries/eu", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -149,10 +235,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await locale.listCountriesPhones(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/locale/countries/phones", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -163,10 +265,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await locale.listCurrencies(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/locale/currencies", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -177,10 +295,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await locale.listLanguages(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/locale/languages", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); }); diff --git a/test/services/messaging_test.dart b/test/services/messaging_test.dart index 5bf1cbd3..11fba0b9 100644 --- a/test/services/messaging_test.dart +++ b/test/services/messaging_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -90,7 +96,13 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await messaging.createSubscriber( @@ -98,6 +110,16 @@ void main() { subscriberId: "", targetId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/messaging/topics//subscribers", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["subscriberId", "targetId"])); expect(response, isA()); }); @@ -105,13 +127,29 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await messaging.deleteSubscriber( topicId: "", subscriberId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/messaging/topics//subscribers/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); }); } diff --git a/test/services/oauth2_test.dart b/test/services/oauth2_test.dart index 41976a32..a8429a5f 100644 --- a/test/services/oauth2_test.dart +++ b/test/services/oauth2_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -73,12 +79,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.approve( grantId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/oauth2/testproject/approve", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["grant_id"])); expect(response, isA()); }); @@ -89,10 +111,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.authorize(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/oauth2/testproject/authorize", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -103,10 +141,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.authorizePost(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/oauth2/testproject/authorize", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -123,10 +177,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.createDeviceAuthorization(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/oauth2/testproject/device_authorization", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -148,12 +218,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.createGrant( userCode: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/oauth2/testproject/grants", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["user_code"])); expect(response, isA()); }); @@ -175,12 +261,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.getGrant( grantId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/oauth2/testproject/grants/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -188,20 +290,52 @@ void main() { final data = ''; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.logout(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/oauth2/testproject/logout", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method logoutPost()', () async { final data = ''; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.logoutPost(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/oauth2/testproject/logout", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method listOrganizations()', () async { @@ -211,10 +345,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.listOrganizations(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/oauth2/testproject/organizations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -225,7 +375,13 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.createPAR( @@ -233,6 +389,16 @@ void main() { redirectUri: "https://example.com", responseType: "code", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/oauth2/testproject/par", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["client_id", "redirect_uri", "response_type"])); expect(response, isA()); }); @@ -243,10 +409,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.listProjects(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/oauth2/testproject/projects", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -257,12 +439,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.reject( grantId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/oauth2/testproject/reject", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["grant_id"])); expect(response, isA()); }); @@ -270,12 +468,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.revoke( token: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/oauth2/testproject/revoke", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["token"])); }); test('test method createToken()', () async { @@ -288,12 +502,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await oauth2.createToken( grantType: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/oauth2/testproject/token", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["grant_type"])); expect(response, isA()); }); }); diff --git a/test/services/organization_test.dart b/test/services/organization_test.dart index 7354def0..4e39beda 100644 --- a/test/services/organization_test.dart +++ b/test/services/organization_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -74,10 +80,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await organization.listInstallations(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/organization/installations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -95,12 +117,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await organization.createInstallation( appId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/organization/installations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["appId"])); expect(response, isA()); }); @@ -118,12 +156,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await organization.getInstallation( installationId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/organization/installations/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -141,12 +195,28 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await organization.updateInstallation( installationId: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/organization/installations/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -154,12 +224,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await organization.deleteInstallation( installationId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/organization/installations/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); }); } diff --git a/test/services/presences_test.dart b/test/services/presences_test.dart index 9f160e79..13c02de0 100644 --- a/test/services/presences_test.dart +++ b/test/services/presences_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -74,10 +80,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await presences.list(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/presences", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -92,12 +114,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await presences.get( presenceId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/presences/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -112,13 +150,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await presences.upsert( presenceId: "", status: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/presences/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["status"])); expect(response, isA()); }); @@ -133,12 +187,28 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await presences.update( presenceId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/presences/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -146,12 +216,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await presences.delete( presenceId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/presences/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); }); } diff --git a/test/services/storage_test.dart b/test/services/storage_test.dart index d1e6f09b..72b05be7 100644 --- a/test/services/storage_test.dart +++ b/test/services/storage_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -74,12 +80,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await storage.listFiles( bucketId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/storage/buckets//files", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -105,11 +127,12 @@ void main() { when( client.chunkedUpload( - path: argThat(isNotNull), - params: argThat(isNotNull), - paramName: argThat(isNotNull), - idParamName: argThat(isNotNull), - headers: argThat(isNotNull), + path: anyNamed('path'), + params: anyNamed('params'), + paramName: anyNamed('paramName'), + idParamName: anyNamed('idParamName'), + headers: anyNamed('headers'), + method: anyNamed('method'), ), ).thenAnswer((_) async => Response(data: data)); @@ -118,6 +141,17 @@ void main() { fileId: "", file: InputFile.fromPath(path: './image.png'), ); + final Map params = verify( + client.chunkedUpload( + path: "/storage/buckets//files", + params: captureAnyNamed('params'), + paramName: anyNamed('paramName'), + idParamName: anyNamed('idParamName'), + headers: anyNamed('headers'), + method: HttpMethod.post, + ), + ).captured.single; + expect(params.keys, unorderedEquals(["fileId", "file"])); expect(response, isA()); }); @@ -142,13 +176,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await storage.getFile( bucketId: "", fileId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/storage/buckets//files/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -173,13 +223,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await storage.updateFile( bucketId: "", fileId: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/storage/buckets//files/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -187,26 +253,58 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await storage.deleteFile( bucketId: "", fileId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/storage/buckets//files/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method getFileDownload()', () async { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await storage.getFileDownload( bucketId: "", fileId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/storage/buckets//files//download", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -214,13 +312,29 @@ void main() { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await storage.getFilePreview( bucketId: "", fileId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/storage/buckets//files//preview", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -228,13 +342,29 @@ void main() { final Uint8List data = Uint8List.fromList([]); when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await storage.getFileView( bucketId: "", fileId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/storage/buckets//files//view", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); }); diff --git a/test/services/tables_db_test.dart b/test/services/tables_db_test.dart index 90a55af7..526bd009 100644 --- a/test/services/tables_db_test.dart +++ b/test/services/tables_db_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -74,10 +80,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.listTransactions(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/tablesdb/transactions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -92,10 +114,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.createTransaction(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/tablesdb/transactions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -110,12 +148,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.getTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/tablesdb/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -130,12 +184,28 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.updateTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/tablesdb/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -143,12 +213,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.deleteTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/tablesdb/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method createOperations()', () async { @@ -162,12 +248,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.createOperations( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/tablesdb/transactions//operations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -178,13 +280,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.listRows( databaseId: "", tableId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/tablesdb//tables//rows", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -200,7 +318,13 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.createRow( @@ -209,9 +333,52 @@ void main() { rowId: "", data: {}, ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/tablesdb//tables//rows", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["rowId", "data"])); expect(response, isA()); }); + test('test method createQuery()', () async { + final Map data = { + 'total': 5, + 'rows': [], + }; + + when( + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).thenAnswer((_) async => Response(data: data)); + + final response = await tablesDB.createQuery( + databaseId: "", + tableId: "", + ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/tablesdb//tables//rows/query", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); + expect(response, isA()); + }); + test('test method getRow()', () async { final Map data = { '\$id': "5e5ea5c16897e", @@ -224,7 +391,13 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.getRow( @@ -232,6 +405,16 @@ void main() { tableId: "", rowId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/tablesdb//tables//rows/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -247,7 +430,13 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.upsertRow( @@ -255,6 +444,16 @@ void main() { tableId: "", rowId: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/tablesdb//tables//rows/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -270,7 +469,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.updateRow( @@ -278,6 +483,16 @@ void main() { tableId: "", rowId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/tablesdb//tables//rows/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -285,7 +500,13 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.deleteRow( @@ -293,6 +514,16 @@ void main() { tableId: "", rowId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/tablesdb//tables//rows/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method decrementRowColumn()', () async { @@ -307,7 +538,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.decrementRowColumn( @@ -316,6 +553,16 @@ void main() { rowId: "", column: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/tablesdb//tables//rows///decrement", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -331,7 +578,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await tablesDB.incrementRowColumn( @@ -340,6 +593,16 @@ void main() { rowId: "", column: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/tablesdb//tables//rows///increment", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); }); diff --git a/test/services/teams_test.dart b/test/services/teams_test.dart index 7c9f2faf..fcf47c3f 100644 --- a/test/services/teams_test.dart +++ b/test/services/teams_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -74,10 +80,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.list(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/teams", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -92,13 +114,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.create( teamId: "", name: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/teams", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["teamId", "name"])); expect(response, isA()); }); @@ -113,12 +151,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.get( teamId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/teams/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -133,13 +187,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.updateName( teamId: "", name: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/teams/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["name"])); expect(response, isA()); }); @@ -147,12 +217,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.delete( teamId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/teams/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method listInstallations()', () async { @@ -162,12 +248,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.listInstallations( teamId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/teams//installations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -185,13 +287,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.createInstallation( teamId: "", appId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/teams//installations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["appId"])); expect(response, isA()); }); @@ -209,13 +327,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.getInstallation( teamId: "", installationId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/teams//installations/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -233,13 +367,29 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.updateInstallation( teamId: "", installationId: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/teams//installations/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -247,13 +397,29 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.deleteInstallation( teamId: "", installationId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/teams//installations/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method listMemberships()', () async { @@ -263,12 +429,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.listMemberships( teamId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/teams//memberships", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -292,13 +474,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.createMembership( teamId: "", roles: [], ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/teams//memberships", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["roles"])); expect(response, isA()); }); @@ -322,13 +520,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.getMembership( teamId: "", membershipId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/teams//memberships/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -352,7 +566,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.updateMembership( @@ -360,6 +580,16 @@ void main() { membershipId: "", roles: [], ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/teams//memberships/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["roles"])); expect(response, isA()); }); @@ -367,13 +597,29 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.deleteMembership( teamId: "", membershipId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/teams//memberships/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method updateMembershipStatus()', () async { @@ -396,7 +642,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.updateMembershipStatus( @@ -405,6 +657,16 @@ void main() { userId: "", secret: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/teams//memberships//status", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["userId", "secret"])); expect(response, isA()); }); @@ -412,12 +674,28 @@ void main() { final Map data = {}; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.getPrefs( teamId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/teams//prefs", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -425,13 +703,29 @@ void main() { final Map data = {}; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await teams.updatePrefs( teamId: "", prefs: {}, ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/teams//prefs", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["prefs"])); expect(response, isA()); }); }); diff --git a/test/services/vectors_db_test.dart b/test/services/vectors_db_test.dart index dc13e38d..066686f6 100644 --- a/test/services/vectors_db_test.dart +++ b/test/services/vectors_db_test.dart @@ -14,13 +14,18 @@ class MockClient extends Mock implements Client { @override Future call( HttpMethod? method, { - String path = '', - Map headers = const {}, - Map params = const {}, + String? path = '', + Map? headers = const {}, + Map? params = const {}, ResponseType? responseType, }) async { return super.noSuchMethod( - Invocation.method(#call, [method]), + Invocation.method(#call, [method], { + #path: path, + #headers: headers, + #params: params, + #responseType: responseType, + }), returnValue: Response(), ); } @@ -42,16 +47,17 @@ class MockClient extends Mock implements Client { Map? headers, Function(UploadProgress)? onProgress, ResponseType? responseType, - HttpMethod method = HttpMethod.post, + HttpMethod? method = HttpMethod.post, }) async { return super.noSuchMethod( - Invocation.method(#chunkedUpload, [ - path, - params, - paramName, - idParamName, - headers, - ]), + Invocation.method(#chunkedUpload, [], { + #path: path, + #params: params, + #paramName: paramName, + #idParamName: idParamName, + #headers: headers, + #method: method, + }), returnValue: Response(data: {}), ); } @@ -74,10 +80,26 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.listTransactions(); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/vectorsdb/transactions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -92,10 +114,26 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.createTransaction(); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/vectorsdb/transactions", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -110,12 +148,28 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.getTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/vectorsdb/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -130,12 +184,28 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.updateTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/vectorsdb/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -143,12 +213,28 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.deleteTransaction( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/vectorsdb/transactions/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); test('test method createOperations()', () async { @@ -162,12 +248,28 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.createOperations( transactionId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/vectorsdb/transactions//operations", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -178,13 +280,29 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.listDocuments( databaseId: "", collectionId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/vectorsdb//collections//documents", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -200,7 +318,13 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.createDocument( @@ -209,6 +333,16 @@ void main() { documentId: "", data: {}, ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/vectorsdb//collections//documents", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, unorderedEquals(["documentId", "data"])); expect(response, isA()); }); @@ -219,13 +353,29 @@ void main() { }; when( - client.call(HttpMethod.post), + client.call( + HttpMethod.post, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.createQuery( databaseId: "", collectionId: "", ); + final Map params = verify( + client.call( + HttpMethod.post, + path: "/vectorsdb//collections//documents/query", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -241,7 +391,13 @@ void main() { }; when( - client.call(HttpMethod.get), + client.call( + HttpMethod.get, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.getDocument( @@ -249,6 +405,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.get, + path: "/vectorsdb//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -264,7 +430,13 @@ void main() { }; when( - client.call(HttpMethod.put), + client.call( + HttpMethod.put, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.upsertDocument( @@ -272,6 +444,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.put, + path: "/vectorsdb//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -287,7 +469,13 @@ void main() { }; when( - client.call(HttpMethod.patch), + client.call( + HttpMethod.patch, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.updateDocument( @@ -295,6 +483,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.patch, + path: "/vectorsdb//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); expect(response, isA()); }); @@ -302,7 +500,13 @@ void main() { final data = ''; when( - client.call(HttpMethod.delete), + client.call( + HttpMethod.delete, + path: anyNamed('path'), + headers: anyNamed('headers'), + params: anyNamed('params'), + responseType: anyNamed('responseType'), + ), ).thenAnswer((_) async => Response(data: data)); final response = await vectorsDB.deleteDocument( @@ -310,6 +514,16 @@ void main() { collectionId: "", documentId: "", ); + final Map params = verify( + client.call( + HttpMethod.delete, + path: "/vectorsdb//collections//documents/", + headers: anyNamed('headers'), + params: captureAnyNamed('params'), + responseType: anyNamed('responseType'), + ), + ).captured.single; + expect(params.keys, isEmpty); }); }); } diff --git a/test/src/client_io_test.dart b/test/src/client_io_test.dart new file mode 100644 index 00000000..2a43f250 --- /dev/null +++ b/test/src/client_io_test.dart @@ -0,0 +1,202 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:appwrite/src/client_io.dart'; +import 'package:appwrite/src/exception.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final messenger = + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger; + + late HttpServer server; + late Directory documents; + late ClientIO client; + late List> authentications; + late List requests; + late String Function(Uri url, String callback) respond; + + setUp(() async { + HttpOverrides.global = null; + documents = await Directory.systemTemp.createTemp(); + messenger.setMockMethodCallHandler( + const MethodChannel('plugins.flutter.io/path_provider'), + (call) async => documents.path, + ); + authentications = []; + messenger.setMockMethodCallHandler( + const MethodChannel('flutter_web_auth_2'), + (call) async { + final arguments = Map.from(call.arguments as Map); + authentications.add(arguments); + return respond( + Uri.parse(arguments['url'] as String), + arguments['callbackUrlScheme'] as String, + ); + }, + ); + + requests = []; + server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0); + server.listen((request) async { + requests.add( + '${request.method} ${request.uri.path} ${await utf8.decoder.bind(request).join()}', + ); + request.response + ..headers.contentType = ContentType.json + ..cookies.add(Cookie('a_session_project', 'session')) + ..write('{}'); + await request.response.close(); + }); + + client = ClientIO(endPoint: 'http://127.0.0.1:${server.port}/v1'); + client.config['project'] = 'project'; + }); + + tearDown(() async { + debugDefaultTargetPlatformOverride = null; + messenger.setMockMethodCallHandler( + const MethodChannel('plugins.flutter.io/path_provider'), + null, + ); + messenger.setMockMethodCallHandler( + const MethodChannel('flutter_web_auth_2'), + null, + ); + await server.close(force: true); + await documents.delete(recursive: true); + }); + + Uri authorization() => Uri.parse( + 'http://127.0.0.1:${server.port}/v1/account/sessions/oauth2/github?scopes%5B%5D=user&scopes%5B%5D=repo&project=project', + ); + + String Function(Uri url, String callback) redirect( + String outcome, + String query, + ) => (url, callback) { + final target = Uri.parse(url.queryParameters[outcome]!); + if (target.origin != Uri.parse(callback).origin) { + throw PlatformException(code: 'CANCELED'); + } + return '$target?$query'; + }; + + Future> cookies() async => + (await client.cookieJar.loadForRequest( + Uri.parse('http://127.0.0.1:${server.port}/v1'), + )).map((cookie) => '${cookie.name}=${cookie.value}').toList(); + + for (final platform in [TargetPlatform.linux, TargetPlatform.windows]) { + group('webAuth on ${platform.name}', () { + setUp(() => debugDefaultTargetPlatformOverride = platform); + + test('signs in through a loopback token callback', () async { + respond = redirect('success', 'userId=user&secret=token'); + + await client.webAuth(authorization()); + + final callback = authentications.single['callbackUrlScheme'] as String; + expect(callback, matches(RegExp(r'^http://localhost:\d+/$'))); + final url = Uri.parse(authentications.single['url'] as String); + expect(url.path, '/v1/account/tokens/oauth2/github'); + expect(url.queryParametersAll['scopes[]'], ['user', 'repo']); + expect(url.queryParameters['project'], 'project'); + expect(url.queryParameters['success'], callback); + expect(url.queryParameters['failure'], callback); + expect(requests, [ + 'POST /v1/account/sessions/token {"userId":"user","secret":"token"}', + ]); + expect(await cookies(), ['a_session_project=session']); + }); + + test('routes the failure URL it is given through the callback', () async { + respond = redirect('success', 'userId=user&secret=token'); + + await client.webAuth( + authorization().replace( + queryParameters: { + ...authorization().queryParametersAll, + 'success': 'http://localhost:4000/auth', + 'failure': 'https://app.example/failed', + }, + ), + callbackUrlScheme: 'http://localhost:4000/auth', + ); + + expect( + authentications.single['callbackUrlScheme'], + 'http://localhost:4000/auth', + ); + final url = Uri.parse(authentications.single['url'] as String); + expect(url.queryParameters['success'], 'http://localhost:4000/auth'); + expect(url.queryParameters['failure'], 'http://localhost:4000/auth'); + expect(requests, hasLength(1)); + }); + + test('throws the error the callback carries', () async { + respond = redirect( + 'failure', + 'error=${Uri.encodeComponent('{"message":"Denied","code":401,"type":"user_oauth2_unauthorized"}')}', + ); + + await expectLater( + client.webAuth(authorization()), + throwsA( + isA() + .having((error) => error.message, 'message', 'Denied') + .having((error) => error.code, 'code', 401), + ), + ); + expect(requests, isEmpty); + }); + + test('throws the error of a failure URL it is given', () async { + respond = redirect( + 'failure', + 'error=${Uri.encodeComponent('{"message":"Denied","code":401,"type":"user_oauth2_unauthorized"}')}', + ); + + await expectLater( + client.webAuth( + authorization().replace( + queryParameters: { + ...authorization().queryParametersAll, + 'failure': 'https://app.example/failed', + }, + ), + ), + throwsA( + isA() + .having((error) => error.message, 'message', 'Denied') + .having((error) => error.code, 'code', 401), + ), + ); + final callback = authentications.single['callbackUrlScheme'] as String; + expect(callback, matches(RegExp(r'^http://localhost:\d+/$'))); + final url = Uri.parse(authentications.single['url'] as String); + expect(url.queryParameters['failure'], callback); + expect(requests, isEmpty); + }); + }); + } + + test('webAuth on android saves the session from the app callback', () async { + debugDefaultTargetPlatformOverride = TargetPlatform.android; + respond = (url, callback) => + '$callback://?key=a_session_project&secret=session'; + + await client.webAuth(authorization()); + + expect( + authentications.single['callbackUrlScheme'], + 'appwrite-callback-project', + ); + expect(authentications.single['url'], authorization().toString()); + expect(requests, isEmpty); + expect(await cookies(), ['a_session_project=session']); + }); +}