Merge pull request #263 from appwrite/dev

Add 1.8.x support
This commit is contained in:
Jake Barnby
2025-08-26 19:38:15 +12:00
committed by GitHub
125 changed files with 1859 additions and 498 deletions
+16
View File
@@ -0,0 +1,16 @@
name: Analyze and test
on: pull_request
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Flutter
uses: subosito/flutter-action@v2
with:
channel: stable
- run: flutter pub get
- run: flutter analyze --no-fatal-infos --no-fatal-warnings
- run: flutter test
+21
View File
@@ -1,5 +1,26 @@
# Change Log
## 18.0.0
* Support for Appwrite 1.8
* Added TablesDB service
* Added new query types:
* `notContains`
* `notSearch`
* `notBetween`
* `notStartsWith`
* `notEndsWith`
* `createdBefore`
* `createdAfter`
* `updatedBefore`
* `updatedAfter`
* Deprecated `updateMagicURLSession`
* Deprecated `updatePhoneSession`
* Deprecated Databases service
> The TablesDB service is the new recommended way to work with databases.
> Existing databases/collections/attributes/documents can be managed using the TablesDB service.
> Existing Databases service will continue to work, but new features may only be added to the TablesDB service.
## 17.1.0
* Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service
+27 -51
View File
@@ -2,12 +2,12 @@
[![pub package](https://img.shields.io/pub/v/appwrite?style=flat-square)](https://pub.dartlang.org/packages/appwrite)
![License](https://img.shields.io/github/license/appwrite/sdk-for-flutter.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.7.x-blue.svg?style=flat-square)
![Version](https://img.shields.io/badge/api%20version-1.8.x-blue.svg?style=flat-square)
[![Build Status](https://img.shields.io/travis/com/appwrite/sdk-generator?style=flat-square)](https://travis-ci.com/appwrite/sdk-generator)
[![Twitter Account](https://img.shields.io/twitter/follow/appwrite?color=00acee&label=twitter&style=flat-square)](https://twitter.com/appwrite)
[![Discord](https://img.shields.io/discord/564160730845151244?label=discord&style=flat-square)](https://appwrite.io/discord)
**This SDK is compatible with Appwrite server version 1.7.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-flutter/releases).**
**This SDK is compatible with Appwrite server version 1.8.x. For older versions, please check [previous releases](https://github.com/appwrite/sdk-for-flutter/releases).**
Appwrite is an open-source backend as a service server that abstract and simplify complex and repetitive development tasks behind a very simple to use REST API. Appwrite aims to help you develop your apps faster and in a more secure way. Use the Flutter SDK to integrate your app with the Appwrite server to easily start interacting with all of Appwrite backend APIs and tools. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)
@@ -21,7 +21,7 @@ Add this to your package's `pubspec.yaml` file:
```yml
dependencies:
appwrite: ^17.1.0
appwrite: ^18.0.0
```
You can install packages from the command line:
@@ -50,7 +50,7 @@ In order to capture the Appwrite OAuth callback url, the following activity need
....
<application ...>
....
<!-- Add this inside the <application> tag, along side the existing <activity> tags -->
<!-- Add this inside the <application> tag, alongside the existing <activity> tags -->
<activity android:exported="true" android:name="com.linusu.flutter_web_auth_2.CallbackActivity" >
<intent-filter android:label="flutter_web_auth_2">
<action android:name="android.intent.action.VIEW" />
@@ -76,8 +76,8 @@ The Appwrite SDK uses ASWebAuthenticationSession on iOS 12+ and SFAuthentication
### Linux
For **Linux** add your app <u>name</u> and <u>package name</u>, Your package name is generally the **name** in your <a href="https://github.com/appwrite/playground-for-flutter/blob/0fdbdff98384fff940ed0b1e08cf14cfe3a2be3e/pubspec.yaml#L1" target="_blank" rel="noopener">pubspec.yaml<a> file. If you cannot find the correct package name, run the application in linux, and make any request with proper exception handling, you should get the application ID needed to add in the received error message.
### Mac OS
For **Mac OS** add your app name and Bundle ID, You can find your Bundle Identifier in the General tab for your app's primary target in Xcode.
### macOS
For **macOS** add your app name and Bundle ID, You can find your Bundle Identifier in the General tab for your app's primary target in Xcode.
The Appwrite SDK uses ASWebAuthenticationSession on macOS 10.15+ to allow OAuth authentication. You have to change your macOS Deployment Target in Xcode to be macOS >= 10.15 to be able to build your app for macOS.
@@ -121,77 +121,53 @@ For **Windows** add your app <u>name</u> and <u>package name</u>, Your package n
### Init your SDK
<p>Initialize your SDK with your Appwrite server API endpoint and project ID, which can be found in your project settings page.
<p>Initialize your SDK with your project ID, which can be found in your project settings page.
```dart
import 'package:appwrite/appwrite.dart';
void main() {
Client client = Client();
client
.setEndpoint('https://localhost/v1') // Your Appwrite Endpoint
.setProject('5e8cf4f46b5e8') // Your project ID
.setSelfSigned() // Use only on dev mode with a self-signed SSL cert
;
}
Client client = Client().setProject('<YOUR_PROJECT_ID>');
```
Before starting to send any API calls to your new Appwrite instance, make sure your Android or iOS emulators has network access to the Appwrite server hostname or IP address.
When trying to connect to Appwrite from an emulator or a mobile device, localhost is the hostname for the device or emulator and not your local Appwrite instance. You should replace localhost with your private IP as the Appwrite endpoint's hostname. You can also use a service like [ngrok](https://ngrok.com/) to proxy the Appwrite API.
> If using a self-hosted instance, you will also need to set your Appwrite endpoint using the `setEndpoint` method. Before starting to send any API calls to your new Appwrite instance, make sure your Android or iOS emulators has network access to the Appwrite server hostname or IP address.
> When trying to connect to a local Appwrite instance from an emulator or a mobile device, localhost is the hostname for the device or emulator and not your machine. You should replace localhost with your machine's private IP as the Appwrite endpoint's hostname (e.g. 192.168.1.100). You can also use a service like [ngrok](https://ngrok.com/) to proxy the Appwrite API.
### Make Your First Request
<p>Once your SDK object is set, access any of the Appwrite services and choose any request to send. Full documentation for any service method you would like to use can be found in your SDK documentation or in the [API References](https://appwrite.io/docs) section.
```dart
// Register User
Account account = Account(client);
final user = await account
.create(
userId: ID.unique(), email: "email@example.com", password: "password", name: "Walter O'Brien"
);
User user = await account.create(
userId: ID.unique(),
email: 'email@example.com',
password: 'password',
name: 'Walter O'Brien',
);
```
### Full Example
```dart
import 'package:appwrite/appwrite.dart';
Client client = Client().setProject('<YOUR_PROJECT_ID>>');
void main() {
Client client = Client();
Account account = Account(client);
client
.setEndpoint('https://localhost/v1') // Your Appwrite Endpoint
.setProject('5e8cf4f46b5e8') // Your project ID
.setSelfSigned() // Use only on dev mode with a self-signed SSL cert
;
// Register User
Account account = Account(client);
final user = await account
.create(
userId: ID.unique(), email: "email@example.com", password: "password", name: "Walter O'Brien"
);
}
User user = await account.create(
userId: ID.unique(),
email: 'email@example.com',
password: 'password',
name: 'Walter O'Brien'
);
```
### Error Handling
The Appwrite Flutter SDK raises `AppwriteException` object with `message`, `type`, `code` and `response` properties. You can handle any errors by catching `AppwriteException` and present the `message` to the user or handle it yourself based on the provided error information. Below is an example.
```dart
Account account = Account(client);
try {
final user = await account.create(userId: ID.unique(), email: "email@example.com", password: "password", name: "Walter O'Brien");
print(user.toMap());
User user = await account.create(...);
} on AppwriteException catch(e) {
//show message to user or do other operation based on error as required
print(e.message);
// Handle the exception
}
```
+1
View File
@@ -0,0 +1 @@
include: package:flutter_lints/flutter.yaml
@@ -6,6 +6,6 @@ Client client = Client()
Account account = Account(client);
MfaType result = await account.createMfaAuthenticator(
MfaType result = await account.createMFAAuthenticator(
type: AuthenticatorType.totp,
);
@@ -6,6 +6,6 @@ Client client = Client()
Account account = Account(client);
MfaChallenge result = await account.createMfaChallenge(
MfaChallenge result = await account.createMFAChallenge(
factor: AuthenticationFactor.email,
);
@@ -6,4 +6,4 @@ Client client = Client()
Account account = Account(client);
MfaRecoveryCodes result = await account.createMfaRecoveryCodes();
MfaRecoveryCodes result = await account.createMFARecoveryCodes();
@@ -6,6 +6,6 @@ Client client = Client()
Account account = Account(client);
await account.deleteMfaAuthenticator(
await account.deleteMFAAuthenticator(
type: AuthenticatorType.totp,
);
@@ -6,4 +6,4 @@ Client client = Client()
Account account = Account(client);
MfaRecoveryCodes result = await account.getMfaRecoveryCodes();
MfaRecoveryCodes result = await account.getMFARecoveryCodes();
+1 -1
View File
@@ -6,4 +6,4 @@ Client client = Client()
Account account = Account(client);
MfaFactors result = await account.listMfaFactors();
MfaFactors result = await account.listMFAFactors();
@@ -6,7 +6,7 @@ Client client = Client()
Account account = Account(client);
User result = await account.updateMfaAuthenticator(
User result = await account.updateMFAAuthenticator(
type: AuthenticatorType.totp,
otp: '<OTP>',
);
@@ -6,7 +6,7 @@ Client client = Client()
Account account = Account(client);
Session result = await account.updateMfaChallenge(
Session result = await account.updateMFAChallenge(
challengeId: '<CHALLENGE_ID>',
otp: '<OTP>',
);
@@ -6,4 +6,4 @@ Client client = Client()
Account account = Account(client);
MfaRecoveryCodes result = await account.updateMfaRecoveryCodes();
MfaRecoveryCodes result = await account.updateMFARecoveryCodes();
+1 -1
View File
@@ -13,5 +13,5 @@ Execution result = await functions.createExecution(
path: '<PATH>', // optional
method: ExecutionMethod.gET, // optional
headers: {}, // optional
scheduledAt: '', // optional
scheduledAt: '<SCHEDULED_AT>', // optional
);
+15
View File
@@ -0,0 +1,15 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
TablesDB tablesDB = TablesDB(client);
Row result = await tablesDB.createRow(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
data: {},
permissions: ["read("any")"], // optional
);
@@ -0,0 +1,16 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
TablesDB tablesDB = TablesDB(client);
Row result = await tablesDB.decrementRowColumn(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
column: '',
value: 0, // optional
min: 0, // optional
);
+13
View File
@@ -0,0 +1,13 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
TablesDB tablesDB = TablesDB(client);
await tablesDB.deleteRow(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
);
+14
View File
@@ -0,0 +1,14 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
TablesDB tablesDB = TablesDB(client);
Row result = await tablesDB.getRow(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
queries: [], // optional
);
@@ -0,0 +1,16 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
TablesDB tablesDB = TablesDB(client);
Row result = await tablesDB.incrementRowColumn(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
column: '',
value: 0, // optional
max: 0, // optional
);
+13
View File
@@ -0,0 +1,13 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
TablesDB tablesDB = TablesDB(client);
RowList result = await tablesDB.listRows(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
queries: [], // optional
);
+15
View File
@@ -0,0 +1,15 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
TablesDB tablesDB = TablesDB(client);
Row result = await tablesDB.updateRow(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
data: {}, // optional
permissions: ["read("any")"], // optional
);
+15
View File
@@ -0,0 +1,15 @@
import 'package:appwrite/appwrite.dart';
Client client = Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
TablesDB tablesDB = TablesDB(client);
Row result = await tablesDB.upsertRow(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
data: {}, // optional
permissions: ["read("any")"], // optional
);
+2 -1
View File
@@ -1,6 +1,6 @@
/// Appwrite Flutter SDK
///
/// This SDK is compatible with Appwrite server version 1.7.x.
/// This SDK is compatible with Appwrite server version 1.8.x.
/// For older versions, please check
/// [previous releases](https://github.com/appwrite/sdk-for-flutter/releases).
library appwrite;
@@ -38,4 +38,5 @@ part 'services/graphql.dart';
part 'services/locale.dart';
part 'services/messaging.dart';
part 'services/storage.dart';
part 'services/tables_db.dart';
part 'services/teams.dart';
+2
View File
@@ -2,6 +2,7 @@
library appwrite.models;
part 'src/models/model.dart';
part 'src/models/row_list.dart';
part 'src/models/document_list.dart';
part 'src/models/session_list.dart';
part 'src/models/identity_list.dart';
@@ -16,6 +17,7 @@ part 'src/models/language_list.dart';
part 'src/models/currency_list.dart';
part 'src/models/phone_list.dart';
part 'src/models/locale_code_list.dart';
part 'src/models/row.dart';
part 'src/models/document.dart';
part 'src/models/log.dart';
part 'src/models/user.dart';
+37
View File
@@ -82,6 +82,43 @@ class Query {
static String contains(String attribute, dynamic value) =>
Query._('contains', attribute, value).toString();
/// Filter resources where [attribute] does not contain [value]
/// [value] can be a single value or a list.
static String notContains(String attribute, dynamic value) =>
Query._('notContains', attribute, value).toString();
/// Filter resources by searching [attribute] for [value] (inverse of search).
static String notSearch(String attribute, String value) =>
Query._('notSearch', attribute, value).toString();
/// Filter resources where [attribute] is not between [start] and [end] (exclusive).
static String notBetween(String attribute, dynamic start, dynamic end) =>
Query._('notBetween', attribute, [start, end]).toString();
/// Filter resources where [attribute] does not start with [value].
static String notStartsWith(String attribute, String value) =>
Query._('notStartsWith', attribute, value).toString();
/// Filter resources where [attribute] does not end with [value].
static String notEndsWith(String attribute, String value) =>
Query._('notEndsWith', attribute, value).toString();
/// Filter resources where document was created before [value].
static String createdBefore(String value) =>
Query._('createdBefore', null, value).toString();
/// Filter resources where document was created after [value].
static String createdAfter(String value) =>
Query._('createdAfter', null, value).toString();
/// Filter resources where document was updated before [value].
static String updatedBefore(String value) =>
Query._('updatedBefore', null, value).toString();
/// Filter resources where document was updated after [value].
static String updatedAfter(String value) =>
Query._('updatedAfter', null, value).toString();
static String or(List<String> queries) => Query._(
'or',
null,
+240 -2
View File
@@ -190,6 +190,9 @@ class Account extends Service {
/// authenticator using the [verify
/// authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator)
/// method.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `Account.createMFAAuthenticator` instead.',
)
Future<models.MfaType> createMfaAuthenticator({
required enums.AuthenticatorType type,
}) async {
@@ -212,9 +215,38 @@ class Account extends Service {
return models.MfaType.fromMap(res.data);
}
/// Add an authenticator app to be used as an MFA factor. Verify the
/// authenticator using the [verify
/// authenticator](/docs/references/cloud/client-web/account#updateMfaAuthenticator)
/// method.
Future<models.MfaType> createMFAAuthenticator({
required enums.AuthenticatorType type,
}) async {
final String apiPath = '/account/mfa/authenticators/{type}'.replaceAll(
'{type}',
type.value,
);
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.post,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.MfaType.fromMap(res.data);
}
/// Verify an authenticator app after adding it using the [add
/// authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator)
/// method.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `Account.updateMFAAuthenticator` instead.',
)
Future<models.User> updateMfaAuthenticator({
required enums.AuthenticatorType type,
required String otp,
@@ -238,7 +270,36 @@ class Account extends Service {
return models.User.fromMap(res.data);
}
/// Verify an authenticator app after adding it using the [add
/// authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator)
/// method.
Future<models.User> updateMFAAuthenticator({
required enums.AuthenticatorType type,
required String otp,
}) async {
final String apiPath = '/account/mfa/authenticators/{type}'.replaceAll(
'{type}',
type.value,
);
final Map<String, dynamic> apiParams = {'otp': otp};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.put,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.User.fromMap(res.data);
}
/// Delete an authenticator for a user by ID.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `Account.deleteMFAAuthenticator` instead.',
)
Future deleteMfaAuthenticator({required enums.AuthenticatorType type}) async {
final String apiPath = '/account/mfa/authenticators/{type}'.replaceAll(
'{type}',
@@ -259,9 +320,33 @@ class Account extends Service {
return res.data;
}
/// Delete an authenticator for a user by ID.
Future deleteMFAAuthenticator({required enums.AuthenticatorType type}) async {
final String apiPath = '/account/mfa/authenticators/{type}'.replaceAll(
'{type}',
type.value,
);
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.delete,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return res.data;
}
/// Begin the process of MFA verification after sign-in. Finish the flow with
/// [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge)
/// method.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `Account.createMFAChallenge` instead.',
)
Future<models.MfaChallenge> createMfaChallenge({
required enums.AuthenticationFactor factor,
}) async {
@@ -281,11 +366,36 @@ class Account extends Service {
return models.MfaChallenge.fromMap(res.data);
}
/// Begin the process of MFA verification after sign-in. Finish the flow with
/// [updateMfaChallenge](/docs/references/cloud/client-web/account#updateMfaChallenge)
/// method.
Future<models.MfaChallenge> createMFAChallenge({
required enums.AuthenticationFactor factor,
}) async {
const String apiPath = '/account/mfa/challenge';
final Map<String, dynamic> apiParams = {'factor': factor.value};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.post,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.MfaChallenge.fromMap(res.data);
}
/// Complete the MFA challenge by providing the one-time password. Finish the
/// process of MFA verification by providing the one-time password. To begin
/// the flow, use
/// [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge)
/// method.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `Account.updateMFAChallenge` instead.',
)
Future<models.Session> updateMfaChallenge({
required String challengeId,
required String otp,
@@ -309,7 +419,38 @@ class Account extends Service {
return models.Session.fromMap(res.data);
}
/// Complete the MFA challenge by providing the one-time password. Finish the
/// process of MFA verification by providing the one-time password. To begin
/// the flow, use
/// [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge)
/// method.
Future<models.Session> updateMFAChallenge({
required String challengeId,
required String otp,
}) async {
const String apiPath = '/account/mfa/challenge';
final Map<String, dynamic> apiParams = {
'challengeId': challengeId,
'otp': otp,
};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.put,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.Session.fromMap(res.data);
}
/// List the factors available on the account to be used as a MFA challange.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `Account.listMFAFactors` instead.',
)
Future<models.MfaFactors> listMfaFactors() async {
const String apiPath = '/account/mfa/factors';
@@ -327,10 +468,31 @@ class Account extends Service {
return models.MfaFactors.fromMap(res.data);
}
/// List the factors available on the account to be used as a MFA challange.
Future<models.MfaFactors> listMFAFactors() async {
const String apiPath = '/account/mfa/factors';
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {};
final res = await client.call(
HttpMethod.get,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.MfaFactors.fromMap(res.data);
}
/// Get recovery codes that can be used as backup for MFA flow. Before getting
/// codes, they must be generated using
/// [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes)
/// method. An OTP challenge is required to read recovery codes.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `Account.getMFARecoveryCodes` instead.',
)
Future<models.MfaRecoveryCodes> getMfaRecoveryCodes() async {
const String apiPath = '/account/mfa/recovery-codes';
@@ -348,11 +510,35 @@ class Account extends Service {
return models.MfaRecoveryCodes.fromMap(res.data);
}
/// Get recovery codes that can be used as backup for MFA flow. Before getting
/// codes, they must be generated using
/// [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes)
/// method. An OTP challenge is required to read recovery codes.
Future<models.MfaRecoveryCodes> getMFARecoveryCodes() async {
const String apiPath = '/account/mfa/recovery-codes';
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {};
final res = await client.call(
HttpMethod.get,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.MfaRecoveryCodes.fromMap(res.data);
}
/// Generate recovery codes as backup for MFA flow. It's recommended to
/// generate and show then immediately after user successfully adds their
/// authehticator. Recovery codes can be used as a MFA verification type in
/// [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge)
/// method.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `Account.createMFARecoveryCodes` instead.',
)
Future<models.MfaRecoveryCodes> createMfaRecoveryCodes() async {
const String apiPath = '/account/mfa/recovery-codes';
@@ -370,10 +556,35 @@ class Account extends Service {
return models.MfaRecoveryCodes.fromMap(res.data);
}
/// Generate recovery codes as backup for MFA flow. It's recommended to
/// generate and show then immediately after user successfully adds their
/// authehticator. Recovery codes can be used as a MFA verification type in
/// [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge)
/// method.
Future<models.MfaRecoveryCodes> createMFARecoveryCodes() async {
const String apiPath = '/account/mfa/recovery-codes';
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.post,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.MfaRecoveryCodes.fromMap(res.data);
}
/// Regenerate recovery codes that can be used as backup for MFA flow. Before
/// regenerating codes, they must be first generated using
/// [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes)
/// method. An OTP challenge is required to regenreate recovery codes.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `Account.updateMFARecoveryCodes` instead.',
)
Future<models.MfaRecoveryCodes> updateMfaRecoveryCodes() async {
const String apiPath = '/account/mfa/recovery-codes';
@@ -391,6 +602,27 @@ class Account extends Service {
return models.MfaRecoveryCodes.fromMap(res.data);
}
/// Regenerate recovery codes that can be used as backup for MFA flow. Before
/// regenerating codes, they must be first generated using
/// [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes)
/// method. An OTP challenge is required to regenreate recovery codes.
Future<models.MfaRecoveryCodes> updateMFARecoveryCodes() async {
const String apiPath = '/account/mfa/recovery-codes';
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.patch,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.MfaRecoveryCodes.fromMap(res.data);
}
/// Update currently logged in user account name.
Future<models.User> updateName({required String name}) async {
const String apiPath = '/account/name';
@@ -658,6 +890,7 @@ class Account extends Service {
/// Use this endpoint to create a session from token. Provide the **userId**
/// and **secret** parameters from the successful response of authentication
/// flows initiated by token creation. For example, magic URL and phone login.
@Deprecated('This API has been deprecated.')
Future<models.Session> updateMagicURLSession({
required String userId,
required String secret,
@@ -742,6 +975,7 @@ class Account extends Service {
/// Use this endpoint to create a session from token. Provide the **userId**
/// and **secret** parameters from the successful response of authentication
/// flows initiated by token creation. For example, magic URL and phone login.
@Deprecated('This API has been deprecated.')
Future<models.Session> updatePhoneSession({
required String userId,
required String secret,
@@ -957,8 +1191,11 @@ class Account extends Service {
}
/// Sends the user an email with a secret key for creating a session. If the
/// provided user ID has not be registered, a new user will be created. Use the
/// returned user ID and secret and submit a request to the [POST
/// email address has never been used, a **new account is created** using the
/// provided `userId`. Otherwise, if the email address is already attached to
/// an account, the **user ID is ignored**. Then, the user will receive an
/// email with the one-time password. Use the returned user ID and secret and
/// submit a request to the [POST
/// /v1/account/sessions/token](https://appwrite.io/docs/references/cloud/client-web/account#createSession)
/// endpoint to complete the login process. The secret sent to the user's email
/// is valid for 15 minutes.
@@ -966,6 +1203,7 @@ class Account extends Service {
/// A user is limited to 10 active sessions at a time by default. [Learn more
/// about session
/// limits](https://appwrite.io/docs/authentication-security#limits).
///
Future<models.Token> createEmailToken({
required String userId,
required String email,
+24 -4
View File
@@ -8,6 +8,9 @@ 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.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `TablesDB.listRows` instead.',
)
Future<models.DocumentList> listDocuments({
required String databaseId,
required String collectionId,
@@ -36,6 +39,9 @@ class Databases extends Service {
/// collection resource using either a [server
/// integration](https://appwrite.io/docs/server/databases#databasesCreateCollection)
/// API or directly from your database console.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `TablesDB.createRow` instead.',
)
Future<models.Document> createDocument({
required String databaseId,
required String collectionId,
@@ -68,6 +74,9 @@ class Databases extends Service {
/// Get a document by its unique ID. This endpoint response returns a JSON
/// object with the document data.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `TablesDB.getRow` instead.',
)
Future<models.Document> getDocument({
required String databaseId,
required String collectionId,
@@ -94,14 +103,13 @@ class Databases extends Service {
return models.Document.fromMap(res.data);
}
/// **WARNING: Experimental Feature** - This endpoint is experimental and not
/// yet officially supported. It may be subject to breaking changes or removal
/// in future versions.
///
/// Create or update a Document. Before using this route, you should create a
/// new collection resource using either a [server
/// integration](https://appwrite.io/docs/server/databases#databasesCreateCollection)
/// API or directly from your database console.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `TablesDB.upsertRow` instead.',
)
Future<models.Document> upsertDocument({
required String databaseId,
required String collectionId,
@@ -134,6 +142,9 @@ class Databases extends Service {
/// Update a document by its unique ID. Using the patch method you can pass
/// only specific fields that will get updated.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `TablesDB.updateRow` instead.',
)
Future<models.Document> updateDocument({
required String databaseId,
required String collectionId,
@@ -165,6 +176,9 @@ class Databases extends Service {
}
/// Delete a document by its unique ID.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `TablesDB.deleteRow` instead.',
)
Future deleteDocument({
required String databaseId,
required String collectionId,
@@ -191,6 +205,9 @@ class Databases extends Service {
}
/// Decrement a specific attribute of a document by a given value.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `TablesDB.decrementRowColumn` instead.',
)
Future<models.Document> decrementDocumentAttribute({
required String databaseId,
required String collectionId,
@@ -221,6 +238,9 @@ class Databases extends Service {
}
/// Increment a specific attribute of a document by a given value.
@Deprecated(
'This API has been deprecated since 1.8.0. Please use `TablesDB.incrementRowColumn` instead.',
)
Future<models.Document> incrementDocumentAttribute({
required String databaseId,
required String collectionId,
+244
View File
@@ -0,0 +1,244 @@
part of '../appwrite.dart';
class TablesDB extends Service {
/// Initializes a [TablesDB] service
TablesDB(super.client);
/// Get a list of all the user's rows in a given table. You can use the query
/// params to filter your results.
Future<models.RowList> listRows({
required String databaseId,
required String tableId,
List<String>? queries,
}) async {
final String apiPath = '/tablesdb/{databaseId}/tables/{tableId}/rows'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId);
final Map<String, dynamic> apiParams = {'queries': queries};
final Map<String, String> apiHeaders = {};
final res = await client.call(
HttpMethod.get,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.RowList.fromMap(res.data);
}
/// Create a new Row. Before using this route, you should create a new table
/// resource using either a [server
/// integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreateTable)
/// API or directly from your database console.
Future<models.Row> createRow({
required String databaseId,
required String tableId,
required String rowId,
required Map data,
List<String>? permissions,
}) async {
final String apiPath = '/tablesdb/{databaseId}/tables/{tableId}/rows'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId);
final Map<String, dynamic> apiParams = {
'rowId': rowId,
'data': data,
'permissions': permissions,
};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.post,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.Row.fromMap(res.data);
}
/// Get a row by its unique ID. This endpoint response returns a JSON object
/// with the row data.
Future<models.Row> getRow({
required String databaseId,
required String tableId,
required String rowId,
List<String>? queries,
}) async {
final String apiPath =
'/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId)
.replaceAll('{rowId}', rowId);
final Map<String, dynamic> apiParams = {'queries': queries};
final Map<String, String> apiHeaders = {};
final res = await client.call(
HttpMethod.get,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.Row.fromMap(res.data);
}
/// Create or update a Row. Before using this route, you should create a new
/// table resource using either a [server
/// integration](https://appwrite.io/docs/server/tablesdb#tablesDBCreateTable)
/// API or directly from your database console.
Future<models.Row> upsertRow({
required String databaseId,
required String tableId,
required String rowId,
Map? data,
List<String>? permissions,
}) async {
final String apiPath =
'/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId)
.replaceAll('{rowId}', rowId);
final Map<String, dynamic> apiParams = {
'data': data,
'permissions': permissions,
};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.put,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.Row.fromMap(res.data);
}
/// Update a row by its unique ID. Using the patch method you can pass only
/// specific fields that will get updated.
Future<models.Row> updateRow({
required String databaseId,
required String tableId,
required String rowId,
Map? data,
List<String>? permissions,
}) async {
final String apiPath =
'/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId)
.replaceAll('{rowId}', rowId);
final Map<String, dynamic> apiParams = {
'data': data,
'permissions': permissions,
};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.patch,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.Row.fromMap(res.data);
}
/// Delete a row by its unique ID.
Future deleteRow({
required String databaseId,
required String tableId,
required String rowId,
}) async {
final String apiPath =
'/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId)
.replaceAll('{rowId}', rowId);
final Map<String, dynamic> apiParams = {};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.delete,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return res.data;
}
/// Decrement a specific column of a row by a given value.
Future<models.Row> decrementRowColumn({
required String databaseId,
required String tableId,
required String rowId,
required String column,
double? value,
double? min,
}) async {
final String apiPath =
'/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}/{column}/decrement'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId)
.replaceAll('{rowId}', rowId)
.replaceAll('{column}', column);
final Map<String, dynamic> apiParams = {'value': value, 'min': min};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.patch,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.Row.fromMap(res.data);
}
/// Increment a specific column of a row by a given value.
Future<models.Row> incrementRowColumn({
required String databaseId,
required String tableId,
required String rowId,
required String column,
double? value,
double? max,
}) async {
final String apiPath =
'/tablesdb/{databaseId}/tables/{tableId}/rows/{rowId}/{column}/increment'
.replaceAll('{databaseId}', databaseId)
.replaceAll('{tableId}', tableId)
.replaceAll('{rowId}', rowId)
.replaceAll('{column}', column);
final Map<String, dynamic> apiParams = {'value': value, 'max': max};
final Map<String, String> apiHeaders = {'content-type': 'application/json'};
final res = await client.call(
HttpMethod.patch,
path: apiPath,
params: apiParams,
headers: apiHeaders,
);
return models.Row.fromMap(res.data);
}
}
+4 -4
View File
@@ -40,8 +40,8 @@ class ClientBrowser extends ClientBase with ClientMixin {
'x-sdk-name': 'Flutter',
'x-sdk-platform': 'client',
'x-sdk-language': 'flutter',
'x-sdk-version': '17.1.0',
'X-Appwrite-Response-Format': '1.7.0',
'x-sdk-version': '18.0.0',
'X-Appwrite-Response-Format': '1.8.0',
};
config = {};
@@ -132,7 +132,7 @@ class ClientBrowser extends ClientBase with ClientMixin {
}
Future init() async {
final cookieFallback = web.window.localStorage['cookieFallback'];
final cookieFallback = web.window.localStorage.getItem('cookieFallback');
if (cookieFallback != null) {
addHeader('x-fallback-cookies', cookieFallback);
}
@@ -253,7 +253,7 @@ class ClientBrowser extends ClientBase with ClientMixin {
'Appwrite is using localStorage for session management. Increase your security by adding a custom domain as your API endpoint.',
);
addHeader('X-Fallback-Cookies', cookieFallback);
web.window.localStorage['cookieFallback'] = cookieFallback;
web.window.localStorage.setItem('cookieFallback', cookieFallback);
}
return prepareResponse(res, responseType: responseType);
} catch (e) {
+2 -2
View File
@@ -58,8 +58,8 @@ class ClientIO extends ClientBase with ClientMixin {
'x-sdk-name': 'Flutter',
'x-sdk-platform': 'client',
'x-sdk-language': 'flutter',
'x-sdk-version': '17.1.0',
'X-Appwrite-Response-Format': '1.7.0',
'x-sdk-version': '18.0.0',
'X-Appwrite-Response-Format': '1.8.0',
};
config = {};
+1 -1
View File
@@ -16,6 +16,6 @@ enum ResponseType {
/// Transform the response data to a String encoded with UTF8.
plain,
/// Get original bytes, the type of response will be List<int>
/// Get original bytes, the type of response will be `List<int>`
bytes,
}
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Continents List
class ContinentList implements Model {
/// Total number of continents documents that matched your query.
/// Total number of continents that matched your query.
final int total;
/// List of continents.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Countries List
class CountryList implements Model {
/// Total number of countries documents that matched your query.
/// Total number of countries that matched your query.
final int total;
/// List of countries.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Currencies List
class CurrencyList implements Model {
/// Total number of currencies documents that matched your query.
/// Total number of currencies that matched your query.
final int total;
/// List of currencies.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Documents List
class DocumentList implements Model {
/// Total number of documents documents that matched your query.
/// Total number of documents that matched your query.
final int total;
/// List of documents.
+7 -1
View File
@@ -8,7 +8,7 @@ class Execution implements Model {
/// Execution creation date in ISO 8601 format.
final String $createdAt;
/// Execution upate date in ISO 8601 format.
/// Execution update date in ISO 8601 format.
final String $updatedAt;
/// Execution roles.
@@ -17,6 +17,9 @@ class Execution implements Model {
/// Function ID.
final String functionId;
/// Function&#039;s deployment ID used to create the execution.
final String deploymentId;
/// The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`.
final String trigger;
@@ -59,6 +62,7 @@ class Execution implements Model {
required this.$updatedAt,
required this.$permissions,
required this.functionId,
required this.deploymentId,
required this.trigger,
required this.status,
required this.requestMethod,
@@ -80,6 +84,7 @@ class Execution implements Model {
$updatedAt: map['\$updatedAt'].toString(),
$permissions: List.from(map['\$permissions'] ?? []),
functionId: map['functionId'].toString(),
deploymentId: map['deploymentId'].toString(),
trigger: map['trigger'].toString(),
status: map['status'].toString(),
requestMethod: map['requestMethod'].toString(),
@@ -106,6 +111,7 @@ class Execution implements Model {
"\$updatedAt": $updatedAt,
"\$permissions": $permissions,
"functionId": functionId,
"deploymentId": deploymentId,
"trigger": trigger,
"status": status,
"requestMethod": requestMethod,
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Executions List
class ExecutionList implements Model {
/// Total number of executions documents that matched your query.
/// Total number of executions that matched your query.
final int total;
/// List of executions.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Files List
class FileList implements Model {
/// Total number of files documents that matched your query.
/// Total number of files that matched your query.
final int total;
/// List of files.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Identities List
class IdentityList implements Model {
/// Total number of identities documents that matched your query.
/// Total number of identities that matched your query.
final int total;
/// List of identities.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Languages List
class LanguageList implements Model {
/// Total number of languages documents that matched your query.
/// Total number of languages that matched your query.
final int total;
/// List of languages.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Locale codes list
class LocaleCodeList implements Model {
/// Total number of localeCodes documents that matched your query.
/// Total number of localeCodes that matched your query.
final int total;
/// List of localeCodes.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Logs List
class LogList implements Model {
/// Total number of logs documents that matched your query.
/// Total number of logs that matched your query.
final int total;
/// List of logs.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Memberships List
class MembershipList implements Model {
/// Total number of memberships documents that matched your query.
/// Total number of memberships that matched your query.
final int total;
/// List of memberships.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Phones List
class PhoneList implements Model {
/// Total number of phones documents that matched your query.
/// Total number of phones that matched your query.
final int total;
/// List of phones.
+66
View File
@@ -0,0 +1,66 @@
part of '../../models.dart';
/// Row
class Row implements Model {
/// Row ID.
final String $id;
/// Row automatically incrementing ID.
final int $sequence;
/// Table ID.
final String $tableId;
/// Database ID.
final String $databaseId;
/// Row creation date in ISO 8601 format.
final String $createdAt;
/// Row update date in ISO 8601 format.
final String $updatedAt;
/// Row permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).
final List<String> $permissions;
final Map<String, dynamic> data;
Row({
required this.$id,
required this.$sequence,
required this.$tableId,
required this.$databaseId,
required this.$createdAt,
required this.$updatedAt,
required this.$permissions,
required this.data,
});
factory Row.fromMap(Map<String, dynamic> map) {
return Row(
$id: map['\$id'].toString(),
$sequence: map['\$sequence'],
$tableId: map['\$tableId'].toString(),
$databaseId: map['\$databaseId'].toString(),
$createdAt: map['\$createdAt'].toString(),
$updatedAt: map['\$updatedAt'].toString(),
$permissions: List.from(map['\$permissions'] ?? []),
data: map,
);
}
Map<String, dynamic> toMap() {
return {
"\$id": $id,
"\$sequence": $sequence,
"\$tableId": $tableId,
"\$databaseId": $databaseId,
"\$createdAt": $createdAt,
"\$updatedAt": $updatedAt,
"\$permissions": $permissions,
"data": data,
};
}
T convertTo<T>(T Function(Map<String, dynamic>) fromJson) => fromJson(data);
}
+26
View File
@@ -0,0 +1,26 @@
part of '../../models.dart';
/// Rows List
class RowList implements Model {
/// Total number of rows that matched your query.
final int total;
/// List of rows.
final List<Row> rows;
RowList({required this.total, required this.rows});
factory RowList.fromMap(Map<String, dynamic> map) {
return RowList(
total: map['total'],
rows: List<Row>.from(map['rows'].map((p) => Row.fromMap(p))),
);
}
Map<String, dynamic> toMap() {
return {"total": total, "rows": rows.map((p) => p.toMap()).toList()};
}
List<T> convertTo<T>(T Function(Map) fromJson) =>
rows.map((d) => d.convertTo<T>(fromJson)).toList();
}
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Sessions List
class SessionList implements Model {
/// Total number of sessions documents that matched your query.
/// Total number of sessions that matched your query.
final int total;
/// List of sessions.
+1 -1
View File
@@ -2,7 +2,7 @@ part of '../../models.dart';
/// Teams List
class TeamList implements Model {
/// Total number of teams documents that matched your query.
/// Total number of teams that matched your query.
final int total;
/// List of teams.
+1 -1
View File
@@ -26,7 +26,7 @@ class RealtimeBrowser extends RealtimeBase with RealtimeMixin {
}
String? _getFallbackCookie() {
final fallbackCookie = web.window.localStorage['cookieFallback'];
final fallbackCookie = web.window.localStorage.getItem('cookieFallback');
if (fallbackCookie != null) {
final cookie = Map<String, dynamic>.from(jsonDecode(fallbackCookie));
return cookie.values.first;
-3
View File
@@ -22,7 +22,6 @@ mixin RealtimeMixin {
GetFallbackCookie? getFallbackCookie;
int? get closeCode => _websok?.closeCode;
Map<int, RealtimeSubscription> _subscriptions = {};
bool _notifyDone = true;
bool _reconnect = true;
int _retries = 0;
StreamSubscription? _websocketSubscription;
@@ -65,11 +64,9 @@ mixin RealtimeMixin {
_creatingSocket = false;
return;
}
_notifyDone = false;
await _closeConnection();
_lastUrl = uri.toString();
_websok = await getWebSocket(uri);
_notifyDone = true;
}
debugPrint('subscription: $_lastUrl');
_retries = 0;
+3 -3
View File
@@ -1,5 +1,5 @@
name: appwrite
version: 17.1.0
version: 18.0.0
description: Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API
homepage: https://appwrite.io
repository: https://github.com/appwrite/sdk-for-flutter
@@ -19,7 +19,7 @@ dependencies:
flutter:
sdk: flutter
cookie_jar: ^4.0.8
device_info_plus: ^10.1.2
device_info_plus: ^11.5.0
flutter_web_auth_2: ^4.1.0
http: '>=0.13.6 <2.0.0'
package_info_plus: ^8.0.2
@@ -29,7 +29,7 @@ dependencies:
dev_dependencies:
path_provider_platform_interface: ^2.1.2
flutter_lints: ^4.0.0
flutter_lints: ^6.0.0
flutter_test:
sdk: flutter
mockito: ^5.4.4
+118 -33
View File
@@ -1,10 +1,12 @@
import 'dart:convert';
import 'package:appwrite/appwrite.dart';
import 'package:flutter_test/flutter_test.dart';
class BasicFilterQueryTest {
class BasicFilterQueryTest<T> {
final String description;
final dynamic value;
final String expectedValues;
final T value;
final List<T> expectedValues;
BasicFilterQueryTest({
required this.description,
@@ -19,7 +21,7 @@ void main() {
BasicFilterQueryTest(
description: 'with a string',
value: 's',
expectedValues: ["s"],
expectedValues: ['s'],
),
BasicFilterQueryTest(
description: 'with an integer',
@@ -44,14 +46,14 @@ void main() {
BasicFilterQueryTest(
description: 'with a list',
value: ['a', 'b', 'c'],
expectedValues: ["a","b","c"],
expectedValues: ['a', 'b', 'c'],
),
];
group('equal()', () {
for (var t in tests) {
test(t.description, () {
final query = Query.equal('attr', t.value).toJson();
final query = jsonDecode(Query.equal('attr', t.value));
expect(query['attribute'], 'attr');
expect(query['values'], t.expectedValues);
expect(query['method'], 'equal');
@@ -61,19 +63,23 @@ void main() {
group('notEqual()', () {
for (var t in tests) {
test(t.description, () {
final query = Query.notEqual('attr', t.value).toJson();
expect(query['attribute'], 'attr');
expect(query['values'], t.expectedValues);
expect(query['method'], 'notEqual');
});
test(
t.description,
() {
final query = jsonDecode(Query.notEqual('attr', t.value));
expect(query['attribute'], 'attr');
expect(query['values'], t.expectedValues);
expect(query['method'], 'notEqual');
},
skip: t.value is List,
);
}
});
group('lessThan()', () {
for (var t in tests) {
test(t.description, () {
final query = Query.lessThan('attr', t.value).toJson();
final query = jsonDecode(Query.lessThan('attr', t.value));
expect(query['attribute'], 'attr');
expect(query['values'], t.expectedValues);
expect(query['method'], 'lessThan');
@@ -84,7 +90,7 @@ void main() {
group('lessThanEqual()', () {
for (var t in tests) {
test(t.description, () {
final query = Query.lessThanEqual('attr', t.value).toJson();
final query = jsonDecode(Query.lessThanEqual('attr', t.value));
expect(query['attribute'], 'attr');
expect(query['values'], t.expectedValues);
expect(query['method'], 'lessThanEqual');
@@ -95,7 +101,7 @@ void main() {
group('greaterThan()', () {
for (var t in tests) {
test(t.description, () {
final query = Query.greaterThan('attr', t.value).toJson();
final query = jsonDecode(Query.greaterThan('attr', t.value));
expect(query['attribute'], 'attr');
expect(query['values'], t.expectedValues);
expect(query['method'], 'greaterThan');
@@ -106,7 +112,7 @@ void main() {
group('greaterThanEqual()', () {
for (var t in tests) {
test(t.description, () {
final query = Query.greaterThanEqual('attr', t.value).toJson();
final query = jsonDecode(Query.greaterThanEqual('attr', t.value));
expect(query['attribute'], 'attr');
expect(query['values'], t.expectedValues);
expect(query['method'], 'greaterThanEqual');
@@ -116,21 +122,21 @@ void main() {
});
test('returns search', () {
final query = Query.search('attr', 'keyword1 keyword2').toJson();
final query = jsonDecode(Query.search('attr', 'keyword1 keyword2'));
expect(query['attribute'], 'attr');
expect(query['values'], ['keyword1 keyword2']);
expect(query['method'], 'search');
});
test('returns isNull', () {
final query = Query.isNull('attr').toJson();
final query = jsonDecode(Query.isNull('attr'));
expect(query['attribute'], 'attr');
expect(query['values'], null);
expect(query['method'], 'isNull');
});
test('returns isNotNull', () {
final query = Query.isNotNull('attr', 'keyword1 keyword2').toJson();
final query = jsonDecode(Query.isNotNull('attr'));
expect(query['attribute'], 'attr');
expect(query['values'], null);
expect(query['method'], 'isNotNull');
@@ -138,21 +144,21 @@ void main() {
group('between()', () {
test('with integers', () {
final query = Query.between('attr', 1, 2).toJson();
final query = jsonDecode(Query.between('attr', 1, 2));
expect(query['attribute'], 'attr');
expect(query['values'], [1, 2]);
expect(query['method'], 'between');
});
test('with doubles', () {
final query = Query.between('attr', 1.0, 2.0).toJson();
final query = jsonDecode(Query.between('attr', 1.0, 2.0));
expect(query['attribute'], 'attr');
expect(query['values'], [1.0, 2.0]);
expect(query['method'], 'between');
});
test('with strings', () {
final query = Query.between('attr', 'a', 'z').toJson();
final query = jsonDecode(Query.between('attr', 'a', 'z'));
expect(query['attribute'], 'attr');
expect(query['values'], ['a', 'z']);
expect(query['method'], 'between');
@@ -160,52 +166,131 @@ void main() {
});
test('returns select', () {
final query = Query.select(['attr1', 'attr2']).toJson();
final query = jsonDecode(Query.select(['attr1', 'attr2']));
expect(query['attribute'], null);
expect(query['values'], ['attr1', 'attr2']);
expect(query['method'], 'select');
});
test('returns orderAsc', () {
final query = Query.orderAsc('attr').toJson();
final query = jsonDecode(Query.orderAsc('attr'));
expect(query['attribute'], 'attr');
expect(query['values'], null);
expect(query['method'], 'orderAsc');
});
test('returns orderDesc', () {
final query = Query.orderDesc('attr').toJson();
final query = jsonDecode(Query.orderDesc('attr'));
expect(query['attribute'], 'attr');
expect(query['values'], null);
expect(query['method'], 'orderDesc');
});
test('returns cursorBefore', () {
final query = Query.cursorBefore('custom').toJson();
final query = jsonDecode(Query.cursorBefore('custom'));
expect(query['attribute'], null);
expect(query['values'], 'custom');
expect(query['values'], ['custom']);
expect(query['method'], 'cursorBefore');
});
test('returns cursorAfter', () {
final query = Query.cursorAfter('custom').toJson();
final query = jsonDecode(Query.cursorAfter('custom'));
expect(query['attribute'], null);
expect(query['values'], 'custom');
expect(query['values'], ['custom']);
expect(query['method'], 'cursorAfter');
});
test('returns limit', () {
final query = Query.limit(1).toJson();
final query = jsonDecode(Query.limit(1));
expect(query['attribute'], null);
expect(query['values'], 1);
expect(query['values'], [1]);
expect(query['method'], 'limit');
});
test('returns offset', () {
final query = Query.offset(1).toJson();
final query = jsonDecode(Query.offset(1));
expect(query['attribute'], null);
expect(query['values'], 1);
expect(query['values'], [1]);
expect(query['method'], 'offset');
});
test('returns notContains', () {
final query = jsonDecode(Query.notContains('attr', 'value'));
expect(query['attribute'], 'attr');
expect(query['values'], ['value']);
expect(query['method'], 'notContains');
});
test('returns notSearch', () {
final query = jsonDecode(Query.notSearch('attr', 'keyword1 keyword2'));
expect(query['attribute'], 'attr');
expect(query['values'], ['keyword1 keyword2']);
expect(query['method'], 'notSearch');
});
group('notBetween()', () {
test('with integers', () {
final query = jsonDecode(Query.notBetween('attr', 1, 2));
expect(query['attribute'], 'attr');
expect(query['values'], [1, 2]);
expect(query['method'], 'notBetween');
});
test('with doubles', () {
final query = jsonDecode(Query.notBetween('attr', 1.0, 2.0));
expect(query['attribute'], 'attr');
expect(query['values'], [1.0, 2.0]);
expect(query['method'], 'notBetween');
});
test('with strings', () {
final query = jsonDecode(Query.notBetween('attr', 'a', 'z'));
expect(query['attribute'], 'attr');
expect(query['values'], ['a', 'z']);
expect(query['method'], 'notBetween');
});
});
test('returns notStartsWith', () {
final query = jsonDecode(Query.notStartsWith('attr', 'prefix'));
expect(query['attribute'], 'attr');
expect(query['values'], ['prefix']);
expect(query['method'], 'notStartsWith');
});
test('returns notEndsWith', () {
final query = jsonDecode(Query.notEndsWith('attr', 'suffix'));
expect(query['attribute'], 'attr');
expect(query['values'], ['suffix']);
expect(query['method'], 'notEndsWith');
});
test('returns createdBefore', () {
final query = jsonDecode(Query.createdBefore('2023-01-01'));
expect(query['attribute'], null);
expect(query['values'], ['2023-01-01']);
expect(query['method'], 'createdBefore');
});
test('returns createdAfter', () {
final query = jsonDecode(Query.createdAfter('2023-01-01'));
expect(query['attribute'], null);
expect(query['values'], ['2023-01-01']);
expect(query['method'], 'createdAfter');
});
test('returns updatedBefore', () {
final query = jsonDecode(Query.updatedBefore('2023-01-01'));
expect(query['attribute'], null);
expect(query['values'], ['2023-01-01']);
expect(query['method'], 'updatedBefore');
});
test('returns updatedAfter', () {
final query = jsonDecode(Query.updatedAfter('2023-01-01'));
expect(query['attribute'], null);
expect(query['values'], ['2023-01-01']);
expect(query['method'], 'updatedAfter');
});
}
+205 -7
View File
@@ -1,6 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:appwrite/models.dart' as models;
import 'package:appwrite/enums.dart' as enums;
import 'package:appwrite/src/enums.dart';
import 'package:appwrite/src/response.dart';
import 'dart:typed_data';
@@ -23,7 +24,7 @@ class MockClient extends Mock implements Client {
@override
Future webAuth(
Uri? url,
Uri? url,
{
String? callbackUrlScheme,
}
@@ -259,7 +260,25 @@ void main() {
final response = await account.createMfaAuthenticator(
type: 'totp',
type: enums.AuthenticatorType.totp,
);
expect(response, isA<models.MfaType>());
});
test('test method createMFAAuthenticator()', () async {
final Map<String, dynamic> data = {
'secret': '1',
'uri': '1',};
when(client.call(
HttpMethod.post,
)).thenAnswer((_) async => Response(data: data));
final response = await account.createMFAAuthenticator(
type: enums.AuthenticatorType.totp,
);
expect(response, isA<models.MfaType>());
@@ -291,7 +310,40 @@ void main() {
final response = await account.updateMfaAuthenticator(
type: 'totp',
type: enums.AuthenticatorType.totp,
otp: '<OTP>',
);
expect(response, isA<models.User>());
});
test('test method updateMFAAuthenticator()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'John Doe',
'registration': '2020-10-15T06:38:00.000+00:00',
'status': true,
'labels': [],
'passwordUpdate': '2020-10-15T06:38:00.000+00:00',
'email': 'john@appwrite.io',
'phone': '+4930901820',
'emailVerification': true,
'phoneVerification': true,
'mfa': true,
'prefs': <String, dynamic>{},
'targets': [],
'accessedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
HttpMethod.put,
)).thenAnswer((_) async => Response(data: data));
final response = await account.updateMFAAuthenticator(
type: enums.AuthenticatorType.totp,
otp: '<OTP>',
);
expect(response, isA<models.User>());
@@ -307,7 +359,20 @@ void main() {
final response = await account.deleteMfaAuthenticator(
type: 'totp',
type: enums.AuthenticatorType.totp,
);
});
test('test method deleteMFAAuthenticator()', () async {
final data = '';
when(client.call(
HttpMethod.delete,
)).thenAnswer((_) async => Response(data: data));
final response = await account.deleteMFAAuthenticator(
type: enums.AuthenticatorType.totp,
);
});
@@ -325,7 +390,27 @@ void main() {
final response = await account.createMfaChallenge(
factor: 'email',
factor: enums.AuthenticationFactor.email,
);
expect(response, isA<models.MfaChallenge>());
});
test('test method createMFAChallenge()', () async {
final Map<String, dynamic> data = {
'\$id': 'bb8ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'userId': '5e5ea5c168bb8',
'expire': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
HttpMethod.post,
)).thenAnswer((_) async => Response(data: data));
final response = await account.createMFAChallenge(
factor: enums.AuthenticationFactor.email,
);
expect(response, isA<models.MfaChallenge>());
@@ -377,6 +462,52 @@ void main() {
});
test('test method updateMFAChallenge()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'userId': '5e5bb8c16897e',
'expire': '2020-10-15T06:38:00.000+00:00',
'provider': 'email',
'providerUid': 'user@example.com',
'providerAccessToken': 'MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3',
'providerAccessTokenExpiry': '2020-10-15T06:38:00.000+00:00',
'providerRefreshToken': 'MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3',
'ip': '127.0.0.1',
'osCode': 'Mac',
'osName': 'Mac',
'osVersion': 'Mac',
'clientType': 'browser',
'clientCode': 'CM',
'clientName': 'Chrome Mobile iOS',
'clientVersion': '84.0',
'clientEngine': 'WebKit',
'clientEngineVersion': '605.1.15',
'deviceName': 'smartphone',
'deviceBrand': 'Google',
'deviceModel': 'Nexus 5',
'countryCode': 'US',
'countryName': 'United States',
'current': true,
'factors': [],
'secret': '5e5bb8c16897e',
'mfaUpdatedAt': '2020-10-15T06:38:00.000+00:00',};
when(client.call(
HttpMethod.put,
)).thenAnswer((_) async => Response(data: data));
final response = await account.updateMFAChallenge(
challengeId: '<CHALLENGE_ID>',
otp: '<OTP>',
);
expect(response, isA<models.Session>());
});
test('test method listMfaFactors()', () async {
final Map<String, dynamic> data = {
'totp': true,
@@ -396,6 +527,25 @@ void main() {
});
test('test method listMFAFactors()', () async {
final Map<String, dynamic> data = {
'totp': true,
'phone': true,
'email': true,
'recoveryCode': true,};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await account.listMFAFactors(
);
expect(response, isA<models.MfaFactors>());
});
test('test method getMfaRecoveryCodes()', () async {
final Map<String, dynamic> data = {
'recoveryCodes': [],};
@@ -412,6 +562,22 @@ void main() {
});
test('test method getMFARecoveryCodes()', () async {
final Map<String, dynamic> data = {
'recoveryCodes': [],};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await account.getMFARecoveryCodes(
);
expect(response, isA<models.MfaRecoveryCodes>());
});
test('test method createMfaRecoveryCodes()', () async {
final Map<String, dynamic> data = {
'recoveryCodes': [],};
@@ -428,6 +594,22 @@ void main() {
});
test('test method createMFARecoveryCodes()', () async {
final Map<String, dynamic> data = {
'recoveryCodes': [],};
when(client.call(
HttpMethod.post,
)).thenAnswer((_) async => Response(data: data));
final response = await account.createMFARecoveryCodes(
);
expect(response, isA<models.MfaRecoveryCodes>());
});
test('test method updateMfaRecoveryCodes()', () async {
final Map<String, dynamic> data = {
'recoveryCodes': [],};
@@ -444,6 +626,22 @@ void main() {
});
test('test method updateMFARecoveryCodes()', () async {
final Map<String, dynamic> data = {
'recoveryCodes': [],};
when(client.call(
HttpMethod.patch,
)).thenAnswer((_) async => Response(data: data));
final response = await account.updateMFARecoveryCodes(
);
expect(response, isA<models.MfaRecoveryCodes>());
});
test('test method updateName()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
@@ -808,7 +1006,7 @@ void main() {
final response = await account.createOAuth2Session(
provider: 'amazon',
provider: enums.OAuthProvider.amazon,
);
});
@@ -1155,7 +1353,7 @@ void main() {
final response = await account.createOAuth2Token(
provider: 'amazon',
provider: enums.OAuthProvider.amazon,
);
});
+5 -4
View File
@@ -1,6 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:appwrite/models.dart' as models;
import 'package:appwrite/enums.dart' as enums;
import 'package:appwrite/src/enums.dart';
import 'package:appwrite/src/response.dart';
import 'dart:typed_data';
@@ -23,7 +24,7 @@ class MockClient extends Mock implements Client {
@override
Future webAuth(
Uri? url,
Uri? url,
{
String? callbackUrlScheme,
}
@@ -62,7 +63,7 @@ void main() {
final response = await avatars.getBrowser(
code: 'aa',
code: enums.Browser.avantBrowser,
);
expect(response, isA<Uint8List>());
@@ -76,7 +77,7 @@ void main() {
final response = await avatars.getCreditCard(
code: 'amex',
code: enums.CreditCard.americanExpress,
);
expect(response, isA<Uint8List>());
@@ -104,7 +105,7 @@ void main() {
final response = await avatars.getFlag(
code: 'af',
code: enums.Flag.afghanistan,
);
expect(response, isA<Uint8List>());
+2 -1
View File
@@ -1,6 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:appwrite/models.dart' as models;
import 'package:appwrite/enums.dart' as enums;
import 'package:appwrite/src/enums.dart';
import 'package:appwrite/src/response.dart';
import 'dart:typed_data';
@@ -23,7 +24,7 @@ class MockClient extends Mock implements Client {
@override
Future webAuth(
Uri? url,
Uri? url,
{
String? callbackUrlScheme,
}
+4 -1
View File
@@ -1,6 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:appwrite/models.dart' as models;
import 'package:appwrite/enums.dart' as enums;
import 'package:appwrite/src/enums.dart';
import 'package:appwrite/src/response.dart';
import 'dart:typed_data';
@@ -23,7 +24,7 @@ class MockClient extends Mock implements Client {
@override
Future webAuth(
Uri? url,
Uri? url,
{
String? callbackUrlScheme,
}
@@ -79,6 +80,7 @@ void main() {
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'\$permissions': [],
'functionId': '5e5ea6g16897e',
'deploymentId': '5e5ea5c16897e',
'trigger': 'http',
'status': 'processing',
'requestMethod': 'GET',
@@ -111,6 +113,7 @@ void main() {
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'\$permissions': [],
'functionId': '5e5ea6g16897e',
'deploymentId': '5e5ea5c16897e',
'trigger': 'http',
'status': 'processing',
'requestMethod': 'GET',
+2 -1
View File
@@ -1,6 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:appwrite/models.dart' as models;
import 'package:appwrite/enums.dart' as enums;
import 'package:appwrite/src/enums.dart';
import 'package:appwrite/src/response.dart';
import 'dart:typed_data';
@@ -23,7 +24,7 @@ class MockClient extends Mock implements Client {
@override
Future webAuth(
Uri? url,
Uri? url,
{
String? callbackUrlScheme,
}
+2 -1
View File
@@ -1,6 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:appwrite/models.dart' as models;
import 'package:appwrite/enums.dart' as enums;
import 'package:appwrite/src/enums.dart';
import 'package:appwrite/src/response.dart';
import 'dart:typed_data';
@@ -23,7 +24,7 @@ class MockClient extends Mock implements Client {
@override
Future webAuth(
Uri? url,
Uri? url,
{
String? callbackUrlScheme,
}
+12 -2
View File
@@ -1,6 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:appwrite/models.dart' as models;
import 'package:appwrite/enums.dart' as enums;
import 'package:appwrite/src/enums.dart';
import 'package:appwrite/src/response.dart';
import 'dart:typed_data';
@@ -23,7 +24,7 @@ class MockClient extends Mock implements Client {
@override
Future webAuth(
Uri? url,
Uri? url,
{
String? callbackUrlScheme,
}
@@ -60,7 +61,16 @@ void main() {
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'targetId': '259125845563242502',
'target': <String, dynamic>{},
'target': <String, dynamic>{
'\$id': '259125845563242502',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'name': 'Apple iPhone 12',
'userId': '259125845563242502',
'providerType': 'email',
'identifier': 'token',
'expired': true,
},
'userId': '5e5ea5c16897e',
'userName': 'Aegon Targaryen',
'topicId': '259125845563242502',
+2 -1
View File
@@ -1,6 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:appwrite/models.dart' as models;
import 'package:appwrite/enums.dart' as enums;
import 'package:appwrite/src/enums.dart';
import 'package:appwrite/src/response.dart';
import 'dart:typed_data';
@@ -23,7 +24,7 @@ class MockClient extends Mock implements Client {
@override
Future webAuth(
Uri? url,
Uri? url,
{
String? callbackUrlScheme,
}
+246
View File
@@ -0,0 +1,246 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:appwrite/models.dart' as models;
import 'package:appwrite/enums.dart' as enums;
import 'package:appwrite/src/enums.dart';
import 'package:appwrite/src/response.dart';
import 'dart:typed_data';
import 'package:appwrite/appwrite.dart';
class MockClient extends Mock implements Client {
Map<String, String> config = {'project': 'testproject'};
String endPoint = 'https://localhost/v1';
@override
Future<Response> call(
HttpMethod? method, {
String path = '',
Map<String, String> headers = const {},
Map<String, dynamic> params = const {},
ResponseType? responseType,
}) async {
return super.noSuchMethod(Invocation.method(#call, [method]),
returnValue: Response());
}
@override
Future webAuth(
Uri? url,
{
String? callbackUrlScheme,
}
) async {
return super.noSuchMethod(Invocation.method(#webAuth, [url]), returnValue: 'done');
}
@override
Future<Response> chunkedUpload({
String? path,
Map<String, dynamic>? params,
String? paramName,
String? idParamName,
Map<String, String>? headers,
Function(UploadProgress)? onProgress,
}) async {
return super.noSuchMethod(Invocation.method(#chunkedUpload, [path, params, paramName, idParamName, headers]), returnValue: Response(data: {}));
}
}
void main() {
group('TablesDB test', () {
late MockClient client;
late TablesDB tablesDB;
setUp(() {
client = MockClient();
tablesDB = TablesDB(client);
});
test('test method listRows()', () async {
final Map<String, dynamic> data = {
'total': 5,
'rows': [],};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await tablesDB.listRows(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
);
expect(response, isA<models.RowList>());
});
test('test method createRow()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'\$permissions': [],};
when(client.call(
HttpMethod.post,
)).thenAnswer((_) async => Response(data: data));
final response = await tablesDB.createRow(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
data: {},
);
expect(response, isA<models.Row>());
});
test('test method getRow()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'\$permissions': [],};
when(client.call(
HttpMethod.get,
)).thenAnswer((_) async => Response(data: data));
final response = await tablesDB.getRow(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
);
expect(response, isA<models.Row>());
});
test('test method upsertRow()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'\$permissions': [],};
when(client.call(
HttpMethod.put,
)).thenAnswer((_) async => Response(data: data));
final response = await tablesDB.upsertRow(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
);
expect(response, isA<models.Row>());
});
test('test method updateRow()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'\$permissions': [],};
when(client.call(
HttpMethod.patch,
)).thenAnswer((_) async => Response(data: data));
final response = await tablesDB.updateRow(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
);
expect(response, isA<models.Row>());
});
test('test method deleteRow()', () async {
final data = '';
when(client.call(
HttpMethod.delete,
)).thenAnswer((_) async => Response(data: data));
final response = await tablesDB.deleteRow(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
);
});
test('test method decrementRowColumn()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'\$permissions': [],};
when(client.call(
HttpMethod.patch,
)).thenAnswer((_) async => Response(data: data));
final response = await tablesDB.decrementRowColumn(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
column: '',
);
expect(response, isA<models.Row>());
});
test('test method incrementRowColumn()', () async {
final Map<String, dynamic> data = {
'\$id': '5e5ea5c16897e',
'\$sequence': 1,
'\$tableId': '5e5ea5c15117e',
'\$databaseId': '5e5ea5c15117e',
'\$createdAt': '2020-10-15T06:38:00.000+00:00',
'\$updatedAt': '2020-10-15T06:38:00.000+00:00',
'\$permissions': [],};
when(client.call(
HttpMethod.patch,
)).thenAnswer((_) async => Response(data: data));
final response = await tablesDB.incrementRowColumn(
databaseId: '<DATABASE_ID>',
tableId: '<TABLE_ID>',
rowId: '<ROW_ID>',
column: '',
);
expect(response, isA<models.Row>());
});
});
}
+2 -1
View File
@@ -1,6 +1,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:appwrite/models.dart' as models;
import 'package:appwrite/enums.dart' as enums;
import 'package:appwrite/src/enums.dart';
import 'package:appwrite/src/response.dart';
import 'dart:typed_data';
@@ -23,7 +24,7 @@ class MockClient extends Mock implements Client {
@override
Future webAuth(
Uri? url,
Uri? url,
{
String? callbackUrlScheme,
}
+5 -5
View File
@@ -40,11 +40,11 @@ void main() {
Cookie('name2', 'value2'),
];
cookieJar.saveFromResponse(uri, cookies);
final request = Request('GET', uri);
await cookieManager.onRequest(request);
expect(request.headers, {
'cookie': 'name=value; name2=value2'
'cookie': 'name=value; name2=value2',
});
});
});
@@ -82,11 +82,11 @@ void main() {
'body',
200,
headers: {
'set-cookie': 'name=value'
'set-cookie': 'name=value',
},
request: request,
);
await cookieManager.onResponse(response);
final cookies = await cookieJar.loadForRequest(uri);
@@ -96,4 +96,4 @@ void main() {
expect(cookies.first.value, 'value');
});
});
}
}
+10 -4
View File
@@ -4,9 +4,15 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('name()', () {
for (final method in HttpMethod.values) {
test('returns ${method.toString().split('.').last.toUpperCase()} for $method', () {
expect(method.name(), method.toString().split('.').last.toUpperCase());
});
test(
'returns ${method.toString().split('.').last.toUpperCase()} for $method',
() {
expect(
method.name(),
method.toString().split('.').last.toUpperCase(),
);
},
);
}
});
}
}
+15 -3
View File
@@ -8,10 +8,22 @@ void main() {
expect(exception1.toString(), equals('AppwriteException'));
final exception2 = AppwriteException('Some error message');
expect(exception2.toString(), equals('AppwriteException: , Some error message (0)'));
expect(
exception2.toString(),
equals('AppwriteException: , Some error message (0)'),
);
final exception3 = AppwriteException('Invalid request', 400, 'ValidationError');
expect(exception3.toString(), equals('AppwriteException: ValidationError, Invalid request (400)'));
final exception3 = AppwriteException(
'Invalid request',
400,
'ValidationError',
);
expect(
exception3.toString(),
equals(
'AppwriteException: ValidationError, Invalid request (400)',
),
);
});
});
}
+4 -1
View File
@@ -36,7 +36,10 @@ void main() {
});
test('creates InputFile from bytes', () {
final inputFile = InputFile.fromBytes(bytes: [1, 2, 3], filename: 'file.txt');
final inputFile = InputFile.fromBytes(
bytes: [1, 2, 3],
filename: 'file.txt',
);
expect(inputFile.path, isNull);
expect(inputFile.filename, 'file.txt');
+5 -6
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('AlgoArgon2', () {
test('model', () {
final model = AlgoArgon2(
type: 'argon2',
@@ -15,10 +14,10 @@ void main() {
final map = model.toMap();
final result = AlgoArgon2.fromMap(map);
expect(result.type, 'argon2');
expect(result.memoryCost, 65536);
expect(result.timeCost, 4);
expect(result.threads, 3);
});
expect(result.type, 'argon2');
expect(result.memoryCost, 65536);
expect(result.timeCost, 4);
expect(result.threads, 3);
});
});
}
+2 -3
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('AlgoBcrypt', () {
test('model', () {
final model = AlgoBcrypt(
type: 'bcrypt',
@@ -12,7 +11,7 @@ void main() {
final map = model.toMap();
final result = AlgoBcrypt.fromMap(map);
expect(result.type, 'bcrypt');
});
expect(result.type, 'bcrypt');
});
});
}
+2 -3
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('AlgoMd5', () {
test('model', () {
final model = AlgoMd5(
type: 'md5',
@@ -12,7 +11,7 @@ void main() {
final map = model.toMap();
final result = AlgoMd5.fromMap(map);
expect(result.type, 'md5');
});
expect(result.type, 'md5');
});
});
}
+2 -3
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('AlgoPhpass', () {
test('model', () {
final model = AlgoPhpass(
type: 'phpass',
@@ -12,7 +11,7 @@ void main() {
final map = model.toMap();
final result = AlgoPhpass.fromMap(map);
expect(result.type, 'phpass');
});
expect(result.type, 'phpass');
});
});
}
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('AlgoScryptModified', () {
test('model', () {
final model = AlgoScryptModified(
type: 'scryptMod',
@@ -15,10 +14,10 @@ void main() {
final map = model.toMap();
final result = AlgoScryptModified.fromMap(map);
expect(result.type, 'scryptMod');
expect(result.salt, 'UxLMreBr6tYyjQ==');
expect(result.saltSeparator, 'Bw==');
expect(result.signerKey, 'XyEKE9RcTDeLEsL/RjwPDBv/RqDl8fb3gpYEOQaPihbxf1ZAtSOHCjuAAa7Q3oHpCYhXSN9tizHgVOwn6krflQ==');
});
expect(result.type, 'scryptMod');
expect(result.salt, 'UxLMreBr6tYyjQ==');
expect(result.saltSeparator, 'Bw==');
expect(result.signerKey, 'XyEKE9RcTDeLEsL/RjwPDBv/RqDl8fb3gpYEOQaPihbxf1ZAtSOHCjuAAa7Q3oHpCYhXSN9tizHgVOwn6krflQ==');
});
});
}
+6 -7
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('AlgoScrypt', () {
test('model', () {
final model = AlgoScrypt(
type: 'scrypt',
@@ -16,11 +15,11 @@ void main() {
final map = model.toMap();
final result = AlgoScrypt.fromMap(map);
expect(result.type, 'scrypt');
expect(result.costCpu, 8);
expect(result.costMemory, 14);
expect(result.costParallel, 1);
expect(result.length, 64);
});
expect(result.type, 'scrypt');
expect(result.costCpu, 8);
expect(result.costMemory, 14);
expect(result.costParallel, 1);
expect(result.length, 64);
});
});
}
+2 -3
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('AlgoSha', () {
test('model', () {
final model = AlgoSha(
type: 'sha',
@@ -12,7 +11,7 @@ void main() {
final map = model.toMap();
final result = AlgoSha.fromMap(map);
expect(result.type, 'sha');
});
expect(result.type, 'sha');
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('ContinentList', () {
test('model', () {
final model = ContinentList(
total: 5,
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = ContinentList.fromMap(map);
expect(result.total, 5);
expect(result.continents, []);
});
expect(result.total, 5);
expect(result.continents, []);
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('Continent', () {
test('model', () {
final model = Continent(
name: 'Europe',
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = Continent.fromMap(map);
expect(result.name, 'Europe');
expect(result.code, 'EU');
});
expect(result.name, 'Europe');
expect(result.code, 'EU');
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('CountryList', () {
test('model', () {
final model = CountryList(
total: 5,
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = CountryList.fromMap(map);
expect(result.total, 5);
expect(result.countries, []);
});
expect(result.total, 5);
expect(result.countries, []);
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('Country', () {
test('model', () {
final model = Country(
name: 'United States',
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = Country.fromMap(map);
expect(result.name, 'United States');
expect(result.code, 'US');
});
expect(result.name, 'United States');
expect(result.code, 'US');
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('CurrencyList', () {
test('model', () {
final model = CurrencyList(
total: 5,
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = CurrencyList.fromMap(map);
expect(result.total, 5);
expect(result.currencies, []);
});
expect(result.total, 5);
expect(result.currencies, []);
});
});
}
+8 -9
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('Currency', () {
test('model', () {
final model = Currency(
symbol: '\$',
@@ -18,13 +17,13 @@ void main() {
final map = model.toMap();
final result = Currency.fromMap(map);
expect(result.symbol, '\$');
expect(result.name, 'US dollar');
expect(result.symbolNative, '\$');
expect(result.decimalDigits, 2);
expect(result.rounding, 0);
expect(result.code, 'USD');
expect(result.namePlural, 'US dollars');
});
expect(result.symbol, '\$');
expect(result.name, 'US dollar');
expect(result.symbolNative, '\$');
expect(result.decimalDigits, 2);
expect(result.rounding, 0);
expect(result.code, 'USD');
expect(result.namePlural, 'US dollars');
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('DocumentList', () {
test('model', () {
final model = DocumentList(
total: 5,
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = DocumentList.fromMap(map);
expect(result.total, 5);
expect(result.documents, []);
});
expect(result.total, 5);
expect(result.documents, []);
});
});
}
+8 -9
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('Document', () {
test('model', () {
final model = Document(
$id: '5e5ea5c16897e',
@@ -19,13 +18,13 @@ void main() {
final map = model.toMap();
final result = Document.fromMap(map);
expect(result.$id, '5e5ea5c16897e');
expect(result.$sequence, 1);
expect(result.$collectionId, '5e5ea5c15117e');
expect(result.$databaseId, '5e5ea5c15117e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$permissions, []);
});
expect(result.$id, '5e5ea5c16897e');
expect(result.$sequence, 1);
expect(result.$collectionId, '5e5ea5c15117e');
expect(result.$databaseId, '5e5ea5c15117e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$permissions, []);
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('ExecutionList', () {
test('model', () {
final model = ExecutionList(
total: 5,
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = ExecutionList.fromMap(map);
expect(result.total, 5);
expect(result.executions, []);
});
expect(result.total, 5);
expect(result.executions, []);
});
});
}
+19 -18
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('Execution', () {
test('model', () {
final model = Execution(
$id: '5e5ea5c16897e',
@@ -11,6 +10,7 @@ void main() {
$updatedAt: '2020-10-15T06:38:00.000+00:00',
$permissions: [],
functionId: '5e5ea6g16897e',
deploymentId: '5e5ea5c16897e',
trigger: 'http',
status: 'processing',
requestMethod: 'GET',
@@ -27,22 +27,23 @@ void main() {
final map = model.toMap();
final result = Execution.fromMap(map);
expect(result.$id, '5e5ea5c16897e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$permissions, []);
expect(result.functionId, '5e5ea6g16897e');
expect(result.trigger, 'http');
expect(result.status, 'processing');
expect(result.requestMethod, 'GET');
expect(result.requestPath, '/articles?id=5');
expect(result.requestHeaders, []);
expect(result.responseStatusCode, 200);
expect(result.responseBody, '');
expect(result.responseHeaders, []);
expect(result.logs, '');
expect(result.errors, '');
expect(result.duration, 0.4);
});
expect(result.$id, '5e5ea5c16897e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$permissions, []);
expect(result.functionId, '5e5ea6g16897e');
expect(result.deploymentId, '5e5ea5c16897e');
expect(result.trigger, 'http');
expect(result.status, 'processing');
expect(result.requestMethod, 'GET');
expect(result.requestPath, '/articles?id=5');
expect(result.requestHeaders, []);
expect(result.responseStatusCode, 200);
expect(result.responseBody, '');
expect(result.responseHeaders, []);
expect(result.logs, '');
expect(result.errors, '');
expect(result.duration, 0.4);
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('FileList', () {
test('model', () {
final model = FileList(
total: 5,
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = FileList.fromMap(map);
expect(result.total, 5);
expect(result.files, []);
});
expect(result.total, 5);
expect(result.files, []);
});
});
}
+12 -13
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('File', () {
test('model', () {
final model = File(
$id: '5e5ea5c16897e',
@@ -22,17 +21,17 @@ void main() {
final map = model.toMap();
final result = File.fromMap(map);
expect(result.$id, '5e5ea5c16897e');
expect(result.bucketId, '5e5ea5c16897e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$permissions, []);
expect(result.name, 'Pink.png');
expect(result.signature, '5d529fd02b544198ae075bd57c1762bb');
expect(result.mimeType, 'image/png');
expect(result.sizeOriginal, 17890);
expect(result.chunksTotal, 17890);
expect(result.chunksUploaded, 17890);
});
expect(result.$id, '5e5ea5c16897e');
expect(result.bucketId, '5e5ea5c16897e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$permissions, []);
expect(result.name, 'Pink.png');
expect(result.signature, '5d529fd02b544198ae075bd57c1762bb');
expect(result.mimeType, 'image/png');
expect(result.sizeOriginal, 17890);
expect(result.chunksTotal, 17890);
expect(result.chunksUploaded, 17890);
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('Headers', () {
test('model', () {
final model = Headers(
name: 'Content-Type',
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = Headers.fromMap(map);
expect(result.name, 'Content-Type');
expect(result.value, 'application/json');
});
expect(result.name, 'Content-Type');
expect(result.value, 'application/json');
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('IdentityList', () {
test('model', () {
final model = IdentityList(
total: 5,
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = IdentityList.fromMap(map);
expect(result.total, 5);
expect(result.identities, []);
});
expect(result.total, 5);
expect(result.identities, []);
});
});
}
+11 -12
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('Identity', () {
test('model', () {
final model = Identity(
$id: '5e5ea5c16897e',
@@ -21,16 +20,16 @@ void main() {
final map = model.toMap();
final result = Identity.fromMap(map);
expect(result.$id, '5e5ea5c16897e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.userId, '5e5bb8c16897e');
expect(result.provider, 'email');
expect(result.providerUid, '5e5bb8c16897e');
expect(result.providerEmail, 'user@example.com');
expect(result.providerAccessToken, 'MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3');
expect(result.providerAccessTokenExpiry, '2020-10-15T06:38:00.000+00:00');
expect(result.providerRefreshToken, 'MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3');
});
expect(result.$id, '5e5ea5c16897e');
expect(result.$createdAt, '2020-10-15T06:38:00.000+00:00');
expect(result.$updatedAt, '2020-10-15T06:38:00.000+00:00');
expect(result.userId, '5e5bb8c16897e');
expect(result.provider, 'email');
expect(result.providerUid, '5e5bb8c16897e');
expect(result.providerEmail, 'user@example.com');
expect(result.providerAccessToken, 'MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3');
expect(result.providerAccessTokenExpiry, '2020-10-15T06:38:00.000+00:00');
expect(result.providerRefreshToken, 'MTQ0NjJkZmQ5OTM2NDE1ZTZjNGZmZjI3');
});
});
}
+2 -3
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('Jwt', () {
test('model', () {
final model = Jwt(
jwt: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
@@ -12,7 +11,7 @@ void main() {
final map = model.toMap();
final result = Jwt.fromMap(map);
expect(result.jwt, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c');
});
expect(result.jwt, 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c');
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('LanguageList', () {
test('model', () {
final model = LanguageList(
total: 5,
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = LanguageList.fromMap(map);
expect(result.total, 5);
expect(result.languages, []);
});
expect(result.total, 5);
expect(result.languages, []);
});
});
}
+4 -5
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('Language', () {
test('model', () {
final model = Language(
name: 'Italian',
@@ -14,9 +13,9 @@ void main() {
final map = model.toMap();
final result = Language.fromMap(map);
expect(result.name, 'Italian');
expect(result.code, 'it');
expect(result.nativeName, 'Italiano');
});
expect(result.name, 'Italian');
expect(result.code, 'it');
expect(result.nativeName, 'Italiano');
});
});
}
+3 -4
View File
@@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
group('LocaleCodeList', () {
test('model', () {
final model = LocaleCodeList(
total: 5,
@@ -13,8 +12,8 @@ void main() {
final map = model.toMap();
final result = LocaleCodeList.fromMap(map);
expect(result.total, 5);
expect(result.localeCodes, []);
});
expect(result.total, 5);
expect(result.localeCodes, []);
});
});
}

Some files were not shown because too many files have changed in this diff Show More