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.
Files changed (251) hide show
  1. package/.eslintrc +20 -0
  2. package/.gitignore +10 -0
  3. package/.travis.yml +20 -0
  4. package/.yardopts +20 -0
  5. package/.yardopts_guide +21 -0
  6. package/Gemfile +16 -0
  7. package/Gemfile.lock +34 -0
  8. package/README.md +5 -6
  9. package/Rakefile +14 -0
  10. package/UPGRADING.md +9 -4
  11. package/configuration.sample +5 -0
  12. package/dist/BUNDLE_LICENSE.txt +96 -0
  13. package/dist/aws-sdk.js +9594 -0
  14. package/dist/aws-sdk.min.js +21 -0
  15. package/dist-tools/.eslintrc +10 -0
  16. package/dist-tools/browser-builder.js +142 -0
  17. package/dist-tools/strategies/cache.js +68 -0
  18. package/dist-tools/strategies/default.js +165 -0
  19. package/dist-tools/test/browser-builder.mocha.spec.coffee +182 -0
  20. package/dist-tools/test/helpers.coffee +16 -0
  21. package/doc-src/guide/browser-building.md +93 -0
  22. package/doc-src/guide/browser-configuring-wif.md +287 -0
  23. package/doc-src/guide/browser-configuring.md +218 -0
  24. package/doc-src/guide/browser-examples.md +220 -0
  25. package/doc-src/guide/browser-intro.md +46 -0
  26. package/doc-src/guide/browser-making-requests.md +279 -0
  27. package/doc-src/guide/browser-services.md +75 -0
  28. package/doc-src/guide/index.md +41 -0
  29. package/doc-src/guide/node-configuring.md +272 -0
  30. package/doc-src/guide/node-examples.md +341 -0
  31. package/doc-src/guide/node-intro.md +32 -0
  32. package/doc-src/guide/node-making-requests.md +309 -0
  33. package/doc-src/guide/node-services.md +159 -0
  34. package/doc-src/templates/api-versions/model_documentor.rb +366 -0
  35. package/doc-src/templates/api-versions/plugin.rb +230 -0
  36. package/doc-src/templates/api-versions/templates/default/class/html/setup.rb +9 -0
  37. package/doc-src/templates/api-versions/templates/default/class/html/waiter_details_list.erb +7 -0
  38. package/doc-src/templates/api-versions/templates/default/class/html/waiter_summary.erb +7 -0
  39. package/doc-src/templates/api-versions/templates/default/docstring/html/experimental.erb +4 -0
  40. package/doc-src/templates/api-versions/templates/default/docstring/setup.rb +9 -0
  41. package/doc-src/templates/api-versions/templates/default/fulldoc/html/css/common.css +6 -0
  42. package/doc-src/templates/api-versions/templates/default/fulldoc/html/setup.rb +62 -0
  43. package/doc-src/templates/api-versions/templates/default/layout/html/services.erb +10 -0
  44. package/doc-src/templates/api-versions/templates/default/layout/html/setup.rb +28 -0
  45. package/doc-src/templates/api-versions/templates/default/module/html/box_info.erb +45 -0
  46. package/doc-src/templates/api-versions/templates/default/module/html/children.erb +8 -0
  47. package/doc-src/templates/api-versions/templates/default/tags/setup.rb +3 -0
  48. package/doc-src/templates/api-versions/templates/default/waiter_details/html/method_signature.erb +3 -0
  49. package/doc-src/templates/api-versions/templates/default/waiter_details/html/setup.rb +5 -0
  50. package/doc-src/templates/default/layout/html/footer.erb +31 -0
  51. package/doc-src/templates/default/layout/html/layout.erb +23 -0
  52. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/css/highlight.github.css +127 -0
  53. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/css/style.css +1192 -0
  54. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/img/logo.png +0 -0
  55. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/app.js +33 -0
  56. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/highlight.pack.js +27 -0
  57. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/AUTHORS +55 -0
  58. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/LICENSE +25 -0
  59. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/doctools.js +247 -0
  60. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/file.png +0 -0
  61. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/sphinx/searchtools.js +568 -0
  62. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/js/underscore.js +23 -0
  63. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/search.erb +29 -0
  64. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/search_index.erb +1 -0
  65. package/doc-src/templates/flasky_sphinx_guide/fulldoc/html/setup.rb +75 -0
  66. package/doc-src/templates/flasky_sphinx_guide/layout/html/layout.erb +93 -0
  67. package/doc-src/templates/flasky_sphinx_guide/layout/html/setup.rb +9 -0
  68. package/doc-src/templates/flasky_sphinx_guide/layout/html/sidebar.erb +45 -0
  69. package/doc-src/templates/flasky_sphinx_guide/onefile/html/layout.erb +51 -0
  70. package/doc-src/templates/flasky_sphinx_guide/onefile/html/setup.rb +1 -0
  71. package/eslint-rules/no-require-in-service.js +10 -0
  72. package/features/autoscaling/autoscaling.feature +21 -0
  73. package/features/autoscaling/step_definitions/autoscaling.js +49 -0
  74. package/features/cloudformation/cloudformation.feature +22 -0
  75. package/features/cloudformation/step_definitions/cloudformation.js +26 -0
  76. package/features/cloudfront/cloudfront.feature +28 -0
  77. package/features/cloudfront/step_definitions/cloudfront-latest.js +54 -0
  78. package/features/cloudfront/step_definitions/cloudfront.js +21 -0
  79. package/features/cloudsearch/cloudsearch.feature +34 -0
  80. package/features/cloudsearch/step_definitions/cloudsearch.js +42 -0
  81. package/features/cloudtrail/cloudtrail.feature +17 -0
  82. package/features/cloudtrail/step_definitions/cloudtrail.js +14 -0
  83. package/features/cloudwatch/cloudwatch.feature +15 -0
  84. package/features/cloudwatch/step_definitions/cloudwatch.js +48 -0
  85. package/features/datapipeline/datapipeline.feature +23 -0
  86. package/features/datapipeline/step_definitions/datapipeline.js +79 -0
  87. package/features/directconnect/directconnect.feature +20 -0
  88. package/features/directconnect/step_definitions/directconnect.js +44 -0
  89. package/features/dynamodb/crc32.feature +18 -0
  90. package/features/dynamodb/step_definitions/dynamodb.js +154 -0
  91. package/features/dynamodb/tables.feature +50 -0
  92. package/features/ec2/ec2.feature +28 -0
  93. package/features/ec2/step_definitions/ec2.js +65 -0
  94. package/features/elasticache/elasticache.feature +20 -0
  95. package/features/elasticache/step_definitions/elasticache.js +34 -0
  96. package/features/elasticbeanstalk/elasticbeanstalk.feature +22 -0
  97. package/features/elasticbeanstalk/step_definitions/elasticbeanstalk.js +38 -0
  98. package/features/elastictranscoder/elastictranscoder.feature +24 -0
  99. package/features/elastictranscoder/step_definitions/elastictranscoder.js +56 -0
  100. package/features/elb/elb.feature +19 -0
  101. package/features/elb/step_definitions/elb.js +37 -0
  102. package/features/emr/emr.feature +16 -0
  103. package/features/emr/step_definitions/emr.js +45 -0
  104. package/features/extra/assertions.js +29 -0
  105. package/features/extra/dummy.feature +0 -0
  106. package/features/extra/fixtures/testfile.txt +1 -0
  107. package/features/extra/helpers.js +113 -0
  108. package/features/extra/hooks.js +107 -0
  109. package/features/extra/world.js +12 -0
  110. package/features/glacier/glacier.feature +47 -0
  111. package/features/glacier/step_definitions/glacier.js +112 -0
  112. package/features/iam/iam.feature +24 -0
  113. package/features/iam/step_definitions/iam.js +66 -0
  114. package/features/importexport/importexport.feature +53 -0
  115. package/features/importexport/step_definitions/importexport.js +42 -0
  116. package/features/kinesis/kinesis.feature +9 -0
  117. package/features/kinesis/step_definitions/kinesis.js +10 -0
  118. package/features/opsworks/opsworks.feature +26 -0
  119. package/features/opsworks/step_definitions/opsworks.js +42 -0
  120. package/features/rds/rds.feature +32 -0
  121. package/features/rds/step_definitions/rds.js +72 -0
  122. package/features/redshift/redshift.feature +20 -0
  123. package/features/redshift/step_definitions/redshift.js +33 -0
  124. package/features/route53/route53.feature +41 -0
  125. package/features/route53/step_definitions/route53.js +97 -0
  126. package/features/s3/buckets.feature +40 -0
  127. package/features/s3/objects.feature +122 -0
  128. package/features/s3/step_definitions/buckets.js +136 -0
  129. package/features/s3/step_definitions/hooks.js +39 -0
  130. package/features/s3/step_definitions/objects.js +204 -0
  131. package/features/s3/step_definitions/proxy.js +44 -0
  132. package/features/ses/ses.feature +20 -0
  133. package/features/ses/step_definitions/ses.js +22 -0
  134. package/features/simpledb/simpledb.feature +29 -0
  135. package/features/simpledb/step_definitions/simpledb.js +46 -0
  136. package/features/sns/sns.feature +15 -0
  137. package/features/sns/step_definitions/sns.js +33 -0
  138. package/features/sqs/messages.feature +21 -0
  139. package/features/sqs/queues.feature +18 -0
  140. package/features/sqs/step_definitions/messages.js +46 -0
  141. package/features/sqs/step_definitions/queues.js +33 -0
  142. package/features/sqs/step_definitions/sqs.js +7 -0
  143. package/features/storagegateway/step_definitions/storagegateway.js +16 -0
  144. package/features/storagegateway/storagegateway.feature +13 -0
  145. package/features/sts/step_definitions/sts.js +35 -0
  146. package/features/sts/sts.feature +29 -0
  147. package/features/support/step_definitions/support.js +35 -0
  148. package/features/support/support.feature +18 -0
  149. package/features/swf/step_definitions/swf.js +38 -0
  150. package/features/swf/swf.feature +15 -0
  151. package/index.js +2 -0
  152. package/lib/core.js +2 -2
  153. package/lib/credentials/shared_ini_file_credentials.js +0 -1
  154. package/lib/event_listeners.js +13 -1
  155. package/lib/http/node.js +19 -30
  156. package/lib/model/resource_waiter.js +0 -4
  157. package/lib/model/shape.js +2 -1
  158. package/lib/protocol/rest_xml.js +1 -1
  159. package/lib/region_config.js +31 -0
  160. package/lib/region_config.json +56 -0
  161. package/lib/request.js +37 -45
  162. package/lib/sequential_executor.js +17 -34
  163. package/lib/service.js +17 -44
  164. package/lib/services/cloudsearchdomain.js +69 -0
  165. package/lib/services/route53.js +0 -12
  166. package/lib/services/s3.js +3 -19
  167. package/lib/signers/v4.js +2 -1
  168. package/lib/util.js +28 -3
  169. package/package.json +3 -3
  170. package/scripts/console +11 -3
  171. package/scripts/coverage +126 -0
  172. package/tasks/apis.rake +122 -0
  173. package/tasks/browser.rake +89 -0
  174. package/tasks/docs.rake +36 -0
  175. package/tasks/lib/cucumber_generator.rb +40 -0
  176. package/tasks/util.rake +33 -0
  177. package/test/browser/js/jasmine-1.3.1.js +2600 -0
  178. package/test/browser/js/jasmine-html.js +681 -0
  179. package/test/browser/runner.html +109 -0
  180. package/test/browser/runner.js +92 -0
  181. package/test/browser/sample/appinfo.sample.js +15 -0
  182. package/test/browser/sample/console.html +429 -0
  183. package/test/browser/sample/css/smoothness/images/animated-overlay.gif +0 -0
  184. package/test/browser/sample/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  185. package/test/browser/sample/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  186. package/test/browser/sample/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  187. package/test/browser/sample/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  188. package/test/browser/sample/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  189. package/test/browser/sample/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  190. package/test/browser/sample/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  191. package/test/browser/sample/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  192. package/test/browser/sample/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  193. package/test/browser/sample/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  194. package/test/browser/sample/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  195. package/test/browser/sample/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  196. package/test/browser/sample/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  197. package/test/browser/sample/css/smoothness/jquery-ui-1.10.1.custom.css +1175 -0
  198. package/test/browser/sample/css/smoothness/jquery-ui-1.10.1.custom.min.css +5 -0
  199. package/test/browser/sample/img/loading.gif +0 -0
  200. package/test/browser/sample/js/jquery-1.9.1.js +9597 -0
  201. package/test/browser/sample/js/jquery-ui-1.10.1.custom.js +14903 -0
  202. package/test/browser/sample/js/jquery-ui-1.10.1.custom.min.js +6 -0
  203. package/test/browser/sample/s3upload.html +111 -0
  204. package/test/browser.spec.coffee +207 -0
  205. package/test/config.spec.coffee +202 -0
  206. package/test/credential_provider_chain.spec.coffee +90 -0
  207. package/test/credentials.spec.coffee +452 -0
  208. package/test/endpoint.spec.coffee +80 -0
  209. package/test/event_listeners.spec.coffee +493 -0
  210. package/test/helpers.coffee +150 -0
  211. package/test/http_request.spec.coffee +55 -0
  212. package/test/json/builder.spec.coffee +129 -0
  213. package/test/json/parser.spec.coffee +108 -0
  214. package/test/metadata_service.spec.coffee +54 -0
  215. package/test/model/api.spec.coffee +67 -0
  216. package/test/model/shape.spec.coffee +23 -0
  217. package/test/node_http_client.spec.coffee +40 -0
  218. package/test/param_validator.spec.coffee +456 -0
  219. package/test/protocol/json.spec.coffee +167 -0
  220. package/test/protocol/query.spec.coffee +191 -0
  221. package/test/protocol/rest.spec.coffee +237 -0
  222. package/test/protocol/rest_json.spec.coffee +255 -0
  223. package/test/protocol/rest_xml.spec.coffee +329 -0
  224. package/test/query/query_param_serializer.spec.coffee +327 -0
  225. package/test/region_config.spec.coffee +50 -0
  226. package/test/request.spec.coffee +316 -0
  227. package/test/resource_waiter.spec.coffee +89 -0
  228. package/test/response.spec.coffee +81 -0
  229. package/test/sequential_executor.spec.coffee +118 -0
  230. package/test/service.spec.coffee +230 -0
  231. package/test/services/cloudfront.spec.coffee +44 -0
  232. package/test/services/cloudsearchdomain.spec.coffee +23 -0
  233. package/test/services/dynamodb.spec.coffee +32 -0
  234. package/test/services/ec2.spec.coffee +78 -0
  235. package/test/services/elastictranscoder.spec.coffee +43 -0
  236. package/test/services/glacier.spec.coffee +61 -0
  237. package/test/services/rds.spec.coffee +38 -0
  238. package/test/services/route53.spec.coffee +77 -0
  239. package/test/services/s3.spec.coffee +538 -0
  240. package/test/services/simpledb.spec.coffee +12 -0
  241. package/test/services/sqs.spec.coffee +130 -0
  242. package/test/services/sts.spec.coffee +72 -0
  243. package/test/services/swf.spec.coffee +6 -0
  244. package/test/signers/presign.spec.coffee +36 -0
  245. package/test/signers/s3.spec.coffee +297 -0
  246. package/test/signers/v2.spec.coffee +68 -0
  247. package/test/signers/v4.spec.coffee +135 -0
  248. package/test/util.spec.coffee +510 -0
  249. package/test/xml/builder.spec.coffee +529 -0
  250. package/test/xml/parser.spec.coffee +587 -0
  251. package/lib/services/simpledb.js +0 -15
@@ -0,0 +1,191 @@
1
+ helpers = require('../helpers')
2
+ AWS = helpers.AWS
3
+ Buffer = AWS.util.Buffer
4
+
5
+ svc = AWS.Protocol.Query
6
+ describe 'AWS.Protocol.Query', ->
7
+ service = null
8
+ request = null
9
+ response = null
10
+
11
+ beforeEach ->
12
+ service = new AWS.Service apiConfig:
13
+ metadata:
14
+ endpointPrefix: 'mockservice'
15
+ apiVersion: '2012-01-01'
16
+ operations:
17
+ OperationName:
18
+ name: 'OperationName'
19
+ input:
20
+ members:
21
+ Input:
22
+ type: 'string'
23
+ List:
24
+ type: 'list'
25
+ members: {}
26
+ output:
27
+ type: 'structure'
28
+ members:
29
+ Data:
30
+ type: 'structure'
31
+ members:
32
+ Name:
33
+ type: 'string'
34
+ Count:
35
+ type: 'float'
36
+
37
+ request = new AWS.Request(service, 'operationName')
38
+ response = request.response
39
+
40
+ describe 'buildRequest', ->
41
+ stringify = (params) -> AWS.util.queryParamsToString(params)
42
+
43
+ buildRequest = (input, list) ->
44
+ if input == undefined
45
+ input = 'foo+bar: yuck/baz=~'
46
+ request.params = Input: input, List: list
47
+ svc.buildRequest(request)
48
+
49
+ it 'should use POST method requests', ->
50
+ buildRequest()
51
+ expect(request.httpRequest.method).toEqual('POST')
52
+
53
+ it 'should perform all operations on root (/)', ->
54
+ buildRequest()
55
+ expect(request.httpRequest.path).toEqual('/')
56
+
57
+ it 'allows mounted path to be specified', ->
58
+ service.setEndpoint('https://localhost/foo/bar')
59
+ request = new AWS.Request(service, 'operationName')
60
+ buildRequest()
61
+ expect(request.httpRequest.path).toEqual('/foo/bar')
62
+
63
+ it 'should set Content-Type header', ->
64
+ buildRequest()
65
+ expect(request.httpRequest.headers['Content-Type']).
66
+ toEqual('application/x-www-form-urlencoded; charset=utf-8')
67
+
68
+ it 'should add the api version param', ->
69
+ buildRequest()
70
+ expect(stringify(request.httpRequest.params)).
71
+ toMatch(/Version=2012-01-01/)
72
+
73
+ it 'should add the operation name as Action', ->
74
+ buildRequest()
75
+ expect(stringify(request.httpRequest.params)).
76
+ toMatch(/Action=OperationName/)
77
+
78
+ it 'should uri encode params properly', ->
79
+ buildRequest()
80
+ expect(stringify(request.httpRequest.params)).
81
+ toMatch(/foo%2Bbar%3A%20yuck%2Fbaz%3D~/);
82
+
83
+ it 'encodes empty string values properly', ->
84
+ buildRequest('')
85
+ expect(stringify(request.httpRequest.params)).
86
+ toMatch(/Input=($|&)/);
87
+
88
+ it 'serializes empty lists', ->
89
+ buildRequest(null, [])
90
+ expect(stringify(request.httpRequest.params)).toMatch(/[?&]List(&|$)/)
91
+
92
+ describe 'extractError', ->
93
+ extractError = (body) ->
94
+ if body == undefined
95
+ body = """
96
+ <Error>
97
+ <Code>InvalidArgument</Code>
98
+ <Message>Provided param is bad</Message>
99
+ </Error>
100
+ """
101
+ response.httpResponse.statusCode = 400
102
+ response.httpResponse.body = new Buffer(body)
103
+ svc.extractError(response)
104
+
105
+ it 'extracts error from UnknownOperationException', ->
106
+ extractError '<UnknownOperationException/>'
107
+ expect(response.error instanceof Error).toBeTruthy()
108
+ expect(response.error.code).toEqual('UnknownOperation')
109
+ expect(response.error.message).toEqual('Unknown operation operationName')
110
+ expect(response.data).toEqual(null)
111
+
112
+ it 'extracts the error code and message', ->
113
+ extractError()
114
+ expect(response.error instanceof Error).toBeTruthy()
115
+ expect(response.error.code).toEqual('InvalidArgument')
116
+ expect(response.error.message).toEqual('Provided param is bad')
117
+ expect(response.data).toEqual(null)
118
+
119
+ it 'returns an empty error when the body is blank', ->
120
+ extractError('')
121
+ expect(response.error.code).toEqual(400)
122
+ expect(response.error.message).toEqual(null)
123
+ expect(response.data).toEqual(null)
124
+
125
+ it 'extracts error when inside <Errors>', ->
126
+ extractError """
127
+ <SomeResponse>
128
+ <Errors>
129
+ <Error>
130
+ <Code>code</Code><Message>msg</Message>
131
+ </Error>
132
+ </Errors>
133
+ </SomeResponse>"""
134
+ expect(response.error.code).toEqual('code')
135
+ expect(response.error.message).toEqual('msg')
136
+
137
+ it 'extracts error when <Error> is nested', ->
138
+ extractError """
139
+ <SomeResponse>
140
+ <Error>
141
+ <Code>code</Code><Message>msg</Message>
142
+ </Error>
143
+ </SomeResponse>"""
144
+ expect(response.error.code).toEqual('code')
145
+ expect(response.error.message).toEqual('msg')
146
+
147
+ describe 'extractData', ->
148
+ extractData = (body) ->
149
+ response.httpResponse.statusCode = 200
150
+ response.httpResponse.body = new Buffer(body)
151
+ svc.extractData(response)
152
+
153
+ it 'parses the response using the operation output rules', ->
154
+ extractData """
155
+ <xml>
156
+ <Data>
157
+ <Name>abc</Name>
158
+ <Count>123</Count>
159
+ </Data>
160
+ </xml>
161
+ """
162
+ expect(response.error).toEqual(null)
163
+ expect(response.data).toEqual({Data:{Name:'abc',Count:123}})
164
+
165
+ it 'performs default xml parsing when output rule is missing', ->
166
+ delete service.api.operations.operationName.output
167
+ extractData """
168
+ <xml>
169
+ <Data>
170
+ <Name>abc</Name>
171
+ <Count>123</Count>
172
+ </Data>
173
+ </xml>
174
+ """
175
+ expect(response.error).toEqual(null)
176
+ expect(response.data).toEqual({Data:{Name:'abc',Count:'123'}})
177
+
178
+ it 'removes wrapping result element if resultWrapper is set', ->
179
+ service.api.operations.operationName.output.resultWrapper = 'OperationNameResult'
180
+ extractData """
181
+ <xml>
182
+ <OperationNameResult>
183
+ <Data>
184
+ <Name>abc</Name>
185
+ <Count>12345.5</Count>
186
+ </Data>
187
+ </OperationNameResult>
188
+ </xml>
189
+ """
190
+ expect(response.error).toEqual(null)
191
+ expect(response.data).toEqual({Data:{Name:'abc',Count:12345.5}})
@@ -0,0 +1,237 @@
1
+ helpers = require('../helpers')
2
+ AWS = helpers.AWS
3
+ Operation = helpers.AWS.Model.Operation
4
+ Api = helpers.AWS.Model.Api
5
+
6
+ svc = AWS.Protocol.Rest
7
+ describe 'AWS.Protocol.Rest', ->
8
+
9
+ MockRESTService = helpers.util.inherit AWS.Service,
10
+ endpointPrefix: 'mockservice'
11
+
12
+ request = null
13
+ response = null
14
+ service = null
15
+
16
+ beforeEach ->
17
+ MockRESTService.prototype.api = new Api operations:
18
+ SampleOperation:
19
+ http:
20
+ method: 'POST'
21
+ requestUri: '/'
22
+
23
+
24
+ AWS.Service.defineMethods(MockRESTService)
25
+
26
+ service = new MockRESTService(region: 'region')
27
+ request = new AWS.Request(service, 'sampleOperation')
28
+ response = request.response
29
+
30
+ defop = (op) ->
31
+ AWS.util.property(service.api.operations, 'sampleOperation',
32
+ new Operation('sampleOperation', op, api: service.api))
33
+
34
+ describe 'buildRequest', ->
35
+ input = null
36
+
37
+ build = -> svc.buildRequest(request); request
38
+
39
+ describe 'method', ->
40
+ it 'populates method from the operation', ->
41
+ defop http: method: 'GET'
42
+ expect(build().httpRequest.method).toEqual('GET')
43
+
44
+ describe 'uri', ->
45
+ beforeEach ->
46
+ input =
47
+ type: 'structure'
48
+ members:
49
+ Id: location: 'uri', locationName: 'Id'
50
+
51
+ it 'populates uri from the operation', ->
52
+ defop http: requestUri: '/path'
53
+ expect(build().httpRequest.path).toEqual('/path')
54
+
55
+ it 'appends to existing httpRequest endpoint', ->
56
+ service = new MockRESTService(endpoint: 'https://localhost/foo/bar')
57
+ request = new AWS.Request(service, 'sampleOperation')
58
+ request.params = Id: 'abc'
59
+ defop input: input, http: requestUri: '/Owner/{Id}'
60
+ expect(build().httpRequest.path).toEqual('/foo/bar/Owner/abc')
61
+
62
+ it 'replaces param placeholders', ->
63
+ request.params = Id: 'abc'
64
+ defop input: input, http: requestUri: '/Owner/{Id}'
65
+ expect(build().httpRequest.path).toEqual('/Owner/abc')
66
+
67
+ it 'replaces param with empty string', ->
68
+ request.params = Id: ''
69
+ defop input: input, http: requestUri: '/Owner/{Id}'
70
+ expect(build().httpRequest.path).toEqual('/Owner/')
71
+
72
+ it 'can replace multiple path placeholders', ->
73
+ request.params = Id: 'abc', Count: 123
74
+ input.members.Count = type: 'integer', location: 'uri'
75
+ defop input: input, http: requestUri: '/{Id}/{Count}'
76
+ expect(build().httpRequest.path).toEqual('/abc/123')
77
+
78
+ it 'performs querystring param replacements', ->
79
+ request.params = Id: 'abc'
80
+ defop input: input, http: requestUri: '/path'
81
+ input.members.Id = location: 'querystring', locationName: 'id-param'
82
+ expect(build().httpRequest.path).toEqual('/path?id-param=abc')
83
+
84
+ it 'omits querystring when param is not provided', ->
85
+ defop input: input, http: requestUri: '/path'
86
+ input.members.Id = location: 'querystring', locationName: 'id-param'
87
+ expect(build().httpRequest.path).toEqual('/path')
88
+
89
+ it 'accpets multiple query params with uri params', ->
90
+ request.params = Abc:'abc', Xyz:'xyz', Bar:'bar'
91
+ defop input: input, http: requestUri: '/{Abc}/{Xyz}'
92
+ input.members.Abc = location: 'uri'
93
+ input.members.Xyz = location: 'uri'
94
+ input.members.Foo = location: 'querystring', locationName: 'foo'
95
+ input.members.Bar = location: 'querystring', locationName: 'bar'
96
+ expect(build().httpRequest.path).toEqual('/abc/xyz?bar=bar')
97
+
98
+ it 'uri escapes params in both path and querystring', ->
99
+ request.params = Path:'a b', Query:'a/b'
100
+ defop input: input, http: requestUri: '/{Path}'
101
+ input.members.Path = location: 'uri'
102
+ input.members.Query = location: 'querystring', locationName: 'query'
103
+ expect(build().httpRequest.path).toEqual('/a%20b?query=a%2Fb')
104
+
105
+ describe 'headers', ->
106
+ beforeEach ->
107
+ input =
108
+ type: 'structure'
109
+ members:
110
+ ACL: location: 'header', locationName: 'x-amz-acl'
111
+
112
+ it 'populates the headers with present params', ->
113
+ request.params = ACL: 'public-read'
114
+ defop input: input
115
+ expect(build().httpRequest.headers['x-amz-acl']).toEqual('public-read')
116
+
117
+ it 'populates the headers type translations', ->
118
+ request.params = Count: 123
119
+ defop input: members: Count: locationName: 'count', type: 'integer', location: 'header'
120
+ expect(build().httpRequest.headers['count']).toEqual('123')
121
+
122
+ it 'uses default rule name if locationName property is not present', ->
123
+ request.params = ACL: 'public-read'
124
+ delete input.members.ACL.locationName
125
+ defop input: input
126
+ expect(build().httpRequest.headers['ACL']).toEqual('public-read')
127
+
128
+ it 'works with map types', ->
129
+ request.params =
130
+ Metadata:
131
+ foo: 'bar'
132
+ abc: 'xyz'
133
+ input.members.Metadata =
134
+ type: 'map'
135
+ location: 'headers'
136
+ locationName: 'x-amz-meta-'
137
+ defop input: input
138
+
139
+ build()
140
+ expect(request.httpRequest.headers['x-amz-meta-foo']).toEqual('bar')
141
+ expect(request.httpRequest.headers['x-amz-meta-abc']).toEqual('xyz')
142
+
143
+ describe 'timestamp header with format', ->
144
+ it 'populates the header with correct timestamp formatting', ->
145
+ date = new Date(); date.setMilliseconds(0)
146
+ request.params = IfModifiedSince: date
147
+ input.members.IfModifiedSince =
148
+ location: 'header'
149
+ locationName: 'If-Modified-Since'
150
+ type: 'timestamp'
151
+ timestampFormat: 'rfc822'
152
+ defop input: input
153
+ expect(build().httpRequest.headers['If-Modified-Since']).toEqual(date.toUTCString())
154
+
155
+ describe 'timestamp header without format', ->
156
+ it 'populates the header using the api formatting', ->
157
+ service.api.timestampFormat = 'rfc822'
158
+ date = new Date(); date.setMilliseconds(0)
159
+ request.params = IfModifiedSince: date
160
+ input.members.IfModifiedSince =
161
+ location: 'header'
162
+ locationName: 'If-Modified-Since'
163
+ type: 'timestamp'
164
+ defop input: input
165
+ expect(build().httpRequest.headers['If-Modified-Since']).toEqual(date.toUTCString())
166
+
167
+ describe 'timestamp header with api formatting and parameter formatting', ->
168
+ it 'populates the header using the parameter formatting', ->
169
+ service.api.timestampFormat = 'invalid'
170
+ date = new Date(); date.setMilliseconds(0)
171
+ request.params = IfModifiedSince: date
172
+ input.members.IfModifiedSince =
173
+ location: 'header'
174
+ locationName: 'If-Modified-Since'
175
+ type: 'timestamp'
176
+ timestampFormat: 'rfc822'
177
+ defop input: input
178
+ expect(build().httpRequest.headers['If-Modified-Since']).toEqual(date.toUTCString())
179
+
180
+ describe 'timestamp header with iso formatting', ->
181
+ it 'populates the header using the parameter formatting', ->
182
+ date = new Date(); date.setMilliseconds(0)
183
+ request.params = IfModifiedSince: date
184
+ input.members.IfModifiedSince =
185
+ location: 'header'
186
+ locationName: 'If-Modified-Since'
187
+ type: 'timestamp'
188
+ timestampFormat: 'iso8601'
189
+ defop input: input
190
+ expect(build().httpRequest.headers['If-Modified-Since']).toEqual(date.toISOString())
191
+
192
+ describe 'extractData', ->
193
+ output = type: 'structure', members:
194
+ ContentType:
195
+ type: 'string'
196
+ location: 'header'
197
+ locationName: 'content-type'
198
+
199
+ extract = -> defop output: output; svc.extractData(response); response
200
+
201
+ describe 'headers', ->
202
+ it 'extracts header values', ->
203
+ response.httpResponse.headers['content-type'] = 'text/plain'
204
+ expect(extract().data.ContentType).toEqual('text/plain')
205
+
206
+ it 'extracts headers when the rule name is camel-cased', ->
207
+ response.httpResponse.headers['content-type'] = 'text/plain'
208
+ output.members.ContentType.locationName = 'Content-Type'
209
+ expect(extract().data.ContentType).toEqual('text/plain')
210
+
211
+ it 'extracts headers when the header name is camel-cased', ->
212
+ response.httpResponse.headers['Content-Type'] = 'text/plain'
213
+ expect(extract().data.ContentType).toEqual('text/plain')
214
+
215
+ it 'extracts map types from header', ->
216
+ output.members.Metadata = type: 'map', location: 'headers', locationName: 'x-amz-meta-'
217
+ response.httpResponse.headers['X-AMZ-META-FOO'] = 'foo'
218
+ response.httpResponse.headers['x-amz-meta-bar'] = 'bar'
219
+
220
+ extract()
221
+ expect(response.data.Metadata.FOO).toEqual('foo')
222
+ expect(response.data.Metadata.bar).toEqual('bar')
223
+
224
+ it 'adds empty map if no matching headers are found', ->
225
+ output.members.Metadata = type: 'map', location: 'headers', locationName: 'x-amz-meta-'
226
+ expect(extract().data.Metadata).toEqual({})
227
+
228
+ describe 'status code', ->
229
+ it 'extracts the http status when instructed to', ->
230
+ output.members.Result = type: 'integer', location: 'status'
231
+ response.httpResponse.statusCode = 200
232
+ expect(extract().data.Result).toEqual(200)
233
+
234
+ it 'casts string status codes to integers', ->
235
+ output.members.Result = type: 'integer', location: 'status'
236
+ response.httpResponse.statusCode = '202'
237
+ expect(extract().data.Result).toEqual(202)
@@ -0,0 +1,255 @@
1
+ helpers = require('../helpers'); AWS = helpers.AWS
2
+ Operation = AWS.Model.Operation
3
+ Buffer = helpers.util.Buffer
4
+
5
+ svc = AWS.Protocol.RestJson
6
+ describe 'AWS.Protocol.RestJson', ->
7
+
8
+ MockJSONRESTService = helpers.util.inherit AWS.Service,
9
+ endpointPrefix: 'mockservice'
10
+
11
+ operation = null
12
+ request = null
13
+ response = null
14
+ service = null
15
+
16
+ beforeEach ->
17
+ MockJSONRESTService.prototype.api = new AWS.Model.Api
18
+ operations:
19
+ sampleOperation:
20
+ http:
21
+ method: 'POST'
22
+ uri: '/'
23
+ input:
24
+ type: 'structure'
25
+ members: {}
26
+ output:
27
+ type: 'structure'
28
+ members:
29
+ a: type: 'string'
30
+ b: type: 'string'
31
+
32
+ AWS.Service.defineMethods(MockJSONRESTService)
33
+
34
+ operation = MockJSONRESTService.prototype.api.operations.sampleOperation
35
+ service = new MockJSONRESTService(region: 'region')
36
+ request = new AWS.Request(service, 'sampleOperation')
37
+ response = new AWS.Response(request)
38
+
39
+ defop = (op) ->
40
+ helpers.util.property(service.api.operations, 'sampleOperation',
41
+ new Operation('sampleOperation', op, api: service.api))
42
+
43
+ describe 'buildRequest', ->
44
+ build = -> svc.buildRequest(request); request
45
+
46
+ describe 'method', ->
47
+ it 'populates method from the operation', ->
48
+ defop http: method: 'GET'
49
+ expect(build().httpRequest.method).toEqual('GET')
50
+
51
+ describe 'uri', ->
52
+ it 'populates uri from the operation', ->
53
+ defop http: requestUri: '/path'
54
+ expect(build().httpRequest.path).toEqual('/path')
55
+
56
+ it 'replaces param placeholders', ->
57
+ request.params = Id: 'abc'
58
+ defop
59
+ http: requestUri: '/Owner/{Id}'
60
+ input: type: 'structure', members: Id: location: 'uri'
61
+ expect(build().httpRequest.path).toEqual('/Owner/abc')
62
+
63
+ it 'can replace multiple path placeholders', ->
64
+ request.params = Id: 'abc', Count: 123
65
+ defop
66
+ http: requestUri: '/{Id}/{Count}'
67
+ input:
68
+ type: 'structure'
69
+ members:
70
+ Id:
71
+ location: 'uri'
72
+ type: 'string'
73
+ Count:
74
+ type: 'integer'
75
+ location: 'uri'
76
+ expect(build().httpRequest.path).toEqual('/abc/123')
77
+
78
+ it 'performs querystring param replacements', ->
79
+ request.params = Id: 'abc'
80
+ defop
81
+ http: requestUri: '/path'
82
+ input:
83
+ type: 'structure'
84
+ members:
85
+ Id:
86
+ location: 'querystring'
87
+ locationName: 'id-param'
88
+ expect(build().httpRequest.path).toEqual('/path?id-param=abc')
89
+
90
+ describe 'headers', ->
91
+ it 'populates the headers with present params', ->
92
+ request.params = ACL: 'public-read'
93
+ defop input:
94
+ members:
95
+ ACL:
96
+ location: 'header'
97
+ locationName: 'x-amz-acl'
98
+ expect(build().httpRequest.headers['x-amz-acl']).toEqual('public-read')
99
+
100
+ it 'uses default rule name if .n property is not present', ->
101
+ request.params = ACL: 'public-read'
102
+ defop input:
103
+ members:
104
+ ACL:
105
+ location: 'header'
106
+ expect(build().httpRequest.headers['ACL']).toEqual('public-read')
107
+
108
+ it 'works with map types', ->
109
+ request.params =
110
+ Metadata:
111
+ foo: 'bar'
112
+ abc: 'xyz'
113
+ defop input:
114
+ members:
115
+ Metadata:
116
+ type: 'map'
117
+ location: 'headers'
118
+ locationName: 'x-amz-meta-'
119
+
120
+ build()
121
+ expect(request.httpRequest.headers['x-amz-meta-foo']).toEqual('bar')
122
+ expect(request.httpRequest.headers['x-amz-meta-abc']).toEqual('xyz')
123
+
124
+ describe 'body', ->
125
+ it 'builds root element if rules contains root', ->
126
+ request.params =
127
+ Config:
128
+ Name: 'foo'
129
+ Type: 'bar'
130
+ defop input:
131
+ payload: 'Config'
132
+ members:
133
+ Config:
134
+ type: 'structure'
135
+ members:
136
+ Name: type: 'string'
137
+ Type: type: 'string'
138
+ expect(build().httpRequest.body.toString()).toEqual(
139
+ '{"Name":"foo","Type":"bar"}')
140
+
141
+ it 'builds payload element as non JSON data if rules contains payload', ->
142
+ request.params = Body: 'foobar'
143
+ defop input:
144
+ payload: 'Body'
145
+ members:
146
+ Body:
147
+ type: 'binary'
148
+ expect(build().httpRequest.body).toEqual('foobar')
149
+
150
+ describe 'extractError', ->
151
+ extractError = (body) ->
152
+ response.httpResponse.statusCode = 500
153
+ response.httpResponse.body = new Buffer(body)
154
+ svc.extractError(response)
155
+
156
+ it 'removes prefixes from the error code', ->
157
+ extractError '{"__type":"com.amazon.coral.service#ErrorCode" }'
158
+ expect(response.error instanceof Error).toBeTruthy()
159
+ expect(response.error.code).toEqual('ErrorCode')
160
+ expect(response.data).toEqual(null)
161
+
162
+ it 'returns the full code when a # is not present', ->
163
+ extractError '{"__type":"ErrorCode" }'
164
+ expect(response.error instanceof Error).toBeTruthy()
165
+ expect(response.error.code).toEqual('ErrorCode')
166
+ expect(response.data).toEqual(null)
167
+
168
+ it 'returns the status code when the body is blank', ->
169
+ extractError ''
170
+ expect(response.error instanceof Error).toBeTruthy()
171
+ expect(response.error.code).toEqual(500)
172
+ expect(response.error.message).toEqual(null)
173
+ expect(response.data).toEqual(null)
174
+
175
+ it 'returns null for the message when not present', ->
176
+ extractError '{"__type":"ErrorCode" }'
177
+ expect(response.error instanceof Error).toBeTruthy()
178
+ expect(response.error.message).toEqual(null)
179
+ expect(response.data).toEqual(null)
180
+
181
+ it 'returns the message when present', ->
182
+ extractError '{"__type":"ErrorCode", "message":"Error Message" }'
183
+ expect(response.error instanceof Error).toBeTruthy()
184
+ expect(response.error.message).toEqual('Error Message')
185
+ expect(response.data).toEqual(null)
186
+
187
+ # DynamoDB and SWF return error message properties with different case
188
+ it 'returns the message when the message property is upper-cased', ->
189
+ extractError '{"__type":"ErrorCode", "Message":"Error Message" }'
190
+ expect(response.error instanceof Error).toBeTruthy()
191
+ expect(response.error.message).toEqual('Error Message')
192
+ expect(response.data).toEqual(null)
193
+
194
+ it 'returns a special message for RequestEntityToLarge errors', ->
195
+ extractError '{"__type":"RequestEntityTooLarge" }'
196
+ expect(response.error instanceof Error).toBeTruthy()
197
+ expect(response.error.message).toEqual('Request body must be less than 1 MB')
198
+ expect(response.data).toEqual(null)
199
+
200
+ describe 'extractData', ->
201
+ extractData = (body) ->
202
+ response.httpResponse.statusCode = 200
203
+ response.httpResponse.body = new Buffer(body)
204
+ svc.extractData(response)
205
+
206
+ it 'JSON parses http response bodies', ->
207
+ extractData '{"a":1, "b":"xyz"}'
208
+ expect(response.error).toEqual(null)
209
+ expect(response.data).toEqual({a:1, b:'xyz'})
210
+
211
+ it 'pulls header data out of response', ->
212
+ response.httpResponse.headers['x-title'] = 'The title'
213
+ defop output:
214
+ type: 'structure'
215
+ members:
216
+ Title:
217
+ location: 'header'
218
+ locationName: 'x-title'
219
+
220
+ extractData '{}'
221
+ expect(response.error).toEqual(null)
222
+ expect(response.data.Title).toEqual('The title')
223
+
224
+ it 'pulls body out into data key if body is payload', ->
225
+ defop output:
226
+ type: 'structure'
227
+ payload: 'Body'
228
+ members:
229
+ Body: location: 'body', type: 'binary'
230
+
231
+ extractData 'foobar'
232
+ expect(response.error).toEqual(null)
233
+ expect(response.data.Body).toEqual('foobar')
234
+
235
+ it 'pulls body out as Buffer if body is streaming payload', ->
236
+ defop output:
237
+ type: 'structure'
238
+ payload: 'Body'
239
+ members:
240
+ Body: location: 'body', type: 'binary', streaming: true
241
+
242
+ extractData 'foobar'
243
+ expect(response.error).toEqual(null)
244
+ expect(Buffer.isBuffer(response.data.Body)).toEqual(true)
245
+ expect(response.data.Body.toString()).toEqual('foobar')
246
+
247
+ it 'returns an empty object when the body is an empty string', ->
248
+ extractData ''
249
+ expect(response.error).toEqual(null)
250
+ expect(response.data).toEqual({})
251
+
252
+ it 'returns an empty object when the body is null', ->
253
+ extractData ''
254
+ expect(response.error).toEqual(null)
255
+ expect(response.data).toEqual({})