aws-sdk 2.0.1 → 2.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +20 -0
- package/.gitignore +10 -0
- package/.travis.yml +20 -0
- package/.yardopts +20 -0
- package/.yardopts_guide +21 -0
- package/Gemfile +16 -0
- package/Gemfile.lock +34 -0
- package/README.md +5 -6
- package/Rakefile +14 -0
- package/UPGRADING.md +9 -4
- package/configuration.sample +5 -0
- package/dist/BUNDLE_LICENSE.txt +96 -0
- package/dist/aws-sdk.js +9594 -0
- package/dist/aws-sdk.min.js +21 -0
- package/dist-tools/.eslintrc +10 -0
- package/dist-tools/browser-builder.js +142 -0
- package/dist-tools/strategies/cache.js +68 -0
- package/dist-tools/strategies/default.js +165 -0
- package/dist-tools/test/browser-builder.mocha.spec.coffee +182 -0
- package/dist-tools/test/helpers.coffee +16 -0
- package/doc-src/guide/browser-building.md +93 -0
- package/doc-src/guide/browser-configuring-wif.md +287 -0
- package/doc-src/guide/browser-configuring.md +218 -0
- package/doc-src/guide/browser-examples.md +220 -0
- package/doc-src/guide/browser-intro.md +46 -0
- package/doc-src/guide/browser-making-requests.md +279 -0
- package/doc-src/guide/browser-services.md +75 -0
- package/doc-src/guide/index.md +41 -0
- package/doc-src/guide/node-configuring.md +272 -0
- package/doc-src/guide/node-examples.md +341 -0
- package/doc-src/guide/node-intro.md +32 -0
- package/doc-src/guide/node-making-requests.md +309 -0
- package/doc-src/guide/node-services.md +159 -0
- package/doc-src/templates/api-versions/model_documentor.rb +366 -0
- package/doc-src/templates/api-versions/plugin.rb +230 -0
- package/doc-src/templates/api-versions/templates/default/class/html/setup.rb +9 -0
- package/doc-src/templates/api-versions/templates/default/class/html/waiter_details_list.erb +7 -0
- package/doc-src/templates/api-versions/templates/default/class/html/waiter_summary.erb +7 -0
- package/doc-src/templates/api-versions/templates/default/docstring/html/experimental.erb +4 -0
- package/doc-src/templates/api-versions/templates/default/docstring/setup.rb +9 -0
- package/doc-src/templates/api-versions/templates/default/fulldoc/html/css/common.css +6 -0
- package/doc-src/templates/api-versions/templates/default/fulldoc/html/setup.rb +62 -0
- package/doc-src/templates/api-versions/templates/default/layout/html/services.erb +10 -0
- package/doc-src/templates/api-versions/templates/default/layout/html/setup.rb +28 -0
- package/doc-src/templates/api-versions/templates/default/module/html/box_info.erb +45 -0
- package/doc-src/templates/api-versions/templates/default/module/html/children.erb +8 -0
- package/doc-src/templates/api-versions/templates/default/tags/setup.rb +3 -0
- package/doc-src/templates/api-versions/templates/default/waiter_details/html/method_signature.erb +3 -0
- package/doc-src/templates/api-versions/templates/default/waiter_details/html/setup.rb +5 -0
- package/doc-src/templates/default/layout/html/footer.erb +31 -0
- package/doc-src/templates/default/layout/html/layout.erb +23 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/css/highlight.github.css +127 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/css/style.css +1192 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/img/logo.png +0 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/app.js +33 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/highlight.pack.js +27 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/AUTHORS +55 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/LICENSE +25 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/doctools.js +247 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/file.png +0 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/searchtools.js +568 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/underscore.js +23 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/search.erb +29 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/search_index.erb +1 -0
- package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/setup.rb +75 -0
- package/doc-src/templates/flasky_sphinx_guide/layout/html/layout.erb +93 -0
- package/doc-src/templates/flasky_sphinx_guide/layout/html/setup.rb +9 -0
- package/doc-src/templates/flasky_sphinx_guide/layout/html/sidebar.erb +45 -0
- package/doc-src/templates/flasky_sphinx_guide/onefile/html/layout.erb +51 -0
- package/doc-src/templates/flasky_sphinx_guide/onefile/html/setup.rb +1 -0
- package/eslint-rules/no-require-in-service.js +10 -0
- package/features/autoscaling/autoscaling.feature +21 -0
- package/features/autoscaling/step_definitions/autoscaling.js +49 -0
- package/features/cloudformation/cloudformation.feature +22 -0
- package/features/cloudformation/step_definitions/cloudformation.js +26 -0
- package/features/cloudfront/cloudfront.feature +28 -0
- package/features/cloudfront/step_definitions/cloudfront-latest.js +54 -0
- package/features/cloudfront/step_definitions/cloudfront.js +21 -0
- package/features/cloudsearch/cloudsearch.feature +34 -0
- package/features/cloudsearch/step_definitions/cloudsearch.js +42 -0
- package/features/cloudtrail/cloudtrail.feature +17 -0
- package/features/cloudtrail/step_definitions/cloudtrail.js +14 -0
- package/features/cloudwatch/cloudwatch.feature +15 -0
- package/features/cloudwatch/step_definitions/cloudwatch.js +48 -0
- package/features/datapipeline/datapipeline.feature +23 -0
- package/features/datapipeline/step_definitions/datapipeline.js +79 -0
- package/features/directconnect/directconnect.feature +20 -0
- package/features/directconnect/step_definitions/directconnect.js +44 -0
- package/features/dynamodb/crc32.feature +18 -0
- package/features/dynamodb/step_definitions/dynamodb.js +154 -0
- package/features/dynamodb/tables.feature +50 -0
- package/features/ec2/ec2.feature +28 -0
- package/features/ec2/step_definitions/ec2.js +65 -0
- package/features/elasticache/elasticache.feature +20 -0
- package/features/elasticache/step_definitions/elasticache.js +34 -0
- package/features/elasticbeanstalk/elasticbeanstalk.feature +22 -0
- package/features/elasticbeanstalk/step_definitions/elasticbeanstalk.js +38 -0
- package/features/elastictranscoder/elastictranscoder.feature +24 -0
- package/features/elastictranscoder/step_definitions/elastictranscoder.js +56 -0
- package/features/elb/elb.feature +19 -0
- package/features/elb/step_definitions/elb.js +37 -0
- package/features/emr/emr.feature +16 -0
- package/features/emr/step_definitions/emr.js +45 -0
- package/features/extra/assertions.js +29 -0
- package/features/extra/dummy.feature +0 -0
- package/features/extra/fixtures/testfile.txt +1 -0
- package/features/extra/helpers.js +113 -0
- package/features/extra/hooks.js +107 -0
- package/features/extra/world.js +12 -0
- package/features/glacier/glacier.feature +47 -0
- package/features/glacier/step_definitions/glacier.js +112 -0
- package/features/iam/iam.feature +24 -0
- package/features/iam/step_definitions/iam.js +66 -0
- package/features/importexport/importexport.feature +53 -0
- package/features/importexport/step_definitions/importexport.js +42 -0
- package/features/kinesis/kinesis.feature +9 -0
- package/features/kinesis/step_definitions/kinesis.js +10 -0
- package/features/opsworks/opsworks.feature +26 -0
- package/features/opsworks/step_definitions/opsworks.js +42 -0
- package/features/rds/rds.feature +32 -0
- package/features/rds/step_definitions/rds.js +72 -0
- package/features/redshift/redshift.feature +20 -0
- package/features/redshift/step_definitions/redshift.js +33 -0
- package/features/route53/route53.feature +41 -0
- package/features/route53/step_definitions/route53.js +97 -0
- package/features/s3/buckets.feature +40 -0
- package/features/s3/objects.feature +122 -0
- package/features/s3/step_definitions/buckets.js +136 -0
- package/features/s3/step_definitions/hooks.js +39 -0
- package/features/s3/step_definitions/objects.js +204 -0
- package/features/s3/step_definitions/proxy.js +44 -0
- package/features/ses/ses.feature +20 -0
- package/features/ses/step_definitions/ses.js +22 -0
- package/features/simpledb/simpledb.feature +29 -0
- package/features/simpledb/step_definitions/simpledb.js +46 -0
- package/features/sns/sns.feature +15 -0
- package/features/sns/step_definitions/sns.js +33 -0
- package/features/sqs/messages.feature +21 -0
- package/features/sqs/queues.feature +18 -0
- package/features/sqs/step_definitions/messages.js +46 -0
- package/features/sqs/step_definitions/queues.js +33 -0
- package/features/sqs/step_definitions/sqs.js +7 -0
- package/features/storagegateway/step_definitions/storagegateway.js +16 -0
- package/features/storagegateway/storagegateway.feature +13 -0
- package/features/sts/step_definitions/sts.js +35 -0
- package/features/sts/sts.feature +29 -0
- package/features/support/step_definitions/support.js +35 -0
- package/features/support/support.feature +18 -0
- package/features/swf/step_definitions/swf.js +38 -0
- package/features/swf/swf.feature +15 -0
- package/index.js +2 -0
- package/lib/core.js +2 -2
- package/lib/credentials/shared_ini_file_credentials.js +0 -1
- package/lib/event_listeners.js +13 -1
- package/lib/http/node.js +19 -30
- package/lib/model/resource_waiter.js +0 -4
- package/lib/model/shape.js +2 -1
- package/lib/protocol/rest_xml.js +1 -1
- package/lib/region_config.js +31 -0
- package/lib/region_config.json +56 -0
- package/lib/request.js +37 -45
- package/lib/sequential_executor.js +17 -34
- package/lib/service.js +17 -44
- package/lib/services/cloudsearchdomain.js +69 -0
- package/lib/services/route53.js +0 -12
- package/lib/services/s3.js +3 -19
- package/lib/signers/v4.js +2 -1
- package/lib/util.js +28 -3
- package/package.json +3 -3
- package/scripts/console +11 -3
- package/scripts/coverage +126 -0
- package/tasks/apis.rake +122 -0
- package/tasks/browser.rake +89 -0
- package/tasks/docs.rake +36 -0
- package/tasks/lib/cucumber_generator.rb +40 -0
- package/tasks/util.rake +33 -0
- package/test/browser/js/jasmine-1.3.1.js +2600 -0
- package/test/browser/js/jasmine-html.js +681 -0
- package/test/browser/runner.html +109 -0
- package/test/browser/runner.js +92 -0
- package/test/browser/sample/appinfo.sample.js +15 -0
- package/test/browser/sample/console.html +429 -0
- package/test/browser/sample/css/smoothness/images/animated-overlay.gif +0 -0
- package/test/browser/sample/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
- package/test/browser/sample/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- package/test/browser/sample/css/smoothness/jquery-ui-1.10.1.custom.css +1175 -0
- package/test/browser/sample/css/smoothness/jquery-ui-1.10.1.custom.min.css +5 -0
- package/test/browser/sample/img/loading.gif +0 -0
- package/test/browser/sample/js/jquery-1.9.1.js +9597 -0
- package/test/browser/sample/js/jquery-ui-1.10.1.custom.js +14903 -0
- package/test/browser/sample/js/jquery-ui-1.10.1.custom.min.js +6 -0
- package/test/browser/sample/s3upload.html +111 -0
- package/test/browser.spec.coffee +207 -0
- package/test/config.spec.coffee +202 -0
- package/test/credential_provider_chain.spec.coffee +90 -0
- package/test/credentials.spec.coffee +452 -0
- package/test/endpoint.spec.coffee +80 -0
- package/test/event_listeners.spec.coffee +493 -0
- package/test/helpers.coffee +150 -0
- package/test/http_request.spec.coffee +55 -0
- package/test/json/builder.spec.coffee +129 -0
- package/test/json/parser.spec.coffee +108 -0
- package/test/metadata_service.spec.coffee +54 -0
- package/test/model/api.spec.coffee +67 -0
- package/test/model/shape.spec.coffee +23 -0
- package/test/node_http_client.spec.coffee +40 -0
- package/test/param_validator.spec.coffee +456 -0
- package/test/protocol/json.spec.coffee +167 -0
- package/test/protocol/query.spec.coffee +191 -0
- package/test/protocol/rest.spec.coffee +237 -0
- package/test/protocol/rest_json.spec.coffee +255 -0
- package/test/protocol/rest_xml.spec.coffee +329 -0
- package/test/query/query_param_serializer.spec.coffee +327 -0
- package/test/region_config.spec.coffee +50 -0
- package/test/request.spec.coffee +316 -0
- package/test/resource_waiter.spec.coffee +89 -0
- package/test/response.spec.coffee +81 -0
- package/test/sequential_executor.spec.coffee +118 -0
- package/test/service.spec.coffee +230 -0
- package/test/services/cloudfront.spec.coffee +44 -0
- package/test/services/cloudsearchdomain.spec.coffee +23 -0
- package/test/services/dynamodb.spec.coffee +32 -0
- package/test/services/ec2.spec.coffee +78 -0
- package/test/services/elastictranscoder.spec.coffee +43 -0
- package/test/services/glacier.spec.coffee +61 -0
- package/test/services/rds.spec.coffee +38 -0
- package/test/services/route53.spec.coffee +77 -0
- package/test/services/s3.spec.coffee +538 -0
- package/test/services/simpledb.spec.coffee +12 -0
- package/test/services/sqs.spec.coffee +130 -0
- package/test/services/sts.spec.coffee +72 -0
- package/test/services/swf.spec.coffee +6 -0
- package/test/signers/presign.spec.coffee +36 -0
- package/test/signers/s3.spec.coffee +297 -0
- package/test/signers/v2.spec.coffee +68 -0
- package/test/signers/v4.spec.coffee +135 -0
- package/test/util.spec.coffee +510 -0
- package/test/xml/builder.spec.coffee +529 -0
- package/test/xml/parser.spec.coffee +587 -0
- package/lib/services/simpledb.js +0 -15
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# language: en
|
|
2
|
+
@s3 @objects
|
|
3
|
+
Feature: Working with Objects in S3
|
|
4
|
+
|
|
5
|
+
As a user of S3
|
|
6
|
+
I need to be able to work with objects in a bucket.
|
|
7
|
+
|
|
8
|
+
Scenario: CRUD objects
|
|
9
|
+
When I write "world" to the key "hello"
|
|
10
|
+
Then the object with the key "hello" should exist
|
|
11
|
+
And the object with the key "hello" should contain "world"
|
|
12
|
+
When I write "new world" to the key "hello"
|
|
13
|
+
Then the object with the key "hello" should exist
|
|
14
|
+
Then the object with the key "hello" should contain "new world"
|
|
15
|
+
|
|
16
|
+
# Empty files
|
|
17
|
+
When I write "" to the key "hello"
|
|
18
|
+
Then the object with the key "hello" should exist
|
|
19
|
+
And the object with the key "hello" should contain ""
|
|
20
|
+
|
|
21
|
+
# ContentLength
|
|
22
|
+
When I write "foobar" to the key "hello" with ContentLength 3
|
|
23
|
+
Then the object with the key "hello" should exist
|
|
24
|
+
And the object with the key "hello" should contain "foo"
|
|
25
|
+
|
|
26
|
+
# ContentLength
|
|
27
|
+
When I write empty buffer to the key "hello"
|
|
28
|
+
Then the object with the key "hello" should exist
|
|
29
|
+
And the object with the key "hello" should contain ""
|
|
30
|
+
|
|
31
|
+
# UTF-8
|
|
32
|
+
When I write "åß∂ƒ©" to the key "hello"
|
|
33
|
+
Then the object with the key "hello" should exist
|
|
34
|
+
And the object with the key "hello" should contain "åß∂ƒ©"
|
|
35
|
+
|
|
36
|
+
When I copy an object with the key "hello" to "byebye"
|
|
37
|
+
Then the object with the key "byebye" should exist
|
|
38
|
+
And the object with the key "byebye" should contain "åß∂ƒ©"
|
|
39
|
+
And I delete the object with the key "byebye"
|
|
40
|
+
|
|
41
|
+
# Unauthenticated request
|
|
42
|
+
When I write "world" to the public key "hello"
|
|
43
|
+
Then the unauthenticated request to read key "hello" should equal "world"
|
|
44
|
+
|
|
45
|
+
When I delete the object with the key "hello"
|
|
46
|
+
Then the object with the key "hello" should not exist
|
|
47
|
+
|
|
48
|
+
@presigned
|
|
49
|
+
Scenario: Pre-signed URLs
|
|
50
|
+
Given I get a pre-signed URL to PUT the key "hello"
|
|
51
|
+
And I access the URL via HTTP PUT with data "PRESIGNED BODY CONTENTS"
|
|
52
|
+
When I get a pre-signed URL to GET the key "hello"
|
|
53
|
+
And I access the URL via HTTP GET
|
|
54
|
+
Then the HTTP response should equal "PRESIGNED BODY CONTENTS"
|
|
55
|
+
|
|
56
|
+
@presigned @checksum
|
|
57
|
+
Scenario: Pre-signed URLs with checksum
|
|
58
|
+
Given I get a pre-signed URL to PUT the key "hello" with data "CHECKSUMMED"
|
|
59
|
+
And I access the URL via HTTP PUT with data "NOT CHECKSUMMED"
|
|
60
|
+
Then the HTTP response should contain "SignatureDoesNotMatch"
|
|
61
|
+
|
|
62
|
+
@buffer
|
|
63
|
+
Scenario: Buffers and streams
|
|
64
|
+
When I write buffer "world" to the key "hello"
|
|
65
|
+
Then the object with the key "hello" should exist
|
|
66
|
+
And the object with the key "hello" should contain "world"
|
|
67
|
+
|
|
68
|
+
When I write file "testfile.txt" to the key "hello"
|
|
69
|
+
Then the object with the key "hello" should exist
|
|
70
|
+
And the object with the key "hello" should contain "CONTENTS OF FILE"
|
|
71
|
+
|
|
72
|
+
When I stream key "hello"
|
|
73
|
+
Then the streamed data should contain "CONTENTS OF FILE"
|
|
74
|
+
|
|
75
|
+
When I stream2 key "hello"
|
|
76
|
+
Then the streamed data should contain "CONTENTS OF FILE"
|
|
77
|
+
|
|
78
|
+
@progress
|
|
79
|
+
Scenario: Progress events
|
|
80
|
+
When I write a 512KB buffer to the key "hello" with progress events
|
|
81
|
+
Then more than 1 "httpUploadProgress" event should fire
|
|
82
|
+
And the "total" value of the progress event should equal 512KB
|
|
83
|
+
And the "loaded" value of the first progress event should be greater than 10 bytes
|
|
84
|
+
|
|
85
|
+
When I read the key "hello" with progress events
|
|
86
|
+
Then more than 1 "httpDownloadProgress" event should fire
|
|
87
|
+
And the "total" value of the progress event should equal 512KB
|
|
88
|
+
And the "loaded" value of the first progress event should be greater than 10 bytes
|
|
89
|
+
|
|
90
|
+
@proxy
|
|
91
|
+
Scenario: Proxy support
|
|
92
|
+
When I write "world" to the key "hello"
|
|
93
|
+
Then the object with the key "hello" should exist
|
|
94
|
+
And the object with the key "hello" should contain "world"
|
|
95
|
+
|
|
96
|
+
When I delete the object with the key "hello"
|
|
97
|
+
Then the object with the key "hello" should not exist
|
|
98
|
+
|
|
99
|
+
And I teardown the local proxy server
|
|
100
|
+
|
|
101
|
+
@pagination
|
|
102
|
+
Scenario: Paginating responses
|
|
103
|
+
Given I delete the object with the key "hello"
|
|
104
|
+
And I write "data" to the key "obj0"
|
|
105
|
+
And I write "data" to the key "obj1"
|
|
106
|
+
And I write "data" to the key "obj2"
|
|
107
|
+
And I write "data" to the key "obj3"
|
|
108
|
+
And I write "data" to the key "obj4"
|
|
109
|
+
And I write "data" to the key "obj5"
|
|
110
|
+
And I write "data" to the key "obj6"
|
|
111
|
+
And I write "data" to the key "obj7"
|
|
112
|
+
And I write "data" to the key "obj8"
|
|
113
|
+
And I write "data" to the key "obj9"
|
|
114
|
+
And the object with the key "obj9" should exist
|
|
115
|
+
And I setup the listObjects request for the bucket
|
|
116
|
+
When I paginate the "listObjects" operation with limit 3
|
|
117
|
+
Then I should get 4 pages
|
|
118
|
+
|
|
119
|
+
@error
|
|
120
|
+
Scenario: Error handling
|
|
121
|
+
Given I write "data" to the invalid key ""
|
|
122
|
+
Then the status code should be 400
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
module.exports = function() {
|
|
2
|
+
|
|
3
|
+
this.When(/^I create a bucket$/, function(next) {
|
|
4
|
+
this.bucket = this.uniqueName('aws-sdk-js-integration');
|
|
5
|
+
this.request('s3', 'createBucket', {Bucket:this.bucket}, next);
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
this.When(/^I create a bucket with the location constraint "([^"]*)"$/, function(loc, next) {
|
|
9
|
+
this.bucket = this.uniqueName('aws-sdk-js-integration');
|
|
10
|
+
var params = { Bucket: this.bucket, CreateBucketConfiguration: { LocationConstraint: loc }};
|
|
11
|
+
this.request('s3', 'createBucket', params, next);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
this.Then(/^the bucket should exist$/, function(next) {
|
|
15
|
+
this.s3.waitFor('bucketExists', {Bucket:this.bucket}, next);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
this.When(/^I delete the bucket$/, function(next) {
|
|
19
|
+
this.request('s3', 'deleteBucket', {Bucket:this.bucket}, next);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
this.Then(/^the bucket should not exist$/, function(next) {
|
|
23
|
+
this.s3.waitFor('bucketNotExists', {Bucket:this.bucket}, next);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
this.Then(/^the bucket should have a location constraint of "([^"]*)"$/, function(loc, next) {
|
|
27
|
+
var self = this;
|
|
28
|
+
self.s3.getBucketLocation({Bucket:self.bucket}, function(err, data) {
|
|
29
|
+
self.assert.equal(data.LocationConstraint, loc);
|
|
30
|
+
next();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
this.Then(/^I delete the bucket$/, function(next) {
|
|
35
|
+
this.request('s3', 'deleteBucket', {Bucket:this.bucket}, next);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
this.When(/^I put a transition lifecycle configuration on the bucket with prefix "([^"]*)"$/, function(prefix, callback) {
|
|
39
|
+
var params = {
|
|
40
|
+
Bucket: this.bucket,
|
|
41
|
+
LifecycleConfiguration: {
|
|
42
|
+
Rules: [{
|
|
43
|
+
Prefix: prefix,
|
|
44
|
+
Status: 'Enabled',
|
|
45
|
+
Transition: {Days: 0, StorageClass: 'GLACIER'}
|
|
46
|
+
}]
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
this.request('s3', 'putBucketLifecycle', params, callback);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
this.When(/^I get the transition lifecycle configuration on the bucket$/, function(callback) {
|
|
54
|
+
this.eventually(callback, function(next) {
|
|
55
|
+
this.request('s3', 'getBucketLifecycle', {Bucket: this.bucket}, next);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
this.Then(/^the lifecycle configuration should have transition days of (\d+)$/, function(days, callback) {
|
|
60
|
+
this.assert.equal(this.data.Rules[0].Transition.Days, 0);
|
|
61
|
+
callback();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
this.Then(/^the lifecycle configuration should have transition storage class of "([^"]*)"$/, function(value, callback) {
|
|
65
|
+
this.assert.equal(this.data.Rules[0].Transition.StorageClass, value);
|
|
66
|
+
callback();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
this.When(/^I put a bucket CORS configuration$/, function(callback) {
|
|
70
|
+
var params = {
|
|
71
|
+
Bucket: this.bucket,
|
|
72
|
+
CORSConfiguration: {
|
|
73
|
+
CORSRules: [{
|
|
74
|
+
AllowedMethods: ['DELETE', 'POST', 'PUT'],
|
|
75
|
+
AllowedOrigins: ['http://example.com'],
|
|
76
|
+
AllowedHeaders: ['*'],
|
|
77
|
+
ExposeHeaders: ['x-amz-server-side-encryption'],
|
|
78
|
+
MaxAgeSeconds: 5000
|
|
79
|
+
}]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
this.request('s3', 'putBucketCors', params, callback);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
this.When(/^I get the bucket CORS configuration$/, function(callback) {
|
|
86
|
+
this.request('s3', 'getBucketCors', {Bucket: this.bucket}, callback);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
this.Then(/^the AllowedMethods list should inclue "([^"]*)"$/, function(value, callback) {
|
|
90
|
+
this.assert.equal(this.data.CORSRules[0].AllowedMethods.sort().join(" "), "DELETE POST PUT");
|
|
91
|
+
callback();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
this.Then(/^the AllowedOrigin value should equal "([^"]*)"$/, function(value, callback) {
|
|
95
|
+
this.assert.equal(this.data.CORSRules[0].AllowedOrigins[0], value);
|
|
96
|
+
callback();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
this.Then(/^the AllowedHeader value should equal "([^"]*)"$/, function(value, callback) {
|
|
100
|
+
this.assert.equal(this.data.CORSRules[0].AllowedHeaders[0], value);
|
|
101
|
+
callback();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
this.Then(/^the ExposeHeader value should equal "([^"]*)"$/, function(value, callback) {
|
|
105
|
+
this.assert.equal(this.data.CORSRules[0].ExposeHeaders[0], value);
|
|
106
|
+
callback();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
this.Then(/^the MaxAgeSeconds value should equal (\d+)$/, function(value, callback) {
|
|
110
|
+
this.assert.equal(this.data.CORSRules[0].MaxAgeSeconds, parseInt(value));
|
|
111
|
+
callback();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
this.When(/^I put a bucket tag with key "([^"]*)" and value "([^"]*)"$/, function(key, value, callback) {
|
|
115
|
+
var params = {
|
|
116
|
+
Bucket: this.bucket,
|
|
117
|
+
Tagging: {
|
|
118
|
+
TagSet: [
|
|
119
|
+
{Key: key, Value: value}
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
this.request('s3', 'putBucketTagging', params, callback);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
this.When(/^I get the bucket tagging$/, function(callback) {
|
|
128
|
+
this.request('s3', 'getBucketTagging', {Bucket: this.bucket}, callback);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
this.Then(/^the first tag in the tag set should have key and value "([^"]*)", "([^"]*)"$/, function(key, value, callback) {
|
|
132
|
+
this.assert.equal(this.data.TagSet[0].Key, key);
|
|
133
|
+
this.assert.equal(this.data.TagSet[0].Value, value);
|
|
134
|
+
callback();
|
|
135
|
+
});
|
|
136
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module.exports = function () {
|
|
2
|
+
|
|
3
|
+
function cleanBucket(world, bucket, callback) {
|
|
4
|
+
if (!bucket) { callback(); return; }
|
|
5
|
+
|
|
6
|
+
var params = {Bucket: bucket};
|
|
7
|
+
var deleteBucket = function() {
|
|
8
|
+
delete params.Delete;
|
|
9
|
+
world.request('s3', 'deleteBucket', params, callback, false);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
world.s3.listObjects(params, function (err, data) {
|
|
13
|
+
if (err) { deleteBucket(); return; }
|
|
14
|
+
if (data.Contents.length > 0) {
|
|
15
|
+
params.Delete = { Objects: [] };
|
|
16
|
+
world.AWS.util.arrayEach(data.Contents, function (item) {
|
|
17
|
+
params.Delete.Objects.push({Key: item.Key});
|
|
18
|
+
});
|
|
19
|
+
world.request('s3', 'deleteObjects', params, deleteBucket);
|
|
20
|
+
} else {
|
|
21
|
+
deleteBucket();
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this.Before("@s3", function (callback) {
|
|
27
|
+
this.service = this.s3 = new this.AWS.S3({maxRetries: 100});
|
|
28
|
+
callback();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
this.After("@s3", function (callback) {
|
|
32
|
+
cleanBucket(this, this.bucket, callback);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
this.AfterAll(function(callback) {
|
|
36
|
+
cleanBucket(this, this.sharedBucket, callback);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
};
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
module.exports = function () {
|
|
2
|
+
/**
|
|
3
|
+
* Create a single bucket that will be shared by all s3 object scenarios.
|
|
4
|
+
*/
|
|
5
|
+
this.Before("@s3", "@objects", function (callback) {
|
|
6
|
+
|
|
7
|
+
// execute only once
|
|
8
|
+
if (this.sharedBucket) {
|
|
9
|
+
callback();
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
this.sharedBucket = this.uniqueName('aws-sdk-js-integration');
|
|
14
|
+
this.s3.createBucket({Bucket:this.sharedBucket}, function(err, data) {
|
|
15
|
+
callback();
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
this.When(/^I write (buffer )?"([^"]*)" to the key "([^"]*)"$/, function(buffer, contents, key, next) {
|
|
20
|
+
var params = {Bucket: this.sharedBucket, Key: key, Body: buffer ? new Buffer(contents) : contents};
|
|
21
|
+
this.request('s3', 'putObject', params, next);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
this.When(/^I write (buffer )?"([^"]*)" to the invalid key "([^"]*)"$/, function(buffer, contents, key, next) {
|
|
25
|
+
var params = {Bucket: this.sharedBucket, Key: key, Body: buffer ? new Buffer(contents) : contents};
|
|
26
|
+
this.request('s3', 'putObject', params, next, false);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
this.When(/^I write "([^"]*)" to the key "([^"]*)" with ContentLength (\d+)$/, function(contents, key, contentLength, next) {
|
|
30
|
+
var params = {Bucket: this.sharedBucket, Key: key, Body: contents, ContentLength: parseInt(contentLength)};
|
|
31
|
+
this.s3nochecksums = new this.AWS.S3({computeChecksums: false});
|
|
32
|
+
this.request('s3nochecksums', 'putObject', params, next);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
this.When(/^I write empty buffer to the key "([^"]*)"$/, function (key, next) {
|
|
36
|
+
var params = {Bucket: this.sharedBucket, Key: key, Body: new Buffer(0)};
|
|
37
|
+
this.request('s3', 'putObject', params, next);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
this.Then(/^the object with the key "([^"]*)" should contain "([^"]*)"$/, function(key, contents, next) {
|
|
41
|
+
this.assert.equal(this.data.Body.toString().replace("\n", ""), contents);
|
|
42
|
+
next();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
this.When(/^I copy an object with the key "([^"]*)" to "([^"]*)"$/, function(key1, key2, next) {
|
|
46
|
+
var params = {
|
|
47
|
+
Bucket: this.sharedBucket, Key: key2, CopySource: '/' + this.sharedBucket + '/' + key1
|
|
48
|
+
}
|
|
49
|
+
this.request('s3', 'copyObject', params, next);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
this.When(/^I delete the object with the key "([^"]*)"$/, function(key, next) {
|
|
53
|
+
var params = {Bucket:this.sharedBucket,Key:key};
|
|
54
|
+
this.request('s3', 'deleteObject', params, next);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
this.Then(/^the object with the key "([^"]*)" should (not )?exist$/, function(key, shouldNotExist, next) {
|
|
58
|
+
var params = { Bucket:this.sharedBucket, Key:key };
|
|
59
|
+
this.eventually(next, function (retry) {
|
|
60
|
+
retry.condition = function() {
|
|
61
|
+
if (shouldNotExist) {
|
|
62
|
+
return this.error && this.error.code == 'NoSuchKey';
|
|
63
|
+
} else {
|
|
64
|
+
return !this.error;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
this.request('s3', 'getObject', params, retry, false);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
this.When(/^I write file "([^"]*)" to the key "([^"]*)"$/, function(filename, key, next) {
|
|
72
|
+
var fs = require('fs');
|
|
73
|
+
var params = {Bucket: this.sharedBucket, Key: key, Body:
|
|
74
|
+
fs.createReadStream(__dirname + '/../../extra/fixtures/' + filename)};
|
|
75
|
+
this.request('s3', 'putObject', params, next);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
this.When(/^I stream key "([^"]*)"$/, function(key, callback) {
|
|
79
|
+
var params = {Bucket: this.sharedBucket, Key: key};
|
|
80
|
+
var world = this;
|
|
81
|
+
this.result = '';
|
|
82
|
+
this.service.getObject(params).createReadStream().
|
|
83
|
+
on('end', function() { callback(); }).
|
|
84
|
+
on('data', function(d) { world.result += d.toString(); });
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
this.When(/^I stream2 key "([^"]*)"$/, function(key, callback) {
|
|
88
|
+
if (!require('stream').Readable) return callback();
|
|
89
|
+
var params = {Bucket: this.sharedBucket, Key: key};
|
|
90
|
+
var world = this;
|
|
91
|
+
this.result = '';
|
|
92
|
+
var stream = this.service.getObject(params).createReadStream();
|
|
93
|
+
stream.on('end', function() { callback(); });
|
|
94
|
+
stream.on('readable', function() {
|
|
95
|
+
var v = stream.read(); if (v) world.result += v;
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
this.Then(/^the streamed data should contain "([^"]*)"$/, function(data, callback) {
|
|
100
|
+
this.assert.equal(this.result.replace('\n', ''), data);
|
|
101
|
+
callback();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
this.When(/^I get a pre\-signed URL to GET the key "([^"]*)"$/, function(key, callback) {
|
|
105
|
+
this.signedUrl = this.s3.getSignedUrl('getObject', {Bucket: this.sharedBucket, Key: key});
|
|
106
|
+
callback();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
this.When(/^I access the URL via HTTP GET$/, function(callback, verb) {
|
|
110
|
+
var world = this;
|
|
111
|
+
this.data = '';
|
|
112
|
+
require('https').get(this.signedUrl, function (res) {
|
|
113
|
+
res.on('data', function (chunk) {
|
|
114
|
+
world.data += chunk.toString();
|
|
115
|
+
}).on('end', callback);
|
|
116
|
+
}).on('error', callback.fail);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
this.Given(/^I get a pre\-signed URL to PUT the key "([^"]*)"(?: with data "([^"]*)")?$/, function(key, body, callback) {
|
|
120
|
+
var params = {Bucket: this.sharedBucket, Key: key};
|
|
121
|
+
if (body) params.Body = body;
|
|
122
|
+
this.signedUrl = this.s3.getSignedUrl('putObject', params);
|
|
123
|
+
callback();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
this.Given(/^I access the URL via HTTP PUT with data "([^"]*)"$/, function(body, callback) {
|
|
127
|
+
var world = this;
|
|
128
|
+
this.data = '';
|
|
129
|
+
|
|
130
|
+
var data = body;
|
|
131
|
+
var options = require('url').parse(this.signedUrl);
|
|
132
|
+
options.method = 'PUT';
|
|
133
|
+
options.headers = {'Content-Length': data.length};
|
|
134
|
+
|
|
135
|
+
var req = require('https').request(options, function (res) {
|
|
136
|
+
res.on('data', function (chunk) {
|
|
137
|
+
world.data += chunk.toString();
|
|
138
|
+
}).on('end', callback);
|
|
139
|
+
}).on('error', callback.fail).end(data);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
this.Then(/^the HTTP response should equal "([^"]*)"$/, function(data, callback) {
|
|
143
|
+
this.assert.equal(this.data, data);
|
|
144
|
+
callback();
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
this.Then(/^the HTTP response should contain "([^"]*)"$/, function(data, callback) {
|
|
148
|
+
this.assert.match(this.data, data);
|
|
149
|
+
callback();
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
this.Given(/^I setup the listObjects request for the bucket$/, function(callback) {
|
|
153
|
+
this.params = { Bucket: this.sharedBucket };
|
|
154
|
+
callback();
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// progress events
|
|
158
|
+
|
|
159
|
+
this.When(/^I write a (\d+)KB buffer to the key "([^"]*)" with progress events$/, function(kb, key, callback) {
|
|
160
|
+
var self = this;
|
|
161
|
+
var body = new Buffer(new Array(kb * 1024 + 1).join('x'));
|
|
162
|
+
this.progress = [];
|
|
163
|
+
var req = this.s3.putObject({Bucket: this.sharedBucket, Key: key, Body: body});
|
|
164
|
+
req.on('httpUploadProgress', function (p) { self.progress.push(p) });
|
|
165
|
+
req.send(callback);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
this.Then(/^more than (\d+) "([^"]*)" event should fire$/, function(numEvents, eventName, callback) {
|
|
169
|
+
this.assert.compare(this.progress.length, '>', numEvents);
|
|
170
|
+
callback();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
this.Then(/^the "([^"]*)" value of the progress event should equal (\d+)KB$/, function(prop, kb, callback) {
|
|
174
|
+
this.assert.equal(this.progress[0][prop], kb * 1024);
|
|
175
|
+
callback();
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
this.Then(/^the "([^"]*)" value of the first progress event should be greater than (\d+) bytes$/, function(prop, bytes, callback) {
|
|
179
|
+
this.assert.compare(this.progress[0][prop], '>', bytes);
|
|
180
|
+
callback();
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
this.When(/^I read the key "([^"]*)" with progress events$/, function(key, callback) {
|
|
184
|
+
var self = this;
|
|
185
|
+
this.progress = [];
|
|
186
|
+
var req = this.s3.getObject({Bucket: this.sharedBucket, Key: key});
|
|
187
|
+
req.on('httpDownloadProgress', function (p) { self.progress.push(p) });
|
|
188
|
+
req.send(callback);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
this.When(/^I write "([^"]*)" to the public key "([^"]*)"$/, function(data, key, next) {
|
|
192
|
+
var params = {Bucket: this.sharedBucket, Key: key, Body: data, ACL: 'public-read'};
|
|
193
|
+
this.request('s3', 'putObject', params, next);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
this.Then(/^the unauthenticated request to read key "([^"]*)" should equal "([^"]*)"$/, function(key, body, next) {
|
|
197
|
+
var params = {Bucket: this.sharedBucket, Key: key};
|
|
198
|
+
this.s3.makeUnauthenticatedRequest('getObject', params, function (err, data) {
|
|
199
|
+
if (err) return next(err);
|
|
200
|
+
this.assert.equal(data.Body.toString(), body);
|
|
201
|
+
next();
|
|
202
|
+
}.bind(this));
|
|
203
|
+
});
|
|
204
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
var url = require('url');
|
|
2
|
+
var http = require('http');
|
|
3
|
+
|
|
4
|
+
module.exports = function() {
|
|
5
|
+
this.Before("@s3", "@proxy", function(callback) {
|
|
6
|
+
setupProxyServer.call(this);
|
|
7
|
+
|
|
8
|
+
this.service = this.s3 = new this.AWS.S3({
|
|
9
|
+
httpOptions: { proxy: 'http://localhost:' + this.proxyPort }
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
callback();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
this.Then(/^I teardown the local proxy server$/, function(callback) {
|
|
16
|
+
this.service = this.s3 = new this.AWS.S3();
|
|
17
|
+
this.proxyServer.close(callback);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
function setupProxyServer() {
|
|
21
|
+
if (this.proxyServer) return;
|
|
22
|
+
this.proxyPort = 8000 + parseInt(Math.random() * 100);
|
|
23
|
+
this.proxyServer = http.createServer(function (req, res) {
|
|
24
|
+
var uri = url.parse(req.url);
|
|
25
|
+
var options = {
|
|
26
|
+
host: uri.hostname,
|
|
27
|
+
port: uri.port || 80,
|
|
28
|
+
method: req.method,
|
|
29
|
+
path: uri.path,
|
|
30
|
+
headers: req.headers
|
|
31
|
+
};
|
|
32
|
+
options.headers.host = uri.hostname;
|
|
33
|
+
|
|
34
|
+
var s = http.request(options, function (res2) {
|
|
35
|
+
res.writeHead(res2.statusCode, res2.headers);
|
|
36
|
+
res2.on('data', function(ch) {
|
|
37
|
+
res.write(ch);
|
|
38
|
+
}).on('end', function() { res.end(); });
|
|
39
|
+
});
|
|
40
|
+
req.pipe(s);
|
|
41
|
+
});
|
|
42
|
+
this.proxyServer.listen(this.proxyPort);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# language: en
|
|
2
|
+
@ses
|
|
3
|
+
Feature: SES
|
|
4
|
+
|
|
5
|
+
I want to use Simple Email Service.
|
|
6
|
+
|
|
7
|
+
Scenario: Check quota
|
|
8
|
+
When I check quota
|
|
9
|
+
Then the result should include number "SentLast24Hours"
|
|
10
|
+
And the result should include number "MaxSendRate"
|
|
11
|
+
|
|
12
|
+
Scenario: Verify email
|
|
13
|
+
When I ask to verify the email address "foo@example.com"
|
|
14
|
+
Then the status code should be 200
|
|
15
|
+
|
|
16
|
+
Scenario: Rescue SES InvalidParameterValue
|
|
17
|
+
When I ask to verify the email address "abc123"
|
|
18
|
+
Then I should get the error:
|
|
19
|
+
| code | message |
|
|
20
|
+
| InvalidParameterValue | Invalid email address<abc123>. |
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module.exports = function() {
|
|
2
|
+
this.Before("@ses", function (callback) {
|
|
3
|
+
this.service = new this.AWS.SES();
|
|
4
|
+
callback();
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
this.When(/^I check quota$/, function(next) {
|
|
8
|
+
this.request(null, 'getSendQuota', {}, next);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
this.Then(/^the result should include (\S+) "([^"]*)"$/, function(type, attr, next) {
|
|
12
|
+
if (this.data[attr] === undefined) next.fail("Missing " + attr);
|
|
13
|
+
if (typeof this.data[attr] !== type) next.fail("Incorrect type " + attr);
|
|
14
|
+
next();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
this.When(/^I ask to verify the email address "([^"]*)"$/, function(email, next) {
|
|
18
|
+
this.request(null, 'verifyEmailAddress', {EmailAddress: email}, next, function() {
|
|
19
|
+
// do nothing
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# language: en
|
|
2
|
+
@simpledb
|
|
3
|
+
Feature: Amazon SimpleDB
|
|
4
|
+
|
|
5
|
+
I want to use Amazon SimpleDB
|
|
6
|
+
|
|
7
|
+
Scenario: CRUD
|
|
8
|
+
Given I create a SimpleDB domain
|
|
9
|
+
And I put an item "key" with attributes:
|
|
10
|
+
"""
|
|
11
|
+
[{"Name": "attr1", "Value": "value1"}]
|
|
12
|
+
"""
|
|
13
|
+
And I get the item "key"
|
|
14
|
+
Then the result should have attribute "attr1" with "value1"
|
|
15
|
+
And I delete the domain
|
|
16
|
+
|
|
17
|
+
Scenario: SELECT * statements
|
|
18
|
+
Given I create a SimpleDB domain
|
|
19
|
+
And I put an item "key" with attributes:
|
|
20
|
+
"""
|
|
21
|
+
[{"Name": "attr1", "Value": "value1"}]
|
|
22
|
+
"""
|
|
23
|
+
And I select "*" from the domain
|
|
24
|
+
Then the select result should contain the item
|
|
25
|
+
And I delete the domain
|
|
26
|
+
|
|
27
|
+
Scenario: Error handling
|
|
28
|
+
Given I create a domain with no name
|
|
29
|
+
Then the error code should be "InvalidParameterValue"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module.exports = function() {
|
|
2
|
+
this.Before("@simpledb", function (callback) {
|
|
3
|
+
this.service = new this.AWS.SimpleDB();
|
|
4
|
+
this.domainName = 'aws-sdk-js-integration-' + new Date().getTime();
|
|
5
|
+
callback();
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
this.Given(/^I create a SimpleDB domain$/, function(callback) {
|
|
9
|
+
this.request(null, 'createDomain', {DomainName: this.domainName}, callback);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
this.Given(/^I put an item "([^"]*)" with attributes:$/, function(item, string, callback) {
|
|
13
|
+
this.item = {Name: item, Attributes: JSON.parse(string)};
|
|
14
|
+
var params = {DomainName: this.domainName, ItemName: item, Attributes: this.item.Attributes};
|
|
15
|
+
this.request(null, 'putAttributes', params, callback);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
this.Given(/^I get the item "([^"]*)"$/, function(item, callback) {
|
|
19
|
+
var params = {DomainName: this.domainName, ItemName: item, ConsistentRead: true};
|
|
20
|
+
this.request(null, 'getAttributes', params, callback);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
this.Given(/^I select "([^"]*)" from the domain$/, function(expr, callback) {
|
|
24
|
+
var params = {SelectExpression: 'SELECT ' + expr + ' FROM `' + this.domainName + '`', ConsistentRead: true};
|
|
25
|
+
this.request(null, 'select', params, callback);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
this.Then(/^the select result should contain the item$/, function(callback) {
|
|
29
|
+
this.assert.deepEqual(this.data.Items, [this.item]);
|
|
30
|
+
callback();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
this.Then(/^the result should have attribute "([^"]*)" with "([^"]*)"$/, function(name, value, callback) {
|
|
34
|
+
this.assert.equal(this.data.Attributes[0].Name, name);
|
|
35
|
+
this.assert.equal(this.data.Attributes[0].Value, value);
|
|
36
|
+
callback();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
this.Then(/^I delete the domain$/, function(callback) {
|
|
40
|
+
this.request(null, 'deleteDomain', {DomainName: this.domainName}, callback);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
this.Given(/^I create a domain with no name$/, function(callback) {
|
|
44
|
+
this.request(null, 'createDomain', {DomainName: ''}, callback, false);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# language: en
|
|
2
|
+
@sns
|
|
3
|
+
Feature: Simple Notification Service
|
|
4
|
+
|
|
5
|
+
I want to use Amazon Simple Notification Service
|
|
6
|
+
|
|
7
|
+
Scenario: Topics
|
|
8
|
+
Given I create an SNS topic with name "aws-js-sdk-integration-topic"
|
|
9
|
+
And I list the SNS topics
|
|
10
|
+
Then the list should contain the topic ARN
|
|
11
|
+
And I delete the SNS topic
|
|
12
|
+
|
|
13
|
+
Scenario: Error handling
|
|
14
|
+
Given I get SNS topic attributes with an invalid ARN
|
|
15
|
+
Then the error code should be "InvalidParameter"
|