-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore(amplify_storage_s3): add storage integration tests and update example app #734
Changes from all commits
29cd7f4
8699cab
5456cd4
ac4665d
fe5a3a5
6a5fc55
a499dc7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,54 @@ | ||
# amplify_storage_s3_example | ||
|
||
Example app for the Amplify Flutter Storage plugin with AWS S3 provider. | ||
|
||
## How to Configure Amplify Backend | ||
|
||
This app (as well as integration tests) depend on an Amplify backend with the storage category | ||
configured for guest access. | ||
|
||
First, initialize the Amplify backend with: | ||
|
||
``` | ||
$ cd packages/amplify_storage_s3/example | ||
$ amplify init | ||
``` | ||
|
||
After completing the prompts, add storage category. | ||
|
||
``` | ||
$ amplify add storage | ||
? Please select from one of the below mentioned services: Content (Images, audio, video, etc.) | ||
? You need to add auth (Amazon Cognito) to your project in order to add storage for user files. Do you want to add auth now? | ||
Yes | ||
Using service: Cognito, provided by: awscloudformation | ||
|
||
The current configured provider is Amazon Cognito. | ||
|
||
Do you want to use the default authentication and security configuration? Default configuration | ||
Warning: you will not be able to edit these selections. | ||
How do you want users to be able to sign in? | ||
Username | ||
Do you want to configure advanced settings? | ||
No, I am done. | ||
Successfully added auth resource MYRESOURCENAME locally | ||
|
||
Some next steps: | ||
"amplify push" will build all your local backend resources and provision it in the cloud | ||
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud | ||
|
||
? Please provide a friendly name for your resource that will be used to label this category in the project: | ||
myGreatProjectNameStorage | ||
? Please provide bucket name: | ||
exampleBucketNameUnique12345 | ||
? Who should have access: | ||
Auth and guest users | ||
? What kind of access do you want for Authenticated users? | ||
create/update, read, delete | ||
? What kind of access do you want for Guest users? | ||
create/update, read, delete | ||
? Do you want to add a Lambda Trigger for your S3 Bucket? | ||
No | ||
``` | ||
|
||
Finally, run `$ amplify push` to provision the storage resource in the cloud. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ buildscript { | |
} | ||
|
||
dependencies { | ||
classpath 'com.android.tools.build:gradle:3.5.0' | ||
classpath 'com.android.tools.build:gradle:3.5.4' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it ok to just make this change here, or should we try to have the same version in all these files? IMO, ok to have this patch here as it's an example app, after all. This is needed here because of something related to new version of file_picker which has sound nulls safety https://github.com/miguelpruivo/flutter_file_picker/wiki/Troubleshooting#-issue. |
||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/* | ||
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
import 'dart:io'; | ||
import 'package:path_provider/path_provider.dart'; | ||
import 'package:integration_test/integration_test.dart'; | ||
import 'package:flutter_test/flutter_test.dart'; | ||
|
||
import 'package:amplify_flutter/amplify.dart'; | ||
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; | ||
import 'package:amplify_storage_s3/amplify_storage_s3.dart'; | ||
import 'package:amplify_storage_s3_example/amplifyconfiguration.dart'; | ||
|
||
const exampleFileName = 'example_file.txt'; | ||
|
||
void main() async { | ||
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); | ||
|
||
group('amplify_storage_s3', () { | ||
// options used for all tests | ||
S3ListOptions listOptions = | ||
S3ListOptions(accessLevel: StorageAccessLevel.guest); | ||
late String? lastUploadedKey; | ||
|
||
// Returns a text file to use for testing, writing if it does not exist. | ||
Future<File> getTemporaryFile() async { | ||
final path = '${(await getTemporaryDirectory()).path}/$exampleFileName'; | ||
final file = File(path); | ||
if (!(await file.exists())) { | ||
await file.writeAsString('Upload me to s3 to see if I work.'); | ||
} | ||
return file; | ||
} | ||
|
||
Future<int> getCountFromListFiles() async { | ||
final result = await Amplify.Storage.list(options: listOptions); | ||
return result.items.length; | ||
} | ||
|
||
Future<void> deleteAllGuestFiles() async { | ||
final result = await Amplify.Storage.list(options: listOptions); | ||
for (StorageItem item in result.items) { | ||
await Amplify.Storage.remove(key: item.key); | ||
} | ||
} | ||
|
||
setUpAll(() async { | ||
Amplify.addPlugins([AmplifyAuthCognito(), AmplifyStorageS3()]); | ||
await Amplify.configure(amplifyconfig); | ||
|
||
await deleteAllGuestFiles(); | ||
}); | ||
|
||
tearDownAll(() async { | ||
await deleteAllGuestFiles(); | ||
}); | ||
|
||
testWidgets('should upload a file', (WidgetTester tester) async { | ||
final file = await getTemporaryFile(); | ||
final initialCount = await getCountFromListFiles(); | ||
|
||
final key = '$exampleFileName${new DateTime.now().toString()}'; | ||
Map<String, String> metadata = <String, String>{}; | ||
metadata['name'] = exampleFileName; | ||
metadata['desc'] = 'A test file'; | ||
S3UploadFileOptions options = S3UploadFileOptions( | ||
accessLevel: StorageAccessLevel.guest, metadata: metadata); | ||
final result = await Amplify.Storage.uploadFile( | ||
key: key, local: file, options: options); | ||
lastUploadedKey = result.key; | ||
expect(lastUploadedKey, key); | ||
|
||
final finalCount = await getCountFromListFiles(); | ||
expect(initialCount + 1, finalCount); | ||
}); | ||
|
||
testWidgets('should list files and get expected attributes', | ||
(WidgetTester tester) async { | ||
if (lastUploadedKey == null) { | ||
fail('No uploaded file to verify.'); | ||
} | ||
final result = await Amplify.Storage.list(options: listOptions); | ||
expect(result.items.length, greaterThan(0)); | ||
final uploadedStorageItem = | ||
result.items.firstWhere((element) => element.key == lastUploadedKey); | ||
expect(uploadedStorageItem.lastModified?.day, | ||
new DateTime.now().day); // was uploaded today | ||
expect(uploadedStorageItem.eTag?.isNotEmpty, true); | ||
expect(uploadedStorageItem.size, greaterThan(0)); | ||
ragingsquirrel3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
|
||
testWidgets('should get the URL of an uploaded file', | ||
(WidgetTester tester) async { | ||
if (lastUploadedKey == null) { | ||
fail('No uploaded file to verify.'); | ||
} | ||
final result = await Amplify.Storage.getUrl(key: lastUploadedKey!); | ||
// assert valid and expected s3 URL | ||
expect(Uri.parse(result.url).isAbsolute, true); | ||
expect(result.url.contains('s3'), true); | ||
}); | ||
|
||
testWidgets('should delete uploaded files', (WidgetTester tester) async { | ||
final initialCount = await getCountFromListFiles(); | ||
expect(initialCount, greaterThan(0)); | ||
await deleteAllGuestFiles(); | ||
final finalCount = await getCountFromListFiles(); | ||
expect(finalCount, 0); | ||
}); | ||
}); | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"). | ||
* You may not use this file except in compliance with the License. | ||
* A copy of the License is located at | ||
* | ||
* http://aws.amazon.com/apache2.0 | ||
* | ||
* or in the "license" file accompanying this file. This file is distributed | ||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either | ||
* express or implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
import 'package:integration_test/integration_test_driver.dart'; | ||
|
||
Future<void> main() => integrationDriver(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
view this on https://github.com/ragingsquirrel3/amplify-flutter/blob/chore-storage-integ-tests/packages/amplify_storage_s3/example/README.md to make it slightly easier to read.